+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:
return -1;
}
-void qemudReload(void) {
+int qemudReload(void) {
qemudScanConfigs(qemu_driver);
if (qemu_driver->iptables) {
}
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;
free(qemu_driver);
qemu_driver = NULL;
+
+ return 0;
}
static int
qemudNetworkSetAutostart, /* networkSetAutostart */
};
+static virStateDriver qemuStateDriver = {
+ qemudStartup,
+ qemudShutdown,
+ qemudReload,
+ qemudActive,
+};
/*
* Local variables:
#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,
#include "remote_protocol.h"
#include "bridge.h"
#include "iptables.h"
+#include "../config.h"
#ifdef __GNUC__
#ifdef HAVE_ANSIDECL_H
#include <libvirt/virterror.h>
#include "internal.h"
+#include "../src/internal.h"
#include "../src/remote_internal.h"
#include "../src/conf.h"
#include "dispatch.h"
switch (sigc) {
case SIGHUP:
qemudLog(QEMUD_INFO, "Reloading configuration on SIGHUP");
+ if (virStateReload() < 0)
+ qemudLog(QEMUD_WARN, "Error while reloading drivers");
+
if (!remote) {
qemudReload();
}
if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1) < 0)
goto cleanup;
+ virStateInitialize();
+
if (!remote) /* qemud only */ {
if (qemudStartup() < 0) {
goto cleanup;
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) {
qemudShutdown();
+ virStateCleanup();
free(server);
}
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
*/
int virRegisterDriver(virDriverPtr);
int virRegisterNetworkDriver(virNetworkDriverPtr);
+int virRegisterStateDriver(virStateDriverPtr);
#ifdef __cplusplus
}
#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 */
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;
/**
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)
__virEventRegisterImpl;
+ __virStateInitialize;
+ __virStateCleanup;
+ __virStateReload;
+ __virStateActive;
+
local: *;
};