migration: qemu_savevm_complete*() helpers
Since we use the same save_complete() hook for both precopy and postcopy, add a set of helpers to invoke the hook() to dedup the code. Reviewed-by: Juraj Marcin <jmarcin@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20250613140801.474264-8-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
parent
57c43e52bd
commit
7dd95a9630
1 changed files with 44 additions and 34 deletions
|
|
@ -1484,6 +1484,38 @@ bool should_send_vmdesc(void)
|
|||
return !machine->suppress_vmdesc;
|
||||
}
|
||||
|
||||
static bool qemu_savevm_complete_exists(SaveStateEntry *se)
|
||||
{
|
||||
return se->ops && se->ops->save_complete;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke the ->save_complete() if necessary.
|
||||
* Returns: 0 if skip the current SE or succeeded, <0 if error happened.
|
||||
*/
|
||||
static int qemu_savevm_complete(SaveStateEntry *se, QEMUFile *f)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (se->ops->is_active) {
|
||||
if (!se->ops->is_active(se->opaque)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
trace_savevm_section_start(se->idstr, se->section_id);
|
||||
save_section_header(f, se, QEMU_VM_SECTION_END);
|
||||
ret = se->ops->save_complete(f, se->opaque);
|
||||
trace_savevm_section_end(se->idstr, se->section_id, ret);
|
||||
save_section_footer(f, se);
|
||||
|
||||
if (ret < 0) {
|
||||
qemu_file_set_error(f, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete saving any postcopy-able devices.
|
||||
*
|
||||
|
|
@ -1493,27 +1525,13 @@ bool should_send_vmdesc(void)
|
|||
void qemu_savevm_state_complete_postcopy(QEMUFile *f)
|
||||
{
|
||||
SaveStateEntry *se;
|
||||
int ret;
|
||||
|
||||
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
|
||||
if (!se->ops || !se->ops->save_complete) {
|
||||
if (!qemu_savevm_complete_exists(se)) {
|
||||
continue;
|
||||
}
|
||||
if (se->ops->is_active) {
|
||||
if (!se->ops->is_active(se->opaque)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
trace_savevm_section_start(se->idstr, se->section_id);
|
||||
/* Section type */
|
||||
qemu_put_byte(f, QEMU_VM_SECTION_END);
|
||||
qemu_put_be32(f, se->section_id);
|
||||
|
||||
ret = se->ops->save_complete(f, se->opaque);
|
||||
trace_savevm_section_end(se->idstr, se->section_id, ret);
|
||||
save_section_footer(f, se);
|
||||
if (ret < 0) {
|
||||
qemu_file_set_error(f, ret);
|
||||
if (qemu_savevm_complete(se, f) < 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1559,7 +1577,6 @@ int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool in_postcopy)
|
|||
{
|
||||
int64_t start_ts_each, end_ts_each;
|
||||
SaveStateEntry *se;
|
||||
int ret;
|
||||
bool multifd_device_state = multifd_device_state_supported();
|
||||
|
||||
if (multifd_device_state) {
|
||||
|
|
@ -1580,32 +1597,25 @@ int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool in_postcopy)
|
|||
}
|
||||
|
||||
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
|
||||
if (!se->ops ||
|
||||
(in_postcopy && se->ops->has_postcopy &&
|
||||
se->ops->has_postcopy(se->opaque)) ||
|
||||
!se->ops->save_complete) {
|
||||
if (!qemu_savevm_complete_exists(se)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (se->ops->is_active) {
|
||||
if (!se->ops->is_active(se->opaque)) {
|
||||
continue;
|
||||
}
|
||||
if (in_postcopy && se->ops->has_postcopy &&
|
||||
se->ops->has_postcopy(se->opaque)) {
|
||||
/*
|
||||
* If postcopy will start soon, and if the SE supports
|
||||
* postcopy, then we can skip the SE for the postcopy phase.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
start_ts_each = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
|
||||
trace_savevm_section_start(se->idstr, se->section_id);
|
||||
|
||||
save_section_header(f, se, QEMU_VM_SECTION_END);
|
||||
|
||||
ret = se->ops->save_complete(f, se->opaque);
|
||||
trace_savevm_section_end(se->idstr, se->section_id, ret);
|
||||
save_section_footer(f, se);
|
||||
if (ret < 0) {
|
||||
qemu_file_set_error(f, ret);
|
||||
if (qemu_savevm_complete(se, f) < 0) {
|
||||
goto ret_fail_abort_threads;
|
||||
}
|
||||
end_ts_each = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
|
||||
|
||||
trace_vmstate_downtime_save("iterable", se->idstr, se->instance_id,
|
||||
end_ts_each - start_ts_each);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue