mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
Add domain events support to UML driver
* src/uml_conf.h: Add queue for dispatch of domain events * src/uml_driver.c: Trigger domain events upon important lifecycle transitions
This commit is contained in:
parent
71d3026077
commit
cf81318cb7
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 umlStartVMDaemon(virConnectPtr conn,
|
||||
struct uml_driver *driver,
|
||||
@ -153,6 +156,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);
|
||||
@ -172,7 +182,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);
|
||||
@ -253,6 +265,7 @@ umlInotifyEvent(int watch,
|
||||
char *tmp, *name;
|
||||
struct uml_driver *driver = data;
|
||||
virDomainObjPtr dom;
|
||||
virDomainEventPtr event = NULL;
|
||||
|
||||
umlDriverLock(driver);
|
||||
if (watch != driver->inotifyWatch)
|
||||
@ -298,6 +311,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);
|
||||
@ -324,6 +340,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);
|
||||
@ -334,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);
|
||||
@ -346,6 +368,8 @@ reread:
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (event)
|
||||
umlDomainEventQueue(driver, event);
|
||||
umlDriverUnlock(driver);
|
||||
}
|
||||
|
||||
@ -379,6 +403,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;
|
||||
@ -457,9 +488,10 @@ umlStartup(int privileged)
|
||||
NULL, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
umlDriverUnlock(uml_driver);
|
||||
|
||||
umlAutostartConfigs(uml_driver);
|
||||
|
||||
umlDriverUnlock(uml_driver);
|
||||
VIR_FREE(userdir);
|
||||
|
||||
return 0;
|
||||
@ -475,6 +507,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:
|
||||
*
|
||||
@ -492,10 +539,10 @@ umlReload(void) {
|
||||
uml_driver->configDir,
|
||||
uml_driver->autostartDir,
|
||||
0, 1 << VIR_DOMAIN_VIRT_UML,
|
||||
NULL, NULL);
|
||||
umlNotifyLoadDomain, uml_driver);
|
||||
umlDriverUnlock(uml_driver);
|
||||
|
||||
umlAutostartConfigs(uml_driver);
|
||||
umlDriverUnlock(uml_driver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -558,6 +605,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);
|
||||
@ -918,6 +967,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;
|
||||
}
|
||||
@ -1017,7 +1067,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;
|
||||
|
||||
@ -1285,6 +1340,7 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
|
||||
virDomainDefPtr def;
|
||||
virDomainObjPtr vm = NULL;
|
||||
virDomainPtr dom = NULL;
|
||||
virDomainEventPtr event = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
|
||||
@ -1311,6 +1367,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;
|
||||
@ -1319,6 +1378,8 @@ cleanup:
|
||||
virDomainDefFree(def);
|
||||
if (vm)
|
||||
virDomainObjUnlock(vm);
|
||||
if (event)
|
||||
umlDomainEventQueue(driver, event);
|
||||
umlDriverUnlock(driver);
|
||||
return dom;
|
||||
}
|
||||
@ -1359,6 +1420,7 @@ cleanup:
|
||||
static int umlDomainDestroy(virDomainPtr dom) {
|
||||
struct uml_driver *driver = dom->conn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
virDomainEventPtr event = NULL;
|
||||
int ret = -1;
|
||||
|
||||
umlDriverLock(driver);
|
||||
@ -1371,6 +1433,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);
|
||||
@ -1381,6 +1446,8 @@ static int umlDomainDestroy(virDomainPtr dom) {
|
||||
cleanup:
|
||||
if (vm)
|
||||
virDomainObjUnlock(vm);
|
||||
if (event)
|
||||
umlDomainEventQueue(driver, event);
|
||||
umlDriverUnlock(driver);
|
||||
return ret;
|
||||
}
|
||||
@ -1638,6 +1705,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);
|
||||
@ -1653,10 +1721,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;
|
||||
}
|
||||
@ -2207,6 +2281,115 @@ 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",
|
||||
@ -2249,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 */
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user