Define an accessor to find vmstate state handler by name and id and unregister it. This is needed to unregister a specific instance of an object that is not an Object, since it lacks the VMStateIf get_id hook.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/migration/vmstate.h | 9 +++++++++ migration/savevm.c | 27 +++++++++++++++++++++++++++ migration/trace-events | 1 + stubs/vmstate.c | 6 ++++++ 4 files changed, 43 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 22aa3c6..3d71b34 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -1299,6 +1299,15 @@ static inline int vmstate_register_named(const char *instance_name, void vmstate_unregister(VMStateIf *obj, const VMStateDescription *vmsd, void *opaque); +/** + * Delete the VMSD handler for the object with name "vmsd_name/instance_name" + * and matching instance_id. If instance_id is VMSTATE_INSTANCE_ID_ANY, + * delete all instances matching name. + */ +void vmstate_unregister_named(const char *vmsd_name, + const char *instance_name, + int instance_id); + void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev); void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev); void vmstate_register_ram_global(struct MemoryRegion *memory); diff --git a/migration/savevm.c b/migration/savevm.c index 86b4c87..cd2eabe 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -964,6 +964,8 @@ void vmstate_unregister(VMStateIf *obj, const VMStateDescription *vmsd, SAVEVM_FOREACH_SAFE_ALL(se, entry, new_se) { if (se->vmsd == vmsd && se->opaque == opaque) { + trace_vmstate_unregister(se->idstr, se->instance_id, (void *)vmsd, + opaque); savevm_state_handler_remove(se); g_free(se->compat); g_free(se); @@ -971,6 +973,31 @@ void vmstate_unregister(VMStateIf *obj, const VMStateDescription *vmsd, } } +void vmstate_unregister_named(const char *vmsd_name, + const char *instance_name, + int instance_id) +{ + SaveStateEntry *se, *new_se; + VMStateId idstr; + + snprintf(idstr, sizeof(idstr), "%s/%s", vmsd_name, instance_name); + + SAVEVM_FOREACH_SAFE_ALL(se, entry, new_se) { + if (!strcmp(se->idstr, idstr) && + (instance_id == VMSTATE_INSTANCE_ID_ANY || + se->instance_id == instance_id)) { + trace_vmstate_unregister(idstr, se->instance_id, (void *)se->vmsd, + se->opaque); + savevm_state_handler_remove(se); + g_free(se->compat); + g_free(se); + if (instance_id != VMSTATE_INSTANCE_ID_ANY) { + return; + } + } + } +} + static int vmstate_load(QEMUFile *f, SaveStateEntry *se) { trace_vmstate_load(se->idstr, se->vmsd ? se->vmsd->name : "(old)"); diff --git a/migration/trace-events b/migration/trace-events index 8647147..1e23238 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -54,6 +54,7 @@ postcopy_pause_incoming(void) "" postcopy_pause_incoming_continued(void) "" postcopy_page_req_sync(void *host_addr) "sync page req %p" vmstate_register(const char *idstr, int id, void *vmsd, void *opaque) "%s, %d, vmsd %p, opaque %p" +vmstate_unregister(const char *idstr, int id, void *vmsd, void *opaque) "%s, %d, vmsd %p, opaque %p" # vmstate.c vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d" diff --git a/stubs/vmstate.c b/stubs/vmstate.c index d67506e..eff8be4 100644 --- a/stubs/vmstate.c +++ b/stubs/vmstate.c @@ -18,6 +18,12 @@ void vmstate_unregister(VMStateIf *obj, { } +void vmstate_unregister_named(const char *vmsd_name, + const char *instance_name, + int instance_id) +{ +} + bool vmstate_check_only_migratable(const VMStateDescription *vmsd) { return true; -- 1.8.3.1