[PATCH 06/12] Domain Events - qemu driver Register for, and dispatch domain event callbacks qemu_conf.h | 3 + qemu_driver.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/src/qemu_conf.h b/src/qemu_conf.h index cfd7d35..d06c4d7 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -63,6 +63,9 @@ struct qemud_driver { char *vncListen; virCapsPtr caps; + + /* An array of callbacks */ + virDomainEventCallbackListPtr domainEventCallbacks; }; diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 59d7166..a9a9340 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -106,7 +106,12 @@ static int qemudSetNonBlock(int fd) { } -static void qemudDispatchVMEvent(int fd, int events, void *opaque); +static void qemudDomainEventDispatch (struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainEventType evt); + +static void qemudDispatchVMEvent(int fd, virEventHandleType events, + void *opaque); static int qemudStartVMDaemon(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, @@ -159,6 +164,10 @@ qemudStartup(void) { /* Don't have a dom0 so start from 1 */ qemu_driver->nextvmid = 1; + /* Init callback list */ + if(VIR_ALLOC(qemu_driver->domainEventCallbacks) < 0) + return -1; + if (!uid) { if (asprintf(&qemu_driver->logDir, "%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1) @@ -301,6 +310,9 @@ qemudShutdown(void) { VIR_FREE(qemu_driver->autostartDir); VIR_FREE(qemu_driver->vncTLSx509certdir); + /* Free domain callback list */ + virDomainEventCallbackListFree(qemu_driver->domainEventCallbacks); + if (qemu_driver->brctl) brShutdown(qemu_driver->brctl); @@ -742,6 +754,9 @@ static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { return -1; } +static virDomainPtr qemudDomainLookupByName(virConnectPtr conn, + const char *name); + static int qemudStartVMDaemon(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, @@ -756,6 +771,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, unsigned int qemuCmdFlags; fd_set keepfd; const char *emulator; + virDomainPtr dom; FD_ZERO(&keepfd); @@ -905,11 +921,15 @@ static int qemudStartVMDaemon(virConnectPtr conn, if (ret == 0) { if ((virEventAddHandle(vm->stdout_fd, - POLLIN | POLLERR | POLLHUP, + VIR_EVENT_HANDLE_READABLE | + VIR_EVENT_HANDLE_ERROR | + VIR_EVENT_HANDLE_HANGUP, qemudDispatchVMEvent, driver) < 0) || (virEventAddHandle(vm->stderr_fd, - POLLIN | POLLERR | POLLHUP, + VIR_EVENT_HANDLE_READABLE | + VIR_EVENT_HANDLE_ERROR | + VIR_EVENT_HANDLE_HANGUP, qemudDispatchVMEvent, driver) < 0) || (qemudWaitForMonitor(conn, driver, vm) < 0) || @@ -918,6 +938,11 @@ static int qemudStartVMDaemon(virConnectPtr conn, qemudShutdownVMDaemon(conn, driver, vm); return -1; } + dom = qemudDomainLookupByName(conn,vm->def->name); + if(dom) + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STARTED); + else + DEBUG0("Warning - dom is NULL at domain start"); } return ret; @@ -1012,6 +1037,7 @@ static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, i static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr vm, int fd ATTRIBUTE_UNUSED) { qemudShutdownVMDaemon(NULL, driver, vm); + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STOPPED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -1019,7 +1045,8 @@ static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr v } -static void qemudDispatchVMEvent(int fd, int events, void *opaque) { +static void +qemudDispatchVMEvent(int fd, virEventHandleType events, void *opaque) { struct qemud_driver *driver = (struct qemud_driver *)opaque; virDomainObjPtr vm = NULL; unsigned int i; @@ -1036,7 +1063,7 @@ static void qemudDispatchVMEvent(int fd, int events, void *opaque) { if (!vm) return; - if (events == POLLIN) + if (events == VIR_EVENT_HANDLE_READABLE) qemudDispatchVMLog(driver, vm, fd); else qemudDispatchVMFailure(driver, vm, fd); @@ -1503,6 +1530,7 @@ static int qemudDomainSuspend(virDomainPtr dom) { } vm->state = VIR_DOMAIN_PAUSED; qemudDebug("Reply %s", info); + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_SUSPENDED); VIR_FREE(info); return 0; } @@ -1531,6 +1559,7 @@ static int qemudDomainResume(virDomainPtr dom) { } vm->state = VIR_DOMAIN_RUNNING; qemudDebug("Reply %s", info); + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESUMED); VIR_FREE(info); return 0; } @@ -1569,10 +1598,10 @@ static int qemudDomainDestroy(virDomainPtr dom) { } qemudShutdownVMDaemon(dom->conn, driver, vm); + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STOPPED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); - return 0; } @@ -1903,7 +1932,7 @@ static int qemudDomainSave(virDomainPtr dom, if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); - + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_SAVED); return 0; } @@ -2104,6 +2133,7 @@ static int qemudDomainRestore(virConnectPtr conn, struct qemud_driver *driver = (struct qemud_driver *)conn->privateData; virDomainDefPtr def; virDomainObjPtr vm; + virDomainPtr dom; int fd; int ret; char *xml; @@ -2210,6 +2240,11 @@ static int qemudDomainRestore(virConnectPtr conn, vm->state = VIR_DOMAIN_RUNNING; } + dom = virDomainLookupByID(conn, def->id); + if(dom) { + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESTORED); + VIR_FREE(dom); + } return 0; } @@ -3148,6 +3183,56 @@ done: } +static int +qemudDomainEventRegister (virConnectPtr conn, + void *callback, + void *opaque) +{ + struct qemud_driver *driver = (struct qemud_driver *)conn->privateData; + + return virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks, + callback, opaque); +} + +static int +qemudDomainEventDeregister (virConnectPtr conn, + void *callback) +{ + struct qemud_driver *driver = (struct qemud_driver *)conn->privateData; + + return virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks, + callback); +} + +static void qemudDomainEventDispatch (struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainEventType evt) +{ + int i; + virDomainEventCallbackListPtr cbList; + + cbList = driver->domainEventCallbacks; + + for(i=0 ; i < cbList->count ; i++) { + if(cbList->callbacks[i] && cbList->callbacks[i]->cb) { + virConnectPtr conn = cbList->callbacks[i]->conn; + virDomainPtr dom = virGetDomain(conn, vm->def->name, + vm->def->uuid); + if (dom) { + dom->id = virDomainIsActive(vm) ? vm->def->id : -1; + DEBUG("Dispatching callback %p %p event %d", + cbList->callbacks[i], + cbList->callbacks[i]->cb, evt); + cbList->callbacks[i]->cb(cbList->callbacks[i]->conn, + dom, evt, + cbList->callbacks[i]->opaque); + virDomainFree(dom); + } + } + } + +} + static virDriver qemuDriver = { VIR_DRV_QEMU, "QEMU", @@ -3218,6 +3303,8 @@ static virDriver qemuDriver = { NULL, /* nodeGetCellsFreeMemory */ NULL, /* getFreeMemory */ #endif + qemudDomainEventRegister, /* domainEventRegister */ + qemudDomainEventDeregister, /* domainEventDeregister */ };
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list