This patch makes the QEMU driver threadsafe with the exception of the
domain events code.
qemu_conf.h | 2
qemu_driver.c | 458 ++++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 337 insertions(+), 123 deletions(-)
Daniel
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -51,6 +51,8 @@ enum qemud_cmd_flags {
/* Main driver state */
struct qemud_driver {
+ PTHREAD_MUTEX_T(lock);
+
unsigned int qemuVersion;
int nextvmid;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -76,6 +76,15 @@ static int qemudShutdown(void);
#define qemudLog(level, msg...) fprintf(stderr, msg)
+static void qemuDriverLock(struct qemud_driver *driver)
+{
+ pthread_mutex_lock(&driver->lock);
+}
+static void qemuDriverUnlock(struct qemud_driver *driver)
+{
+ pthread_mutex_unlock(&driver->lock);
+}
+
static int qemudSetCloseExec(int fd) {
int flags;
if ((flags = fcntl(fd, F_GETFD)) < 0)
@@ -141,6 +150,7 @@ qemudAutostartConfigs(struct qemud_drive
for (i = 0 ; i < driver->domains.count ; i++) {
virDomainObjPtr vm = driver->domains.objs[i];
+ virDomainObjLock(vm);
if (vm->autostart &&
!virDomainIsActive(vm)) {
int ret = qemudStartVMDaemon(NULL, driver, vm, NULL);
@@ -154,6 +164,7 @@ qemudAutostartConfigs(struct qemud_drive
VIR_DOMAIN_EVENT_STARTED_BOOTED);
}
}
+ virDomainObjUnlock(vm);
}
}
@@ -172,12 +183,15 @@ qemudStartup(void) {
if (VIR_ALLOC(qemu_driver) < 0)
return -1;
+ pthread_mutex_init(&qemu_driver->lock, NULL);
+ qemuDriverLock(qemu_driver);
+
/* Don't have a dom0 so start from 1 */
qemu_driver->nextvmid = 1;
/* Init callback list */
if(VIR_ALLOC(qemu_driver->domainEventCallbacks) < 0)
- return -1;
+ goto out_of_memory;
if (!uid) {
if (asprintf(&qemu_driver->logDir,
@@ -190,7 +204,7 @@ qemudStartup(void) {
if (!(pw = getpwuid(uid))) {
qemudLog(QEMUD_ERR, _("Failed to find user record for uid '%d':
%s\n"),
uid, strerror(errno));
- goto out_nouid;
+ goto error;
}
if (asprintf(&qemu_driver->logDir,
@@ -229,20 +243,22 @@ qemudStartup(void) {
&qemu_driver->domains,
qemu_driver->configDir,
qemu_driver->autostartDir,
- NULL, NULL) < 0) {
- qemudShutdown();
- return -1;
- }
+ NULL, NULL) < 0)
+ goto error;
qemudAutostartConfigs(qemu_driver);
- return 0;
-
- out_of_memory:
+ qemuDriverUnlock(qemu_driver);
+
+ return 0;
+
+out_of_memory:
qemudLog (QEMUD_ERR,
"%s", _("qemudStartup: out of memory\n"));
- out_nouid:
+error:
+ if (qemu_driver)
+ qemuDriverUnlock(qemu_driver);
VIR_FREE(base);
- VIR_FREE(qemu_driver);
+ qemudShutdown();
return -1;
}
@@ -267,6 +283,7 @@ qemudReload(void) {
if (!qemu_driver)
return 0;
+ qemuDriverLock(qemu_driver);
virDomainLoadAllConfigs(NULL,
qemu_driver->caps,
&qemu_driver->domains,
@@ -275,6 +292,7 @@ qemudReload(void) {
qemudNotifyLoadDomain, qemu_driver);
qemudAutostartConfigs(qemu_driver);
+ qemuDriverUnlock(qemu_driver);
return 0;
}
@@ -290,16 +308,18 @@ static int
static int
qemudActive(void) {
unsigned int i;
+ int active = 0;
if (!qemu_driver)
return 0;
+ qemuDriverLock(qemu_driver);
for (i = 0 ; i < qemu_driver->domains.count ; i++)
if (virDomainIsActive(qemu_driver->domains.objs[i]))
- return 1;
-
- /* Otherwise we're happy to deal with a shutdown */
- return 0;
+ active = 1;
+
+ qemuDriverUnlock(qemu_driver);
+ return active;
}
/**
@@ -314,16 +334,16 @@ qemudShutdown(void) {
if (!qemu_driver)
return -1;
+ qemuDriverLock(qemu_driver);
virCapabilitiesFree(qemu_driver->caps);
/* shutdown active VMs */
for (i = 0 ; i < qemu_driver->domains.count ; i++) {
virDomainObjPtr dom = qemu_driver->domains.objs[i];
+ virDomainObjLock(dom);
if (virDomainIsActive(dom))
qemudShutdownVMDaemon(NULL, qemu_driver, dom);
- if (!dom->persistent)
- virDomainRemoveInactive(&qemu_driver->domains,
- dom);
+ virDomainObjUnlock(dom);
}
virDomainObjListFree(&qemu_driver->domains);
@@ -340,6 +360,7 @@ qemudShutdown(void) {
if (qemu_driver->brctl)
brShutdown(qemu_driver->brctl);
+ qemuDriverUnlock(qemu_driver);
VIR_FREE(qemu_driver);
return 0;
@@ -1047,38 +1068,15 @@ static void qemudShutdownVMDaemon(virCon
}
}
-static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, int fd) {
- if (qemudVMData(driver, vm, fd) < 0) {
- qemudShutdownVMDaemon(NULL, driver, vm);
- qemudDomainEventDispatch(driver, vm,
- VIR_DOMAIN_EVENT_STOPPED,
- VIR_DOMAIN_EVENT_STOPPED_FAILED);
- if (!vm->persistent)
- virDomainRemoveInactive(&driver->domains,
- vm);
- }
- return 0;
-}
-
-static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr vm,
- int fd ATTRIBUTE_UNUSED) {
- qemudShutdownVMDaemon(NULL, driver, vm);
- qemudDomainEventDispatch(driver, vm,
- VIR_DOMAIN_EVENT_STOPPED,
- VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
- if (!vm->persistent)
- virDomainRemoveInactive(&driver->domains,
- vm);
- return 0;
-}
-
static void
qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
struct qemud_driver *driver = opaque;
virDomainObjPtr vm = NULL;
unsigned int i;
-
+ int quit = 0, failed = 0;
+
+ qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) {
if (virDomainIsActive(driver->domains.objs[i]) &&
(driver->domains.objs[i]->stdout_watch == watch ||
@@ -1089,18 +1087,38 @@ qemudDispatchVMEvent(int watch, int fd,
}
if (!vm)
- return;
+ goto cleanup;
if (vm->stdout_fd != fd &&
vm->stderr_fd != fd) {
- qemudDispatchVMFailure(driver, vm, fd);
- return;
- }
-
- if (events == VIR_EVENT_HANDLE_READABLE)
- qemudDispatchVMLog(driver, vm, fd);
- else
- qemudDispatchVMFailure(driver, vm, fd);
+ failed = 1;
+ } else {
+ if (events & VIR_EVENT_HANDLE_READABLE) {
+ if (qemudVMData(driver, vm, fd) < 0)
+ failed = 1;
+ } else {
+ quit = 1;
+ }
+ }
+
+ if (failed || quit) {
+ qemudShutdownVMDaemon(NULL, driver, vm);
+ qemudDomainEventDispatch(driver, vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ quit ?
+ VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN :
+ VIR_DOMAIN_EVENT_STOPPED_FAILED);
+ if (!vm->persistent) {
+ virDomainRemoveInactive(&driver->domains,
+ vm);
+ vm = NULL;
+ }
+ }
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
}
static int
@@ -1311,9 +1329,11 @@ static char *qemudGetCapabilities(virCon
struct qemud_driver *driver = conn->privateData;
char *xml;
+ qemuDriverLock(driver);
if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for capabilities
support"));
+ qemuDriverUnlock(driver);
return xml;
}
@@ -1423,7 +1443,9 @@ static virDomainPtr qemudDomainLookupByI
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ qemuDriverLock(driver);
vm = virDomainFindByID(&driver->domains, id);
+ qemuDriverUnlock(driver);
if (!vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
@@ -1434,15 +1456,21 @@ static virDomainPtr qemudDomainLookupByI
if (dom) dom->id = vm->def->id;
cleanup:
- return dom;
-}
+ if (vm)
+ virDomainObjUnlock(vm);
+ return dom;
+}
+
static virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid) {
struct qemud_driver *driver = conn->privateData;
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
@@ -1452,15 +1480,21 @@ static virDomainPtr qemudDomainLookupByU
if (dom) dom->id = vm->def->id;
cleanup:
- return dom;
-}
+ if (vm)
+ virDomainObjUnlock(vm);
+ return dom;
+}
+
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
const char *name) {
struct qemud_driver *driver = conn->privateData;
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ qemuDriverLock(driver);
vm = virDomainFindByName(&driver->domains, name);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
@@ -1470,6 +1504,8 @@ static virDomainPtr qemudDomainLookupByN
if (dom) dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
@@ -1477,6 +1513,7 @@ static int qemudGetVersion(virConnectPtr
struct qemud_driver *driver = conn->privateData;
int ret = -1;
+ qemuDriverLock(driver);
if (qemudExtractVersion(conn, driver) < 0)
goto cleanup;
@@ -1484,6 +1521,7 @@ static int qemudGetVersion(virConnectPtr
ret = 0;
cleanup:
+ qemuDriverUnlock(driver);
return ret;
}
@@ -1513,29 +1551,42 @@ static int qemudListDomains(virConnectPt
struct qemud_driver *driver = conn->privateData;
int got = 0, i;
- for (i = 0 ; i < driver->domains.count && got < nids ; i++)
+ qemuDriverLock(driver);
+ for (i = 0 ; i < driver->domains.count && got < nids ; i++) {
+ virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ qemuDriverUnlock(driver);
return got;
}
+
static int qemudNumDomains(virConnectPtr conn) {
struct qemud_driver *driver = conn->privateData;
int n = 0, i;
- for (i = 0 ; i < driver->domains.count ; i++)
+ qemuDriverLock(driver);
+ for (i = 0 ; i < driver->domains.count ; i++) {
+ virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
n++;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ qemuDriverUnlock(driver);
return n;
}
+
static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
unsigned int flags ATTRIBUTE_UNUSED) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def;
- virDomainObjPtr vm;
- virDomainPtr dom = NULL;
-
+ virDomainObjPtr vm = NULL;
+ virDomainPtr dom = NULL;
+
+ qemuDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
goto cleanup;
@@ -1567,6 +1618,7 @@ static virDomainPtr qemudDomainCreate(vi
if (qemudStartVMDaemon(conn, driver, vm, NULL) < 0) {
virDomainRemoveInactive(&driver->domains,
vm);
+ vm = NULL;
goto cleanup;
}
qemudDomainEventDispatch(driver, vm,
@@ -1578,7 +1630,9 @@ static virDomainPtr qemudDomainCreate(vi
cleanup:
virDomainDefFree(def);
-
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return dom;
}
@@ -1589,7 +1643,10 @@ static int qemudDomainSuspend(virDomainP
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverLock(driver);
+ vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, _("no
domain with matching id %d"), dom->id);
goto cleanup;
@@ -1615,6 +1672,8 @@ static int qemudDomainSuspend(virDomainP
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -1625,7 +1684,10 @@ static int qemudDomainResume(virDomainPt
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverLock(driver);
+ vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1652,6 +1714,8 @@ static int qemudDomainResume(virDomainPt
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -1662,7 +1726,10 @@ static int qemudDomainShutdown(virDomain
char* info;
int ret = -1;
- vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverLock(driver);
+ vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1678,8 +1745,9 @@ static int qemudDomainShutdown(virDomain
ret = 0;
cleanup:
- return ret;
-
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
}
@@ -1688,6 +1756,7 @@ static int qemudDomainDestroy(virDomainP
virDomainObjPtr vm;
int ret = -1;
+ qemuDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -1699,12 +1768,17 @@ static int qemudDomainDestroy(virDomainP
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
- if (!vm->persistent)
+ if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains,
vm);
- ret = 0;
-
-cleanup:
+ vm = NULL;
+ }
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -1714,7 +1788,9 @@ static char *qemudDomainGetOSType(virDom
virDomainObjPtr vm;
char *type = NULL;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -1726,6 +1802,8 @@ static char *qemudDomainGetOSType(virDom
"%s", _("failed to allocate space for
ostype"));
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return type;
}
@@ -1735,7 +1813,10 @@ static unsigned long qemudDomainGetMaxMe
virDomainObjPtr vm;
unsigned long ret = 0;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -1748,6 +1829,8 @@ static unsigned long qemudDomainGetMaxMe
ret = vm->def->maxmem;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -1756,7 +1839,10 @@ static int qemudDomainSetMaxMemory(virDo
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -1776,6 +1862,8 @@ static int qemudDomainSetMaxMemory(virDo
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -1784,7 +1872,9 @@ static int qemudDomainSetMemory(virDomai
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -1810,6 +1900,8 @@ static int qemudDomainSetMemory(virDomai
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -1819,7 +1911,9 @@ static int qemudDomainGetInfo(virDomainP
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -1843,6 +1937,8 @@ static int qemudDomainGetInfo(virDomainP
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -1956,6 +2052,7 @@ static int qemudDomainSave(virDomainPtr
memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
header.version = QEMUD_SAVE_VERSION;
+ qemuDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
@@ -2054,9 +2151,11 @@ static int qemudDomainSave(virDomainPtr
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SAVED);
- if (!vm->persistent)
+ if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains,
vm);
+ vm = NULL;
+ }
ret = 0;
cleanup:
@@ -2068,7 +2167,9 @@ cleanup:
VIR_FREE(info);
if (ret != 0)
unlink(path);
-
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -2079,7 +2180,10 @@ static int qemudDomainSetVcpus(virDomain
int max;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -2112,6 +2216,8 @@ static int qemudDomainSetVcpus(virDomain
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -2129,7 +2235,10 @@ qemudDomainPinVcpu(virDomainPtr dom,
virNodeInfo nodeinfo;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s",_("cannot pin vcpus on an inactive
domain"));
@@ -2170,6 +2279,8 @@ qemudDomainPinVcpu(virDomainPtr dom,
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -2185,7 +2296,10 @@ qemudDomainGetVcpus(virDomainPtr dom,
int i, v, maxcpu;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s",_("cannot pin vcpus on an inactive
domain"));
@@ -2241,6 +2355,8 @@ qemudDomainGetVcpus(virDomainPtr dom,
ret = maxinfo;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
#endif /* HAVE_SCHED_GETAFFINITY */
@@ -2252,7 +2368,10 @@ static int qemudDomainGetMaxVcpus(virDom
const char *type;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -2272,6 +2391,8 @@ static int qemudDomainGetMaxVcpus(virDom
ret = qemudGetMaxVCPUs(dom->conn, type);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -2280,12 +2401,13 @@ static int qemudDomainRestore(virConnect
const char *path) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def = NULL;
- virDomainObjPtr vm;
+ virDomainObjPtr vm = NULL;
int fd = -1;
int ret = -1;
char *xml = NULL;
struct qemud_save_header header;
+ qemuDriverLock(driver);
/* Verify the header and read the XML */
if ((fd = open(path, O_RDONLY)) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
@@ -2359,9 +2481,11 @@ static int qemudDomainRestore(virConnect
if (ret < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to start VM"));
- if (!vm->persistent)
+ if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains,
vm);
+ vm = NULL;
+ }
goto cleanup;
}
@@ -2387,7 +2511,9 @@ cleanup:
VIR_FREE(xml);
if (fd != -1)
close(fd);
-
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -2398,7 +2524,10 @@ static char *qemudDomainDumpXML(virDomai
virDomainObjPtr vm;
char *ret = NULL;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -2411,6 +2540,8 @@ static char *qemudDomainDumpXML(virDomai
flags);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -2420,21 +2551,27 @@ static int qemudListDefinedDomains(virCo
struct qemud_driver *driver = conn->privateData;
int got = 0, i;
+ qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) {
+ virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for VM
name string"));
- goto cleanup;
- }
- }
- }
-
+ virDomainObjUnlock(driver->domains.objs[i]);
+ goto cleanup;
+ }
+ }
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+
+ qemuDriverUnlock(driver);
return got;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
+ qemuDriverUnlock(driver);
return -1;
}
@@ -2442,9 +2579,11 @@ static int qemudNumDefinedDomains(virCon
struct qemud_driver *driver = conn->privateData;
int n = 0, i;
+ qemuDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++)
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
+ qemuDriverUnlock(driver);
return n;
}
@@ -2455,7 +2594,10 @@ static int qemudDomainStart(virDomainPtr
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -2469,6 +2611,8 @@ static int qemudDomainStart(virDomainPtr
VIR_DOMAIN_EVENT_STARTED_BOOTED);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -2476,16 +2620,19 @@ static virDomainPtr qemudDomainDefine(vi
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def;
- virDomainObjPtr vm;
+ virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
int newVM = 1;
+ qemuDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
goto cleanup;
vm = virDomainFindByName(&driver->domains, def->name);
- if (vm)
+ if (vm) {
+ virDomainObjUnlock(vm);
newVM = 0;
+ }
if (!(vm = virDomainAssignDef(conn,
&driver->domains,
@@ -2500,6 +2647,7 @@ static virDomainPtr qemudDomainDefine(vi
vm->newDef ? vm->newDef : vm->def) < 0) {
virDomainRemoveInactive(&driver->domains,
vm);
+ vm = NULL;
goto cleanup;
}
@@ -2513,6 +2661,9 @@ static virDomainPtr qemudDomainDefine(vi
if (dom) dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return dom;
}
@@ -2521,7 +2672,9 @@ static int qemudDomainUndefine(virDomain
virDomainObjPtr vm;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -2549,9 +2702,13 @@ static int qemudDomainUndefine(virDomain
virDomainRemoveInactive(&driver->domains,
vm);
- ret = 0;
-
-cleanup:
+ vm = NULL;
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -2913,6 +3070,7 @@ static int qemudDomainAttachDevice(virDo
virDomainDeviceDefPtr dev = NULL;
int ret = -1;
+ qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2964,6 +3122,9 @@ static int qemudDomainAttachDevice(virDo
cleanup:
virDomainDeviceDefFree(dev);
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -3045,6 +3206,7 @@ static int qemudDomainDetachDevice(virDo
virDomainDeviceDefPtr dev = NULL;
int ret = -1;
+ qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -3074,16 +3236,22 @@ static int qemudDomainDetachDevice(virDo
cleanup:
virDomainDeviceDefFree(dev);
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
static int qemudDomainGetAutostart(virDomainPtr dom,
- int *autostart) {
- struct qemud_driver *driver = dom->conn->privateData;
- virDomainObjPtr vm;
- int ret = -1;
-
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ int *autostart) {
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -3094,6 +3262,8 @@ static int qemudDomainGetAutostart(virDo
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -3104,7 +3274,10 @@ static int qemudDomainSetAutostart(virDo
char *configFile = NULL, *autostartLink = NULL;
int ret = -1;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -3157,7 +3330,8 @@ cleanup:
cleanup:
VIR_FREE(configFile);
VIR_FREE(autostartLink);
-
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -3179,7 +3353,9 @@ qemudDomainBlockStats (virDomainPtr dom,
virDomainObjPtr vm;
virDomainDiskDefPtr disk = NULL;
- vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverLock(driver);
+ vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverUnlock(driver);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -3292,6 +3468,8 @@ qemudDomainBlockStats (virDomainPtr dom,
cleanup:
VIR_FREE(qemu_dev_name);
VIR_FREE(info);
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -3306,7 +3484,10 @@ qemudDomainInterfaceStats (virDomainPtr
int i;
int ret = -1;
- vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverLock(driver);
+ vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -3341,6 +3522,8 @@ qemudDomainInterfaceStats (virDomainPtr
_("invalid path, '%s' is not a known
interface"), path);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
#else
@@ -3365,7 +3548,10 @@ qemudDomainBlockPeek (virDomainPtr dom,
virDomainObjPtr vm;
int fd = -1, ret = -1, i;
- vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -3417,6 +3603,8 @@ cleanup:
cleanup:
if (fd >= 0)
close (fd);
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -3432,7 +3620,9 @@ qemudDomainMemoryPeek (virDomainPtr dom,
char tmp[] = TEMPDIR "/qemu.mem.XXXXXX";
int fd = -1, ret = -1;
- vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverLock(driver);
+ vm = virDomainFindByID(&driver->domains, dom->id);
+ qemuDriverUnlock(driver);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -3482,6 +3672,8 @@ cleanup:
VIR_FREE(info);
if (fd >= 0) close (fd);
unlink (tmp);
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -3495,8 +3687,10 @@ qemudDomainEventRegister (virConnectPtr
struct qemud_driver *driver = conn->privateData;
int ret;
+ qemuDriverLock(driver);
ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
callback, opaque, freecb);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -3508,8 +3702,10 @@ qemudDomainEventDeregister (virConnectPt
struct qemud_driver *driver = conn->privateData;
int ret;
+ qemuDriverLock(driver);
ret = virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
callback);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -3573,6 +3769,7 @@ qemudDomainMigratePrepare2 (virConnectPt
*uri_out = NULL;
+ qemuDriverLock(driver);
if (!dom_xml) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("no domain XML passed"));
@@ -3683,9 +3880,10 @@ qemudDomainMigratePrepare2 (virConnectPt
if (qemudStartVMDaemon (dconn, driver, vm, migrateFrom) < 0) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to start listening VM"));
- if (!vm->persistent)
+ if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm);
-
+ vm = NULL;
+ }
goto cleanup;
}
qemudDomainEventDispatch(driver, vm,
@@ -3698,7 +3896,9 @@ cleanup:
if (ret != 0) {
VIR_FREE(*uri_out);
}
-
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -3719,6 +3919,7 @@ qemudDomainMigratePerform (virDomainPtr
char *info = NULL;
int ret = -1;
+ qemuDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -3783,12 +3984,17 @@ qemudDomainMigratePerform (virDomainPtr
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
- if (!vm->persistent)
+ if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm);
- ret = 0;
-
-cleanup:
- VIR_FREE(info);
+ vm = NULL;
+ }
+ ret = 0;
+
+cleanup:
+ VIR_FREE(info);
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return ret;
}
@@ -3807,6 +4013,7 @@ qemudDomainMigrateFinish2 (virConnectPtr
virDomainPtr dom = NULL;
char *info = NULL;
+ qemuDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dname);
if (!vm) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -3829,11 +4036,16 @@ qemudDomainMigrateFinish2 (virConnectPtr
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_FAILED);
- if (!vm->persistent)
+ if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm);
- }
-
-cleanup:
+ vm = NULL;
+ }
+ }
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
return dom;
}
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|