[libvirt] [PATCH] Add domain events support to UML driver
Daniel P. Berrange
berrange at redhat.com
Tue Jul 12 16:04:30 UTC 2011
Any thoughts on this patch..
Regards,
Daniel
On Mon, Jul 04, 2011 at 01:32:23PM +0100, Daniel P. Berrange wrote:
> * src/uml_conf.h: Add queue for dispatch of domain events
> * src/uml_driver.c: Trigger domain events upon important lifecycle transitions
> ---
> src/uml/uml_conf.h | 4 +
> src/uml/uml_driver.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 194 insertions(+), 4 deletions(-)
>
> diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h
> index 1105f84..5401a7e 100644
> --- a/src/uml/uml_conf.h
> +++ b/src/uml/uml_conf.h
> @@ -29,6 +29,7 @@
> # include "capabilities.h"
> # include "network_conf.h"
> # include "domain_conf.h"
> +# include "domain_event.h"
> # include "virterror_internal.h"
> # include "threads.h"
> # include "command.h"
> @@ -60,6 +61,9 @@ struct uml_driver {
> int inotifyWatch;
>
> virCapsPtr caps;
> +
> + /* Event handling */
> + virDomainEventStatePtr domainEventState;
> };
>
>
> diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
> index 91591f1..d0736df 100644
> --- a/src/uml/uml_driver.c
> +++ b/src/uml/uml_driver.c
> @@ -113,6 +113,9 @@ static int umlOpenMonitor(struct uml_driver *driver,
> virDomainObjPtr vm);
> static int umlReadPidFile(struct uml_driver *driver,
> virDomainObjPtr vm);
> +static void umlDomainEventFlush(int timer, void *opaque);
> +static void umlDomainEventQueue(struct uml_driver *driver,
> + virDomainEventPtr event);
>
> static int umlSetCloseExec(int fd) {
> int flags;
> @@ -166,6 +169,13 @@ umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu
> virErrorPtr err = virGetLastError();
> VIR_ERROR(_("Failed to autostart VM '%s': %s"),
> vm->def->name, err ? err->message : _("unknown error"));
> + } else {
> + virDomainEventPtr event =
> + virDomainEventNewFromObj(vm,
> + VIR_DOMAIN_EVENT_STARTED,
> + VIR_DOMAIN_EVENT_STARTED_BOOTED);
> + if (event)
> + umlDomainEventQueue(data->driver, event);
> }
> }
> virDomainObjUnlock(vm);
> @@ -185,7 +195,9 @@ umlAutostartConfigs(struct uml_driver *driver) {
>
> struct umlAutostartData data = { driver, conn };
>
> + umlDriverLock(driver);
> virHashForEach(driver->domains.objs, umlAutostartDomain, &data);
> + umlDriverUnlock(driver);
>
> if (conn)
> virConnectClose(conn);
> @@ -266,6 +278,7 @@ umlInotifyEvent(int watch,
> char *tmp, *name;
> struct uml_driver *driver = data;
> virDomainObjPtr dom;
> + virDomainEventPtr event = NULL;
>
> umlDriverLock(driver);
> if (watch != driver->inotifyWatch)
> @@ -311,6 +324,9 @@ reread:
>
> umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
> virDomainAuditStop(dom, "shutdown");
> + event = virDomainEventNewFromObj(dom,
> + VIR_DOMAIN_EVENT_STOPPED,
> + VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
> if (!dom->persistent) {
> virDomainRemoveInactive(&driver->domains,
> dom);
> @@ -337,6 +353,9 @@ reread:
> umlShutdownVMDaemon(NULL, driver, dom,
> VIR_DOMAIN_SHUTOFF_FAILED);
> virDomainAuditStop(dom, "failed");
> + event = virDomainEventNewFromObj(dom,
> + VIR_DOMAIN_EVENT_STOPPED,
> + VIR_DOMAIN_EVENT_STOPPED_FAILED);
> if (!dom->persistent) {
> virDomainRemoveInactive(&driver->domains,
> dom);
> @@ -347,6 +366,9 @@ reread:
> umlShutdownVMDaemon(NULL, driver, dom,
> VIR_DOMAIN_SHUTOFF_FAILED);
> virDomainAuditStop(dom, "failed");
> + event = virDomainEventNewFromObj(dom,
> + VIR_DOMAIN_EVENT_STOPPED,
> + VIR_DOMAIN_EVENT_STOPPED_FAILED);
> if (!dom->persistent) {
> virDomainRemoveInactive(&driver->domains,
> dom);
> @@ -359,6 +381,8 @@ reread:
> }
>
> cleanup:
> + if (event)
> + umlDomainEventQueue(driver, event);
> umlDriverUnlock(driver);
> }
>
> @@ -392,6 +416,13 @@ umlStartup(int privileged)
> if (virDomainObjListInit(¨_driver->domains) < 0)
> goto error;
>
> + uml_driver->domainEventState = virDomainEventStateNew(umlDomainEventFlush,
> + uml_driver,
> + NULL,
> + true);
> + if (!uml_driver->domainEventState)
> + goto error;
> +
> userdir = virGetUserDirectory(uid);
> if (!userdir)
> goto error;
> @@ -469,9 +500,10 @@ umlStartup(int privileged)
> 0, NULL, NULL) < 0)
> goto error;
>
> + umlDriverUnlock(uml_driver);
> +
> umlAutostartConfigs(uml_driver);
>
> - umlDriverUnlock(uml_driver);
> VIR_FREE(userdir);
>
> return 0;
> @@ -487,6 +519,21 @@ error:
> return -1;
> }
>
> +static void umlNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
> +{
> + struct uml_driver *driver = opaque;
> +
> + if (newVM) {
> + virDomainEventPtr event =
> + virDomainEventNewFromObj(vm,
> + VIR_DOMAIN_EVENT_DEFINED,
> + VIR_DOMAIN_EVENT_DEFINED_ADDED);
> + if (event)
> + umlDomainEventQueue(driver, event);
> + }
> +}
> +
> +
> /**
> * umlReload:
> *
> @@ -503,10 +550,10 @@ umlReload(void) {
> ¨_driver->domains,
> uml_driver->configDir,
> uml_driver->autostartDir,
> - 0, NULL, NULL);
> + 0, umlNotifyLoadDomain, uml_driver);
> + umlDriverUnlock(uml_driver);
>
> umlAutostartConfigs(uml_driver);
> - umlDriverUnlock(uml_driver);
>
> return 0;
> }
> @@ -569,6 +616,8 @@ umlShutdown(void) {
>
> virDomainObjListDeinit(¨_driver->domains);
>
> + virDomainEventStateFree(uml_driver->domainEventState);
> +
> VIR_FREE(uml_driver->logDir);
> VIR_FREE(uml_driver->configDir);
> VIR_FREE(uml_driver->autostartDir);
> @@ -929,6 +978,7 @@ cleanup:
> /* XXX what if someone else tries to start it again
> before we get the inotification ? Sounds like
> trouble.... */
> + /* XXX this is bad for events too. must fix this better */
>
> return ret;
> }
> @@ -1025,7 +1075,12 @@ static virDrvOpenStatus umlOpen(virConnectPtr conn,
> }
>
> static int umlClose(virConnectPtr conn) {
> - /*struct uml_driver *driver = conn->privateData;*/
> + struct uml_driver *driver = conn->privateData;
> +
> + umlDriverLock(driver);
> + virDomainEventCallbackListRemoveConn(conn,
> + driver->domainEventState->callbacks);
> + umlDriverUnlock(driver);
>
> conn->privateData = NULL;
>
> @@ -1293,6 +1348,7 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
> virDomainDefPtr def;
> virDomainObjPtr vm = NULL;
> virDomainPtr dom = NULL;
> + virDomainEventPtr event = NULL;
>
> virCheckFlags(0, NULL);
>
> @@ -1318,6 +1374,9 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
> goto cleanup;
> }
> virDomainAuditStart(vm, "booted", true);
> + event = virDomainEventNewFromObj(vm,
> + VIR_DOMAIN_EVENT_STARTED,
> + VIR_DOMAIN_EVENT_STARTED_BOOTED);
>
> dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
> if (dom) dom->id = vm->def->id;
> @@ -1326,6 +1385,8 @@ cleanup:
> virDomainDefFree(def);
> if (vm)
> virDomainObjUnlock(vm);
> + if (event)
> + umlDomainEventQueue(driver, event);
> umlDriverUnlock(driver);
> return dom;
> }
> @@ -1366,6 +1427,7 @@ cleanup:
> static int umlDomainDestroy(virDomainPtr dom) {
> struct uml_driver *driver = dom->conn->privateData;
> virDomainObjPtr vm;
> + virDomainEventPtr event = NULL;
> int ret = -1;
>
> umlDriverLock(driver);
> @@ -1378,6 +1440,9 @@ static int umlDomainDestroy(virDomainPtr dom) {
>
> umlShutdownVMDaemon(dom->conn, driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
> virDomainAuditStop(vm, "destroyed");
> + event = virDomainEventNewFromObj(vm,
> + VIR_DOMAIN_EVENT_STOPPED,
> + VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
> if (!vm->persistent) {
> virDomainRemoveInactive(&driver->domains,
> vm);
> @@ -1388,6 +1453,8 @@ static int umlDomainDestroy(virDomainPtr dom) {
> cleanup:
> if (vm)
> virDomainObjUnlock(vm);
> + if (event)
> + umlDomainEventQueue(driver, event);
> umlDriverUnlock(driver);
> return ret;
> }
> @@ -1640,6 +1707,7 @@ static int umlNumDefinedDomains(virConnectPtr conn) {
> static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
> struct uml_driver *driver = dom->conn->privateData;
> virDomainObjPtr vm;
> + virDomainEventPtr event = NULL;
> int ret = -1;
>
> virCheckFlags(0, -1);
> @@ -1655,10 +1723,16 @@ static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
>
> ret = umlStartVMDaemon(dom->conn, driver, vm);
> virDomainAuditStart(vm, "booted", ret >= 0);
> + if (ret == 0)
> + event = virDomainEventNewFromObj(vm,
> + VIR_DOMAIN_EVENT_STARTED,
> + VIR_DOMAIN_EVENT_STARTED_BOOTED);
>
> cleanup:
> if (vm)
> virDomainObjUnlock(vm);
> + if (event)
> + umlDomainEventQueue(driver, event);
> umlDriverUnlock(driver);
> return ret;
> }
> @@ -2208,6 +2282,114 @@ cleanup:
> }
>
>
> +static int
> +umlDomainEventRegister(virConnectPtr conn,
> + virConnectDomainEventCallback callback,
> + void *opaque,
> + virFreeCallback freecb)
> +{
> + struct uml_driver *driver = conn->privateData;
> + int ret;
> +
> + umlDriverLock(driver);
> + ret = virDomainEventCallbackListAdd(conn,
> + driver->domainEventState->callbacks,
> + callback, opaque, freecb);
> + umlDriverUnlock(driver);
> +
> + return ret;
> +}
> +
> +static int
> +umlDomainEventDeregister(virConnectPtr conn,
> + virConnectDomainEventCallback callback)
> +{
> + struct uml_driver *driver = conn->privateData;
> + int ret;
> +
> + umlDriverLock(driver);
> + ret = virDomainEventStateDeregister(conn,
> + driver->domainEventState,
> + callback);
> + umlDriverUnlock(driver);
> +
> + return ret;
> +}
> +static int
> +umlDomainEventRegisterAny(virConnectPtr conn,
> + virDomainPtr dom,
> + int eventID,
> + virConnectDomainEventGenericCallback callback,
> + void *opaque,
> + virFreeCallback freecb)
> +{
> + struct uml_driver *driver = conn->privateData;
> + int ret;
> +
> + umlDriverLock(driver);
> + ret = virDomainEventCallbackListAddID(conn,
> + driver->domainEventState->callbacks,
> + dom, eventID,
> + callback, opaque, freecb);
> + umlDriverUnlock(driver);
> +
> + return ret;
> +}
> +
> +
> +static int
> +umlDomainEventDeregisterAny(virConnectPtr conn,
> + int callbackID)
> +{
> + struct uml_driver *driver = conn->privateData;
> + int ret;
> +
> + umlDriverLock(driver);
> + ret = virDomainEventStateDeregisterAny(conn,
> + driver->domainEventState,
> + callbackID);
> + umlDriverUnlock(driver);
> +
> + return ret;
> +}
> +
> +
> +static void umlDomainEventDispatchFunc(virConnectPtr conn,
> + virDomainEventPtr event,
> + virConnectDomainEventGenericCallback cb,
> + void *cbopaque,
> + void *opaque)
> +{
> + struct uml_driver *driver = opaque;
> +
> + /* Drop the lock whle dispatching, for sake of re-entrancy */
> + umlDriverUnlock(driver);
> + virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
> + umlDriverLock(driver);
> +}
> +
> +
> +static void umlDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
> +{
> + struct uml_driver *driver = opaque;
> +
> + umlDriverLock(driver);
> + virDomainEventStateFlush(driver->domainEventState,
> + umlDomainEventDispatchFunc,
> + driver);
> + umlDriverUnlock(driver);
> +}
> +
> +
> +/* driver must be locked before calling */
> +static void umlDomainEventQueue(struct uml_driver *driver,
> + virDomainEventPtr event)
> +{
> + virDomainEventStateQueue(driver->domainEventState, event);
> +}
> +
> +
> +
> static virDriver umlDriver = {
> .no = VIR_DRV_UML,
> .name = "UML",
> @@ -2250,11 +2432,15 @@ static virDriver umlDriver = {
> .nodeGetMemoryStats = nodeGetMemoryStats, /* 0.9.3 */
> .nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.5.0 */
> .nodeGetFreeMemory = nodeGetFreeMemory, /* 0.5.0 */
> + .domainEventRegister = umlDomainEventRegister, /* 0.9.4 */
> + .domainEventDeregister = umlDomainEventDeregister, /* 0.9.4 */
> .isEncrypted = umlIsEncrypted, /* 0.7.3 */
> .isSecure = umlIsSecure, /* 0.7.3 */
> .domainIsActive = umlDomainIsActive, /* 0.7.3 */
> .domainIsPersistent = umlDomainIsPersistent, /* 0.7.3 */
> .domainIsUpdated = umlDomainIsUpdated, /* 0.8.6 */
> + .domainEventRegisterAny = umlDomainEventRegisterAny, /* 0.9.4 */
> + .domainEventDeregisterAny = umlDomainEventDeregisterAny, /* 0.9.4 */
> .domainOpenConsole = umlDomainOpenConsole, /* 0.8.6 */
> };
>
> --
> 1.7.4.4
>
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list