提交 9b5655a8 编写于 作者: D Daniel P. Berrange

Add domain events support to LXC driver

* src/lxc_conf.h: Add queue for dispatch of domain events
* src/lxc_driver.c: Trigger domain events upon important lifecycle transitions
上级 899ae0d2
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "internal.h" #include "internal.h"
#include "domain_conf.h" #include "domain_conf.h"
#include "domain_event.h"
#include "capabilities.h" #include "capabilities.h"
#include "threads.h" #include "threads.h"
...@@ -47,6 +48,12 @@ struct __lxc_driver { ...@@ -47,6 +48,12 @@ struct __lxc_driver {
char *stateDir; char *stateDir;
char *logDir; char *logDir;
int have_netns; int have_netns;
/* An array of callbacks */
virDomainEventCallbackListPtr domainEventCallbacks;
virDomainEventQueuePtr domainEventQueue;
int domainEventTimer;
int domainEventDispatching;
}; };
int lxcLoadDriverConfig(lxc_driver_t *driver); int lxcLoadDriverConfig(lxc_driver_t *driver);
......
...@@ -67,6 +67,10 @@ static void lxcDriverUnlock(lxc_driver_t *driver) ...@@ -67,6 +67,10 @@ static void lxcDriverUnlock(lxc_driver_t *driver)
virMutexUnlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
static void lxcDomainEventFlush(int timer, void *opaque);
static void lxcDomainEventQueue(lxc_driver_t *driver,
virDomainEventPtr event);
static virDrvOpenStatus lxcOpen(virConnectPtr conn, static virDrvOpenStatus lxcOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED, virConnectAuthPtr auth ATTRIBUTE_UNUSED,
...@@ -114,6 +118,12 @@ static virDrvOpenStatus lxcOpen(virConnectPtr conn, ...@@ -114,6 +118,12 @@ static virDrvOpenStatus lxcOpen(virConnectPtr conn,
static int lxcClose(virConnectPtr conn) static int lxcClose(virConnectPtr conn)
{ {
lxc_driver_t *driver = conn->privateData;
lxcDriverLock(driver);
virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
lxcDriverUnlock(driver);
conn->privateData = NULL; conn->privateData = NULL;
return 0; return 0;
} }
...@@ -293,6 +303,8 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml) ...@@ -293,6 +303,8 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
virDomainDefPtr def = NULL; virDomainDefPtr def = NULL;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
int newVM = 1;
lxcDriverLock(driver); lxcDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml, if (!(def = virDomainDefParseString(conn, driver->caps, xml,
...@@ -318,6 +330,12 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml) ...@@ -318,6 +330,12 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
goto cleanup; goto cleanup;
} }
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_DEFINED,
newVM ?
VIR_DOMAIN_EVENT_DEFINED_ADDED :
VIR_DOMAIN_EVENT_DEFINED_UPDATED);
dom = virGetDomain(conn, vm->def->name, vm->def->uuid); dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) if (dom)
dom->id = vm->def->id; dom->id = vm->def->id;
...@@ -326,6 +344,8 @@ cleanup: ...@@ -326,6 +344,8 @@ cleanup:
virDomainDefFree(def); virDomainDefFree(def);
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return dom; return dom;
} }
...@@ -334,6 +354,7 @@ static int lxcDomainUndefine(virDomainPtr dom) ...@@ -334,6 +354,7 @@ static int lxcDomainUndefine(virDomainPtr dom)
{ {
lxc_driver_t *driver = dom->conn->privateData; lxc_driver_t *driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1; int ret = -1;
lxcDriverLock(driver); lxcDriverLock(driver);
...@@ -362,6 +383,10 @@ static int lxcDomainUndefine(virDomainPtr dom) ...@@ -362,6 +383,10 @@ static int lxcDomainUndefine(virDomainPtr dom)
vm) < 0) vm) < 0)
goto cleanup; goto cleanup;
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_UNDEFINED,
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
virDomainRemoveInactive(&driver->domains, vm); virDomainRemoveInactive(&driver->domains, vm);
vm = NULL; vm = NULL;
ret = 0; ret = 0;
...@@ -369,6 +394,8 @@ static int lxcDomainUndefine(virDomainPtr dom) ...@@ -369,6 +394,8 @@ static int lxcDomainUndefine(virDomainPtr dom)
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return ret; return ret;
} }
...@@ -532,6 +559,13 @@ static int lxcVMCleanup(virConnectPtr conn, ...@@ -532,6 +559,13 @@ static int lxcVMCleanup(virConnectPtr conn,
virCgroupFree(&cgroup); virCgroupFree(&cgroup);
} }
if (vm->newDef) {
virDomainDefFree(vm->def);
vm->def = vm->newDef;
vm->def->id = -1;
vm->newDef = NULL;
}
return rc; return rc;
} }
...@@ -709,6 +743,7 @@ static void lxcMonitorEvent(int watch, ...@@ -709,6 +743,7 @@ static void lxcMonitorEvent(int watch,
{ {
lxc_driver_t *driver = data; lxc_driver_t *driver = data;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainEventPtr event = NULL;
unsigned int i; unsigned int i;
lxcDriverLock(driver); lxcDriverLock(driver);
...@@ -731,12 +766,19 @@ static void lxcMonitorEvent(int watch, ...@@ -731,12 +766,19 @@ static void lxcMonitorEvent(int watch,
goto cleanup; goto cleanup;
} }
if (lxcVmTerminate(NULL, driver, vm, SIGINT) < 0) if (lxcVmTerminate(NULL, driver, vm, SIGINT) < 0) {
virEventRemoveHandle(watch); virEventRemoveHandle(watch);
} else {
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
}
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
} }
...@@ -977,6 +1019,7 @@ static int lxcDomainStart(virDomainPtr dom) ...@@ -977,6 +1019,7 @@ static int lxcDomainStart(virDomainPtr dom)
{ {
lxc_driver_t *driver = dom->conn->privateData; lxc_driver_t *driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1; int ret = -1;
lxcDriverLock(driver); lxcDriverLock(driver);
...@@ -995,9 +1038,16 @@ static int lxcDomainStart(virDomainPtr dom) ...@@ -995,9 +1038,16 @@ static int lxcDomainStart(virDomainPtr dom)
ret = lxcVmStart(dom->conn, driver, vm); ret = lxcVmStart(dom->conn, driver, vm);
if (ret == 0)
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return ret; return ret;
} }
...@@ -1020,6 +1070,7 @@ lxcDomainCreateAndStart(virConnectPtr conn, ...@@ -1020,6 +1070,7 @@ lxcDomainCreateAndStart(virConnectPtr conn,
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainDefPtr def; virDomainDefPtr def;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
lxcDriverLock(driver); lxcDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml, if (!(def = virDomainDefParseString(conn, driver->caps, xml,
...@@ -1043,6 +1094,10 @@ lxcDomainCreateAndStart(virConnectPtr conn, ...@@ -1043,6 +1094,10 @@ lxcDomainCreateAndStart(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
dom = virGetDomain(conn, vm->def->name, vm->def->uuid); dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) if (dom)
dom->id = vm->def->id; dom->id = vm->def->id;
...@@ -1051,6 +1106,8 @@ cleanup: ...@@ -1051,6 +1106,8 @@ cleanup:
virDomainDefFree(def); virDomainDefFree(def);
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return dom; return dom;
} }
...@@ -1067,6 +1124,7 @@ static int lxcDomainShutdown(virDomainPtr dom) ...@@ -1067,6 +1124,7 @@ static int lxcDomainShutdown(virDomainPtr dom)
{ {
lxc_driver_t *driver = dom->conn->privateData; lxc_driver_t *driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1; int ret = -1;
lxcDriverLock(driver); lxcDriverLock(driver);
...@@ -1078,6 +1136,9 @@ static int lxcDomainShutdown(virDomainPtr dom) ...@@ -1078,6 +1136,9 @@ static int lxcDomainShutdown(virDomainPtr dom)
} }
ret = lxcVmTerminate(dom->conn, driver, vm, 0); ret = lxcVmTerminate(dom->conn, driver, vm, 0);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
if (!vm->persistent) { if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm); virDomainRemoveInactive(&driver->domains, vm);
vm = NULL; vm = NULL;
...@@ -1086,10 +1147,103 @@ static int lxcDomainShutdown(virDomainPtr dom) ...@@ -1086,10 +1147,103 @@ static int lxcDomainShutdown(virDomainPtr dom)
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver);
return ret;
}
static int
lxcDomainEventRegister (virConnectPtr conn,
virConnectDomainEventCallback callback,
void *opaque,
virFreeCallback freecb)
{
lxc_driver_t *driver = conn->privateData;
int ret;
lxcDriverLock(driver);
ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
callback, opaque, freecb);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return ret; return ret;
} }
static int
lxcDomainEventDeregister (virConnectPtr conn,
virConnectDomainEventCallback callback)
{
lxc_driver_t *driver = conn->privateData;
int ret;
lxcDriverLock(driver);
if (driver->domainEventDispatching)
ret = virDomainEventCallbackListMarkDelete(conn, driver->domainEventCallbacks,
callback);
else
ret = virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
callback);
lxcDriverUnlock(driver);
return ret;
}
static void lxcDomainEventDispatchFunc(virConnectPtr conn,
virDomainEventPtr event,
virConnectDomainEventCallback cb,
void *cbopaque,
void *opaque)
{
lxc_driver_t *driver = opaque;
/* Drop the lock whle dispatching, for sake of re-entrancy */
lxcDriverUnlock(driver);
virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
lxcDriverLock(driver);
}
static void lxcDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
{
lxc_driver_t *driver = opaque;
virDomainEventQueue tempQueue;
lxcDriverLock(driver);
driver->domainEventDispatching = 1;
/* Copy the queue, so we're reentrant safe */
tempQueue.count = driver->domainEventQueue->count;
tempQueue.events = driver->domainEventQueue->events;
driver->domainEventQueue->count = 0;
driver->domainEventQueue->events = NULL;
virEventUpdateTimeout(driver->domainEventTimer, -1);
virDomainEventQueueDispatch(&tempQueue,
driver->domainEventCallbacks,
lxcDomainEventDispatchFunc,
driver);
/* Purge any deleted callbacks */
virDomainEventCallbackListPurgeMarked(driver->domainEventCallbacks);
driver->domainEventDispatching = 0;
lxcDriverUnlock(driver);
}
/* driver must be locked before calling */
static void lxcDomainEventQueue(lxc_driver_t *driver,
virDomainEventPtr event)
{
if (virDomainEventQueuePush(driver->domainEventQueue,
event) < 0)
virDomainEventFree(event);
if (lxc_driver->domainEventQueue->count == 1)
virEventUpdateTimeout(driver->domainEventTimer, 0);
}
/** /**
* lxcDomainDestroy: * lxcDomainDestroy:
...@@ -1103,6 +1257,7 @@ static int lxcDomainDestroy(virDomainPtr dom) ...@@ -1103,6 +1257,7 @@ static int lxcDomainDestroy(virDomainPtr dom)
{ {
lxc_driver_t *driver = dom->conn->privateData; lxc_driver_t *driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1; int ret = -1;
lxcDriverLock(driver); lxcDriverLock(driver);
...@@ -1114,6 +1269,9 @@ static int lxcDomainDestroy(virDomainPtr dom) ...@@ -1114,6 +1269,9 @@ static int lxcDomainDestroy(virDomainPtr dom)
} }
ret = lxcVmTerminate(dom->conn, driver, vm, SIGKILL); ret = lxcVmTerminate(dom->conn, driver, vm, SIGKILL);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
if (!vm->persistent) { if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm); virDomainRemoveInactive(&driver->domains, vm);
vm = NULL; vm = NULL;
...@@ -1122,6 +1280,8 @@ static int lxcDomainDestroy(virDomainPtr dom) ...@@ -1122,6 +1280,8 @@ static int lxcDomainDestroy(virDomainPtr dom)
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
lxcDomainEventQueue(driver, event);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return ret; return ret;
} }
...@@ -1172,6 +1332,15 @@ static int lxcStartup(int privileged) ...@@ -1172,6 +1332,15 @@ static int lxcStartup(int privileged)
if(lxcContainerAvailable(0) < 0) if(lxcContainerAvailable(0) < 0)
goto cleanup; goto cleanup;
if(VIR_ALLOC(lxc_driver->domainEventCallbacks) < 0)
goto cleanup;
if (!(lxc_driver->domainEventQueue = virDomainEventQueueNew()))
goto cleanup;
if ((lxc_driver->domainEventTimer =
virEventAddTimeout(-1, lxcDomainEventFlush, lxc_driver, NULL)) < 0)
goto cleanup;
lxc_driver->have_netns = lxcCheckNetNsSupport(); lxc_driver->have_netns = lxcCheckNetNsSupport();
/* Call function to load lxc driver configuration information */ /* Call function to load lxc driver configuration information */
...@@ -1252,6 +1421,12 @@ static int lxcShutdown(void) ...@@ -1252,6 +1421,12 @@ static int lxcShutdown(void)
lxcDriverLock(lxc_driver); lxcDriverLock(lxc_driver);
virDomainObjListFree(&lxc_driver->domains); virDomainObjListFree(&lxc_driver->domains);
virDomainEventCallbackListFree(lxc_driver->domainEventCallbacks);
virDomainEventQueueFree(lxc_driver->domainEventQueue);
if (lxc_driver->domainEventTimer != -1)
virEventRemoveTimeout(lxc_driver->domainEventTimer);
virCapabilitiesFree(lxc_driver->caps); virCapabilitiesFree(lxc_driver->caps);
VIR_FREE(lxc_driver->configDir); VIR_FREE(lxc_driver->configDir);
VIR_FREE(lxc_driver->autostartDir); VIR_FREE(lxc_driver->autostartDir);
...@@ -1490,8 +1665,8 @@ static virDriver lxcDriver = { ...@@ -1490,8 +1665,8 @@ static virDriver lxcDriver = {
NULL, /* domainMemoryPeek */ NULL, /* domainMemoryPeek */
nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
nodeGetFreeMemory, /* getFreeMemory */ nodeGetFreeMemory, /* getFreeMemory */
NULL, /* domainEventRegister */ lxcDomainEventRegister, /* domainEventRegister */
NULL, /* domainEventDeregister */ lxcDomainEventDeregister, /* domainEventDeregister */
NULL, /* domainMigratePrepare2 */ NULL, /* domainMigratePrepare2 */
NULL, /* domainMigrateFinish2 */ NULL, /* domainMigrateFinish2 */
NULL, /* nodeDeviceDettach */ NULL, /* nodeDeviceDettach */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册