[libvirt] [PATCH 0/2] notify about reverting to snapshot

Reverting to snapshot may change domain configuration but there will be no events about that. Lack of the event become a problem for virt-manager https://bugzilla.redhat.com/show_bug.cgi?id=1081148 This patch-set introduces new event and emits it in qemuDomainRevertToSnapshot. Dmitry Andreev (2): Introduce new VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT event qemu: emit 'defined' event after reverted to snapshot examples/object-events/event-test.c | 2 ++ include/libvirt/libvirt-domain.h | 1 + src/qemu/qemu_driver.c | 5 +++++ tools/virsh-domain.c | 3 ++- 4 files changed, 10 insertions(+), 1 deletion(-) -- 1.8.3.1

This should be emitted whenever a domain is reverted to snapshot. --- examples/object-events/event-test.c | 2 ++ include/libvirt/libvirt-domain.h | 1 + tools/virsh-domain.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/object-events/event-test.c b/examples/object-events/event-test.c index dcae981..afac100 100644 --- a/examples/object-events/event-test.c +++ b/examples/object-events/event-test.c @@ -110,6 +110,8 @@ static const char *eventDetailToString(int event, int detail) { ret = "Updated"; else if (detail == VIR_DOMAIN_EVENT_DEFINED_RENAMED) ret = "Renamed"; + else if (detail == VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT) + ret = "Snapshot"; break; case VIR_DOMAIN_EVENT_UNDEFINED: if (detail == VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index a1ea6a5..f3d360b 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2330,6 +2330,7 @@ typedef enum { VIR_DOMAIN_EVENT_DEFINED_ADDED = 0, /* Newly created config file */ VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1, /* Changed config file */ VIR_DOMAIN_EVENT_DEFINED_RENAMED = 2, /* Domain was renamed */ + VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT = 3, /* Config file was restored from a snapshot */ # ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_DEFINED_LAST diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index b7e7606..a257cc7 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -11910,7 +11910,8 @@ VIR_ENUM_IMPL(virshDomainEventDefined, VIR_DOMAIN_EVENT_DEFINED_LAST, N_("Added"), N_("Updated"), - N_("Renamed")) + N_("Renamed"), + N_("Snapshot")) VIR_ENUM_DECL(virshDomainEventUndefined) VIR_ENUM_IMPL(virshDomainEventUndefined, -- 1.8.3.1

Config file is changed. VIR_DOMAIN_EVENT_DEFINED should be emitted --- src/qemu/qemu_driver.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ae1d8e7..b32172a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15293,6 +15293,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, virDomainSnapshotObjPtr snap = NULL; virObjectEventPtr event = NULL; virObjectEventPtr event2 = NULL; + virObjectEventPtr define_event = NULL; int detail; qemuDomainObjPrivatePtr priv; int rc; @@ -15401,6 +15402,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, config = virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, true); if (!config) goto endjob; + define_event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_DEFINED, + VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT); } switch ((virDomainState) snap->def->state) { @@ -15627,6 +15631,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, } else if (snap) { snap->def->current = false; } + qemuDomainEventQueue(driver, define_event); if (event) { qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event2); -- 1.8.3.1

On 12/09/2015 03:29 AM, Dmitry Andreev wrote:
Config file is changed. VIR_DOMAIN_EVENT_DEFINED should be emitted --- src/qemu/qemu_driver.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ae1d8e7..b32172a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15293,6 +15293,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, virDomainSnapshotObjPtr snap = NULL; virObjectEventPtr event = NULL; virObjectEventPtr event2 = NULL; + virObjectEventPtr define_event = NULL; int detail; qemuDomainObjPrivatePtr priv; int rc; @@ -15401,6 +15402,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, config = virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, true); if (!config) goto endjob; + define_event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_DEFINED, + VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT); }
switch ((virDomainState) snap->def->state) { @@ -15627,6 +15631,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, } else if (snap) { snap->def->current = false; } + qemuDomainEventQueue(driver, define_event);
I think this can go right after the generation of the event. That way it can come "in order"... Following the rest of the logic, event can be queued as it happens and then "reused" in a few instances prior to event2 being generated. Then at cleanup the most recent event and event2 get queued. If you're OK with me moving that, then I can do so and push the two patches. John
if (event) { qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event2);

On 14.12.2015 23:10, John Ferlan wrote:
On 12/09/2015 03:29 AM, Dmitry Andreev wrote:
Config file is changed. VIR_DOMAIN_EVENT_DEFINED should be emitted --- src/qemu/qemu_driver.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ae1d8e7..b32172a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15293,6 +15293,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, virDomainSnapshotObjPtr snap = NULL; virObjectEventPtr event = NULL; virObjectEventPtr event2 = NULL; + virObjectEventPtr define_event = NULL; int detail; qemuDomainObjPrivatePtr priv; int rc; @@ -15401,6 +15402,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, config = virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, true); if (!config) goto endjob; + define_event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_DEFINED, + VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT); }
switch ((virDomainState) snap->def->state) { @@ -15627,6 +15631,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, } else if (snap) { snap->def->current = false; } + qemuDomainEventQueue(driver, define_event);
I think this can go right after the generation of the event. That way it can come "in order"...
Following the rest of the logic, event can be queued as it happens and then "reused" in a few instances prior to event2 being generated. Then at cleanup the most recent event and event2 get queued.
As I can see from the code - 'stopped' event is the only event that is queued as it happens. The VM state is changed to STOPPED inside the switch for few cases. If you queue the 'defined' event before the switch (or right after the generation) the order will be 'defined' -> 'stopped' -> event -> event2 when the natural order is 'stopped' before 'defined'. API client will get 'defined' event for VM with cached running state before you send him 'stopped' event.
If you're OK with me moving that, then I can do so and push the two patches.
John
if (event) { qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event2);

On 12/15/2015 04:00 AM, Dmitry Andreev wrote:
On 14.12.2015 23:10, John Ferlan wrote:
On 12/09/2015 03:29 AM, Dmitry Andreev wrote:
Config file is changed. VIR_DOMAIN_EVENT_DEFINED should be emitted --- src/qemu/qemu_driver.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ae1d8e7..b32172a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15293,6 +15293,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, virDomainSnapshotObjPtr snap = NULL; virObjectEventPtr event = NULL; virObjectEventPtr event2 = NULL; + virObjectEventPtr define_event = NULL; int detail; qemuDomainObjPrivatePtr priv; int rc; @@ -15401,6 +15402,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, config = virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, true); if (!config) goto endjob; + define_event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_DEFINED, + VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT); }
switch ((virDomainState) snap->def->state) { @@ -15627,6 +15631,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, } else if (snap) { snap->def->current = false; } + qemuDomainEventQueue(driver, define_event);
I think this can go right after the generation of the event. That way it can come "in order"...
Following the rest of the logic, event can be queued as it happens and then "reused" in a few instances prior to event2 being generated. Then at cleanup the most recent event and event2 get queued.
As I can see from the code - 'stopped' event is the only event that is queued as it happens. The VM state is changed to STOPPED inside the switch for few cases. If you queue the 'defined' event before the switch (or right after the generation) the order will be 'defined' -> 'stopped' -> event -> event2 when the natural order is 'stopped' before 'defined'.
API client will get 'defined' event for VM with cached running state before you send him 'stopped' event.
hmm... true. Following the transitions is a bit of a challenge. Not part of this issue, but I think there's also a bug in there now. I'll send a different patch on that... As for this new event, I think there is an odd path after the comment about transitions 1, 4, 7, where the STOP event is created, but before the "if (config)", we goto cleanup where the DEFINED event could be generated before the STOP event gets queued, but the redefinition never occurs. So, I think perhaps, prior to the "goto cleanup;" there could be virObjectUnref(define_event); define_event = NULL; similar to what happens in the code after the comments about transitions 2, 5, 8 when the event is cleared. Alternatively, whenever there is: if (config) virDomainObjAssignDef(...) that's when the "define_event" could be queued, especially since once that ObjAssignDef code runs - regardless of what other paths are taken in the code, the domain is redefined. John
If you're OK with me moving that, then I can do so and push the two patches.
John
if (event) { qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event2);
participants (2)
-
Dmitry Andreev
-
John Ferlan