[libvirt] Re: [PATCH 06/12] Domain Events - qemu driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[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

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]