examples/c/misc/event-test.c | 3 +++ include/libvirt/libvirt-domain.h | 1 + src/qemu/qemu_migration.c | 10 ++++++++++ tools/virsh-domain-event.c | 3 ++- 4 files changed, 16 insertions(+), 1 deletion(-)
From: Jim Fehlig <jfehlig@suse.com>
When migrating with VIR_MIGRATE_UNDEFINE_SOURCE, qemuMigrationSrcConfirm()
and qemuMigrationSrcPerformJob() delete the domain's persistent config on
the source host but never emit a VIR_DOMAIN_EVENT_UNDEFINED lifecycle
event. Applications relying solely on domain events never learn the domain
was undefined on the source.
Add a new UNDEFINED event detail named 'VIR_DOMAIN_EVENT_UNDEFINED_MIGRATED",
and include it when emitting an UNDEFINED event after a successful migration
with VIR_MIGRATE_UNDEFINE_SOURCE flag.
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
---
examples/c/misc/event-test.c | 3 +++
include/libvirt/libvirt-domain.h | 1 +
src/qemu/qemu_migration.c | 10 ++++++++++
tools/virsh-domain-event.c | 3 ++-
4 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/examples/c/misc/event-test.c b/examples/c/misc/event-test.c
index 601f5eafcf..3a601cce33 100644
--- a/examples/c/misc/event-test.c
+++ b/examples/c/misc/event-test.c
@@ -121,6 +121,9 @@ eventDetailToString(int event,
case VIR_DOMAIN_EVENT_UNDEFINED_RENAMED:
return "Renamed";
+ case VIR_DOMAIN_EVENT_UNDEFINED_MIGRATED:
+ return "Migrated";
+
case VIR_DOMAIN_EVENT_UNDEFINED_LAST:
break;
}
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 99208137c3..890d11cf5e 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5691,6 +5691,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED = 0, /* Deleted the config file (Since: 0.5.0) */
VIR_DOMAIN_EVENT_UNDEFINED_RENAMED = 1, /* Domain was renamed (Since: 1.2.19) */
+ VIR_DOMAIN_EVENT_UNDEFINED_MIGRATED = 2, /* Domain was migrated with VIR_MIGRATE_UNDEFINE_SOURCE flag (Since: 12.9.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_UNDEFINED_LAST /* (Since: 0.9.10) */
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 797f83ca0d..76661de09a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -4279,6 +4279,7 @@ qemuMigrationSrcConfirm(virQEMUDriver *driver,
{
qemuMigrationJobPhase phase;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ virObjectEvent *event = NULL;
int ret = -1;
VIR_DEBUG("vm=%p, flags=0x%x, cancelled=%d", vm, flags, cancelled);
@@ -4325,11 +4326,15 @@ qemuMigrationSrcConfirm(virQEMUDriver *driver,
if (!cancelled && ret == 0 && flags & VIR_MIGRATE_UNDEFINE_SOURCE) {
virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
vm->persistent = 0;
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_UNDEFINED,
+ VIR_DOMAIN_EVENT_UNDEFINED_MIGRATED);
}
qemuDomainRemoveInactive(vm, VIR_DOMAIN_UNDEFINE_TPM, true);
}
cleanup:
+ virObjectEventStateQueue(driver->domainEventState, event);
virDomainObjEndAPI(&vm);
return ret;
}
@@ -6328,6 +6333,7 @@ qemuMigrationSrcPerformJob(virQEMUDriver *driver,
bool v3proto)
{
virObjectEvent *event = NULL;
+ virObjectEvent *undefine_event = NULL;
int ret = -1;
virErrorPtr orig_err = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
@@ -6419,6 +6425,9 @@ qemuMigrationSrcPerformJob(virQEMUDriver *driver,
if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) {
virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
vm->persistent = 0;
+ undefine_event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_UNDEFINED,
+ VIR_DOMAIN_EVENT_UNDEFINED_MIGRATED);
}
qemuDomainRemoveInactive(vm, 0, true);
}
@@ -6427,6 +6436,7 @@ qemuMigrationSrcPerformJob(virQEMUDriver *driver,
cleanup:
virObjectEventStateQueue(driver->domainEventState, event);
+ virObjectEventStateQueue(driver->domainEventState, undefine_event);
return ret;
}
diff --git a/tools/virsh-domain-event.c b/tools/virsh-domain-event.c
index a541b155f4..40a72563a5 100644
--- a/tools/virsh-domain-event.c
+++ b/tools/virsh-domain-event.c
@@ -62,7 +62,8 @@ VIR_ENUM_DECL(virshDomainEventUndefined);
VIR_ENUM_IMPL(virshDomainEventUndefined,
VIR_DOMAIN_EVENT_UNDEFINED_LAST,
N_("Removed"),
- N_("Renamed"));
+ N_("Renamed"),
+ N_("Migrated"));
VIR_ENUM_DECL(virshDomainEventStarted);
VIR_ENUM_IMPL(virshDomainEventStarted,
--
2.51.0
On 10/17/26 00:06, Jim Fehlig via Devel wrote: > From: Jim Fehlig <jfehlig@suse.com> > > When migrating with VIR_MIGRATE_UNDEFINE_SOURCE, qemuMigrationSrcConfirm() > and qemuMigrationSrcPerformJob() delete the domain's persistent config on > the source host but never emit a VIR_DOMAIN_EVENT_UNDEFINED lifecycle > event. Applications relying solely on domain events never learn the domain > was undefined on the source. > > Add a new UNDEFINED event detail named 'VIR_DOMAIN_EVENT_UNDEFINED_MIGRATED", > and include it when emitting an UNDEFINED event after a successful migration > with VIR_MIGRATE_UNDEFINE_SOURCE flag. > > Signed-off-by: Jim Fehlig <jfehlig@suse.com> > --- > examples/c/misc/event-test.c | 3 +++ > include/libvirt/libvirt-domain.h | 1 + > src/qemu/qemu_migration.c | 10 ++++++++++ > tools/virsh-domain-event.c | 3 ++- > 4 files changed, 16 insertions(+), 1 deletion(-) Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
© 2016 - 2026 Red Hat, Inc.