[libvirt] [PATCH v2 0/2] Emit more events

diff to v1: -a new event invented -more APIs updated Michal Privoznik (2): Introduce new VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR event qemu: Emit event if 'cont' fails examples/domain-events/events-c/event-test.c | 3 + examples/domain-events/events-python/event-test.py | 2 +- include/libvirt/libvirt.h.in | 1 + src/qemu/qemu_driver.c | 59 ++++++++++++++------ 4 files changed, 47 insertions(+), 18 deletions(-) -- 1.7.8.6

This is supposed to be thrown every time we need to pause domain because of API execution (e.g. qemuDomainSaveInternal) but fails to restore it back after. In this case, domain remains paused, however, none of existing reasons can fit this scenario. --- examples/domain-events/events-c/event-test.c | 3 +++ examples/domain-events/events-python/event-test.py | 2 +- include/libvirt/libvirt.h.in | 1 + 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 39bea49..ee324b3 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -149,6 +149,9 @@ static const char *eventDetailToString(int event, int detail) { case VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT: ret = "Snapshot"; break; + case VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR: + ret = "Api error"; + break; } break; case VIR_DOMAIN_EVENT_RESUMED: diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py index 2bb5195..cd9e2b4 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -445,7 +445,7 @@ def detailToString(event, detail): ( "Added", "Updated" ), ( "Removed", ), ( "Booted", "Migrated", "Restored", "Snapshot", "Wakeup" ), - ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot" ), + ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot", "Api error" ), ( "Unpaused", "Migrated", "Snapshot" ), ( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"), ( "Finished", ), diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index fe58c08..bf584a0 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3159,6 +3159,7 @@ typedef enum { VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG = 3, /* Suspended due to a watchdog firing */ VIR_DOMAIN_EVENT_SUSPENDED_RESTORED = 4, /* Restored from paused state file */ VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT = 5, /* Restored from paused snapshot */ + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR = 6, /* suspended after failure during libvirt API call */ #ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_SUSPENDED_LAST -- 1.7.8.6

On 11/06/2012 11:23 AM, Michal Privoznik wrote:
This is supposed to be thrown every time we need to pause domain because of API execution (e.g. qemuDomainSaveInternal) but fails to restore it back after. In this case, domain remains paused, however, none of existing reasons can fit this scenario. --- examples/domain-events/events-c/event-test.c | 3 +++ examples/domain-events/events-python/event-test.py | 2 +- include/libvirt/libvirt.h.in | 1 + 3 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 39bea49..ee324b3 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -149,6 +149,9 @@ static const char *eventDetailToString(int event, int detail) { case VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT: ret = "Snapshot"; break; + case VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR: + ret = "Api error";
s/Api/API/
+++ b/examples/domain-events/events-python/event-test.py @@ -445,7 +445,7 @@ def detailToString(event, detail): ( "Added", "Updated" ), ( "Removed", ), ( "Booted", "Migrated", "Restored", "Snapshot", "Wakeup" ), - ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot" ), + ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot", "Api error" ),
and again.
( "Unpaused", "Migrated", "Snapshot" ), ( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"), ( "Finished", ), diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index fe58c08..bf584a0 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3159,6 +3159,7 @@ typedef enum { VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG = 3, /* Suspended due to a watchdog firing */ VIR_DOMAIN_EVENT_SUSPENDED_RESTORED = 4, /* Restored from paused state file */ VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT = 5, /* Restored from paused snapshot */ + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR = 6, /* suspended after failure during libvirt API call */
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Some operations, APIs needs domain to be paused prior operation can be performed, e.g. (managed-) save of a domain. The processors should be restored in the end. However, if 'cont' fails for some reason, we log a message but this is not sufficient as an event should be emitted as well. Mgmt application can then decide what to do. --- src/qemu/qemu_driver.c | 59 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 978af57..b640f1a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2990,8 +2990,12 @@ endjob: rc = qemuProcessStartCPUs(driver, vm, dom->conn, VIR_DOMAIN_RUNNING_SAVE_CANCELED, QEMU_ASYNC_JOB_SAVE); - if (rc < 0) + if (rc < 0) { VIR_WARN("Unable to resume guest CPUs after save failure"); + event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); + } } } if (qemuDomainObjEndAsyncJob(driver, vm) == 0) @@ -3448,6 +3452,9 @@ endjob: if (resume && qemuProcessStartCPUs(driver, vm, dom->conn, VIR_DOMAIN_RUNNING_UNPAUSED, QEMU_ASYNC_JOB_DUMP) < 0) { + event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); if (virGetLastError() == NULL) virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resuming after dump failed")); @@ -10665,6 +10672,7 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn, { virDomainObjPtr vm = *vmptr; qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainEventPtr event = NULL; bool resume = false; int ret = -1; @@ -10701,8 +10709,6 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn, goto cleanup; if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) { - virDomainEventPtr event; - event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT); qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT, 0); @@ -10712,18 +10718,20 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn, ignore_value(qemuDomainObjEndJob(driver, vm)); resume = false; vm = NULL; - if (event) - qemuDomainEventQueue(driver, event); } cleanup: if (resume && virDomainObjIsActive(vm) && qemuProcessStartCPUs(driver, vm, conn, VIR_DOMAIN_RUNNING_UNPAUSED, - QEMU_ASYNC_JOB_NONE) < 0 && - virGetLastError() == NULL) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("resuming after snapshot failed")); + QEMU_ASYNC_JOB_NONE) < 0) { + event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); + if (virGetLastError() == NULL) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("resuming after snapshot failed")); + } } endjob: @@ -10734,6 +10742,9 @@ endjob: ret = -1; } + if (event) + qemuDomainEventQueue(driver, event); + return ret; } @@ -11234,10 +11245,17 @@ endjob: if (resume && vm && virDomainObjIsActive(vm) && qemuProcessStartCPUs(driver, vm, conn, VIR_DOMAIN_RUNNING_UNPAUSED, - QEMU_ASYNC_JOB_NONE) < 0 && - virGetLastError() == NULL) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("resuming after snapshot failed")); + QEMU_ASYNC_JOB_NONE) < 0) { + virDomainEventPtr event = NULL; + event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); + if (event) + qemuDomainEventQueue(driver, event); + if (virGetLastError() == NULL) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("resuming after snapshot failed")); + } return -1; } @@ -12814,10 +12832,17 @@ cleanup: if (resume && virDomainObjIsActive(vm) && qemuProcessStartCPUs(driver, vm, conn, VIR_DOMAIN_RUNNING_UNPAUSED, - QEMU_ASYNC_JOB_NONE) < 0 && - virGetLastError() == NULL) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("resuming after drive-reopen failed")); + QEMU_ASYNC_JOB_NONE) < 0) { + virDomainEventPtr event = NULL; + event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); + if (event) + qemuDomainEventQueue(driver, event); + if (virGetLastError() == NULL) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("resuming after drive-reopen failed")); + } } return ret; } -- 1.7.8.6

On 11/06/2012 11:23 AM, Michal Privoznik wrote:
Some operations, APIs needs domain to be paused prior operation can be performed, e.g. (managed-) save of a domain. The processors should be restored in the end. However, if 'cont' fails for some reason, we log a message but this is not sufficient as an event should be emitted as well. Mgmt application can then decide what to do. --- src/qemu/qemu_driver.c | 59 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 42 insertions(+), 17 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06.11.2012 21:00, Eric Blake wrote:
On 11/06/2012 11:23 AM, Michal Privoznik wrote:
Some operations, APIs needs domain to be paused prior operation can be performed, e.g. (managed-) save of a domain. The processors should be restored in the end. However, if 'cont' fails for some reason, we log a message but this is not sufficient as an event should be emitted as well. Mgmt application can then decide what to do. --- src/qemu/qemu_driver.c | 59 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 42 insertions(+), 17 deletions(-)
ACK.
Fixed capitalization in the 1st patch and pushed. Thanks. Michal
participants (2)
-
Eric Blake
-
Michal Privoznik