]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add driver API for global startup/shutdown/reload hooks
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 26 Jun 2007 22:56:14 +0000 (22:56 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 26 Jun 2007 22:56:14 +0000 (22:56 +0000)
ChangeLog
qemud/driver.c
qemud/driver.h
qemud/internal.h
qemud/qemud.c
src/driver.h
src/internal.h
src/libvirt.c
src/libvirt_sym.version

index d75c37ca86f228aa7c062d584d0e7dc2f32e51fd..cd65bb3dfe76d29fbdf412e59ef6867e132e607f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Tue Jun 26 18:53:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/internal.h, src/libvirt.c, src/driver.h, src/libvirt_sym.version
+       Added internal driver API hooks for global shutdown/startup/reload
+       * qemud/driver.c, qemud/driver.h, qemud/internal.h, qemud/qemud.c
+       Adapt to make use of new driver API for startup/shutdown
+
 Tue Jun 26 18:47:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
 
        * src/event.h, src/event.c, src/Makefile.am, src/libvirt_sym.version:
index 7f0d113e169f7245cad050ec76a1bb5b080f014e..62b6ac2ed8ab582ec3140ca2486fbf7a57bbacc5 100644 (file)
@@ -205,7 +205,7 @@ int qemudStartup(void) {
     return -1;
 }
 
-void qemudReload(void) {
+int qemudReload(void) {
     qemudScanConfigs(qemu_driver);
 
      if (qemu_driver->iptables) {
@@ -214,14 +214,28 @@ void qemudReload(void) {
     }
 
     qemudAutostartConfigs(qemu_driver);
+
+    return 0;
 }
 
-void qemudShutdown() {
+int qemudActive(void) {
+    /* If we've any active networks or guests, then we
+     * mark this driver as active
+     */
+    if (qemu_driver->nactivenetworks &&
+        qemu_driver->nactivevms)
+        return 1;
+
+    /* Otherwise we're happy to deal with a shutdown */
+    return 0;
+}
+
+int qemudShutdown() {
     struct qemud_vm *vm;
     struct qemud_network *network;
 
     if (!qemu_driver)
-        return;
+        return -1;
 
     /* shutdown active VMs */
     vm = qemu_driver->vms;
@@ -279,6 +293,8 @@ void qemudShutdown() {
 
     free(qemu_driver);
     qemu_driver = NULL;
+
+    return 0;
 }
 
 static int
@@ -2516,6 +2532,12 @@ static virNetworkDriver qemuNetworkDriver = {
     qemudNetworkSetAutostart, /* networkSetAutostart */
 };
 
+static virStateDriver qemuStateDriver = {
+    qemudStartup,
+    qemudShutdown,
+    qemudReload,
+    qemudActive,
+};
 
 /*
  * Local variables:
index b4228757e1ef1155889991e465c04b6383217839..957754bb8d9629c93357369df0b0ddcdfd8bd5ef 100644 (file)
@@ -29,8 +29,9 @@
 #include "../src/internal.h"
 
 int qemudStartup(void);
-void qemudReload(void);
-void qemudShutdown(void);
+int qemudReload(void);
+int qemudShutdown(void);
+int qemudActive(void);
 
 
 virDrvOpenStatus qemudOpen(virConnectPtr conn,
index 73b38631d55d762380bce0b70be40b25e49656e7..c709146fc038c40959837e68c3a6f0bdcdcc9277 100644 (file)
@@ -34,6 +34,7 @@
 #include "remote_protocol.h"
 #include "bridge.h"
 #include "iptables.h"
+#include "../config.h"
 
 #ifdef __GNUC__
 #ifdef HAVE_ANSIDECL_H
index 669c61cf92d0401570b59702f25cd06d7f1a7e75..f33facbc066996a9fcc7ee31692bb0b3e7343636 100644 (file)
@@ -54,6 +54,7 @@
 #include <libvirt/virterror.h>
 
 #include "internal.h"
+#include "../src/internal.h"
 #include "../src/remote_internal.h"
 #include "../src/conf.h"
 #include "dispatch.h"
@@ -206,6 +207,9 @@ static void qemudDispatchSignalEvent(int fd ATTRIBUTE_UNUSED,
     switch (sigc) {
     case SIGHUP:
         qemudLog(QEMUD_INFO, "Reloading configuration on SIGHUP");
+        if (virStateReload() < 0)
+            qemudLog(QEMUD_WARN, "Error while reloading drivers");
+
         if (!remote) {
             qemudReload();
         }
@@ -704,6 +708,8 @@ static struct qemud_server *qemudInitialize(int sigread) {
     if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1) < 0)
         goto cleanup;
 
+    virStateInitialize();
+
     if (!remote) /* qemud only */ {
         if (qemudStartup() < 0) {
             goto cleanup;
@@ -1478,13 +1484,45 @@ static int qemudOneLoop(void) {
     return 0;
 }
 
+static void qemudInactiveTimer(int timer ATTRIBUTE_UNUSED, void *data) {
+    struct qemud_server *server = (struct qemud_server *)data;
+    qemudDebug("Got inactive timer expiry");
+    if (!virStateActive()) {
+        qemudDebug("No state active, shutting down");
+        server->shutdown = 1;
+    }
+}
+
 static int qemudRunLoop(struct qemud_server *server) {
-    int ret;
+    int timerid = -1;
+
+    for (;;) {
+        /* A shutdown timeout is specified, so check
+         * if any drivers have active state, if not
+         * shutdown after timeout seconds
+         */
+        if (timeout > 0 && !virStateActive() && !server->clients) {
+            timerid = virEventAddTimeoutImpl(timeout*1000, qemudInactiveTimer, server);
+            qemudDebug("Scheduling shutdown timer %d", timerid);
+        }
+
+        if (qemudOneLoop() < 0)
+            break;
 
-    while ((ret = qemudOneLoop()) == 0 && !server->shutdown)
-        ;
+        /* Unregister any timeout that's active, since we
+         * just had an event processed
+         */
+        if (timerid != -1) {
+            qemudDebug("Removing shutdown timer %d", timerid);
+            virEventRemoveTimeoutImpl(timerid);
+            timerid = -1;
+        }
 
-    return ret == -1 ? -1 : 0;
+        if (server->shutdown)
+            return 0;
+    }
+
+    return -1;
 }
 
 static void qemudCleanup(struct qemud_server *server) {
@@ -1502,6 +1540,7 @@ static void qemudCleanup(struct qemud_server *server) {
 
 
     qemudShutdown();
+    virStateCleanup();
 
     free(server);
 }
index 077a4b4a4be22483ffb024e505edb4c26f24983a..fe4f9e2439e70a18cb15878f2a71c269ce3a1aec 100644 (file)
@@ -322,6 +322,20 @@ struct _virNetworkDriver {
        virDrvNetworkSetAutostart       networkSetAutostart;
 };
 
+typedef int (*virDrvStateInitialize) (void);
+typedef int (*virDrvStateCleanup) (void);
+typedef int (*virDrvStateReload) (void);
+typedef int (*virDrvStateActive) (void);
+
+typedef struct _virStateDriver virStateDriver;
+typedef virStateDriver *virStateDriverPtr;
+
+struct _virStateDriver {
+    virDrvStateInitialize  initialize;
+    virDrvStateCleanup     cleanup;
+    virDrvStateReload      reload;
+    virDrvStateActive      active;
+};
 
 /*
  * Registration
@@ -330,6 +344,7 @@ struct _virNetworkDriver {
  */
 int virRegisterDriver(virDriverPtr);
 int virRegisterNetworkDriver(virNetworkDriverPtr);
+int virRegisterStateDriver(virStateDriverPtr);
 
 #ifdef __cplusplus
 }
index a0a074de52dba8b70f16717b867d607a22856f40..ee7b17e336a86a0b88357c39514e111ed7481662 100644 (file)
@@ -220,6 +220,15 @@ int                virFreeNetwork  (virConnectPtr conn,
 #define virGetDomain(c,n,u) __virGetDomain((c),(n),(u))
 #define virGetNetwork(c,n,u) __virGetNetwork((c),(n),(u))
 
+int __virStateInitialize(void);
+int __virStateCleanup(void);
+int __virStateReload(void);
+int __virStateActive(void);
+#define virStateInitialize() __virStateInitialize()
+#define virStateCleanup() __virStateCleanup()
+#define virStateReload() __virStateReload()
+#define virStateActive() __virStateActive()
+
 #ifdef __cplusplus
 }
 #endif                          /* __cplusplus */
index e473e533bf1ff364c4fce096f2e05991aef0325b..e8ca9173be19b406737b367eb1b24f7e8fdf109f 100644 (file)
@@ -40,6 +40,8 @@ static virDriverPtr virDriverTab[MAX_DRIVERS];
 static int virDriverTabCount = 0;
 static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
 static int virNetworkDriverTabCount = 0;
+static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
+static int virStateDriverTabCount = 0;
 static int initialized = 0;
 
 /**
@@ -240,6 +242,79 @@ virRegisterDriver(virDriverPtr driver)
     return virDriverTabCount++;
 }
 
+/**
+ * virRegisterStateDriver:
+ * @driver: pointer to a driver block
+ *
+ * Register a virtualization driver
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+virRegisterStateDriver(virStateDriverPtr driver)
+{
+    if (virInitialize() < 0)
+      return -1;
+
+    if (driver == NULL) {
+        virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    if (virStateDriverTabCount >= MAX_DRIVERS) {
+       virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    virStateDriverTab[virStateDriverTabCount] = driver;
+    return virStateDriverTabCount++;
+}
+
+int __virStateInitialize(void) {
+    int i, ret = 0;
+
+    if (virInitialize() < 0)
+        return -1;
+
+    for (i = 0 ; i < virStateDriverTabCount ; i++) {
+        if (virStateDriverTab[i]->initialize() < 0)
+            ret = -1;
+    }
+    return ret;
+}
+
+int __virStateCleanup(void) {
+    int i, ret = 0;
+
+    for (i = 0 ; i < virStateDriverTabCount ; i++) {
+        if (virStateDriverTab[i]->cleanup() < 0)
+            ret = -1;
+    }
+    return ret;
+}
+
+int __virStateReload(void) {
+    int i, ret = 0;
+
+    for (i = 0 ; i < virStateDriverTabCount ; i++) {
+        if (virStateDriverTab[i]->reload() < 0)
+            ret = -1;
+    }
+    return ret;
+}
+
+int __virStateActive(void) {
+    int i, ret = 0;
+
+    for (i = 0 ; i < virStateDriverTabCount ; i++) {
+        if (virStateDriverTab[i]->active())
+            ret = 1;
+    }
+    return ret;
+}
+
+
+
 /**
  * virGetVersion:
  * @libVer: return value for the library version (OUT)
index d71ca8e197c7b2d4e3a437c69930a9ba1ef0af09..f32deae9e0cfe49b84348f0fb62d4d0ab85640a6 100644 (file)
 
        __virEventRegisterImpl;
 
+       __virStateInitialize;
+       __virStateCleanup;
+       __virStateReload;
+       __virStateActive;
+
     local: *;
 };