Add locking for thread safety to UML driver

This commit is contained in:
Daniel P. Berrange 2008-12-04 21:14:39 +00:00
parent 773c8bac35
commit 055c2b25d2
3 changed files with 187 additions and 38 deletions

View File

@ -1,3 +1,8 @@
Thu Dec 4 21:14:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* src/uml_conf.h: Add driver lock variable
* src/uml_driver.c: Add locking for thread safety
Thu Dec 4 21:13:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com> Thu Dec 4 21:13:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* Makefile.maint: Add umlError function * Makefile.maint: Add umlError function

View File

@ -39,6 +39,8 @@
/* Main driver state */ /* Main driver state */
struct uml_driver { struct uml_driver {
PTHREAD_MUTEX_T(lock);
unsigned int umlVersion; unsigned int umlVersion;
int nextvmid; int nextvmid;

View File

@ -74,6 +74,15 @@ static int umlShutdown(void);
#define umlLog(level, msg...) fprintf(stderr, msg) #define umlLog(level, msg...) fprintf(stderr, msg)
static void umlDriverLock(struct uml_driver *driver)
{
pthread_mutex_lock(&driver->lock);
}
static void umlDriverUnlock(struct uml_driver *driver)
{
pthread_mutex_unlock(&driver->lock);
}
static int umlOpenMonitor(virConnectPtr conn, static int umlOpenMonitor(virConnectPtr conn,
struct uml_driver *driver, struct uml_driver *driver,
@ -206,28 +215,29 @@ umlInotifyEvent(int watch,
struct uml_driver *driver = data; struct uml_driver *driver = data;
virDomainObjPtr dom; virDomainObjPtr dom;
umlDriverLock(driver);
if (watch != driver->inotifyWatch) if (watch != driver->inotifyWatch)
return; goto cleanup;
reread: reread:
got = read(fd, buf, sizeof(buf)); got = read(fd, buf, sizeof(buf));
if (got == -1) { if (got == -1) {
if (errno == EINTR) if (errno == EINTR)
goto reread; goto reread;
return; goto cleanup;
} }
tmp = buf; tmp = buf;
while (got) { while (got) {
if (got < sizeof(struct inotify_event)) if (got < sizeof(struct inotify_event))
return; /* bad */ goto cleanup; /* bad */
e = (struct inotify_event *)tmp; e = (struct inotify_event *)tmp;
tmp += sizeof(struct inotify_event); tmp += sizeof(struct inotify_event);
got -= sizeof(struct inotify_event); got -= sizeof(struct inotify_event);
if (got < e->len) if (got < e->len)
return; goto cleanup;
tmp += e->len; tmp += e->len;
got -= e->len; got -= e->len;
@ -242,6 +252,7 @@ reread:
if (e->mask & IN_DELETE) { if (e->mask & IN_DELETE) {
if (!virDomainIsActive(dom)) { if (!virDomainIsActive(dom)) {
virDomainObjUnlock(dom);
continue; continue;
} }
@ -254,10 +265,12 @@ reread:
dom->state = VIR_DOMAIN_SHUTOFF; dom->state = VIR_DOMAIN_SHUTOFF;
} else if (e->mask & (IN_CREATE | IN_MODIFY)) { } else if (e->mask & (IN_CREATE | IN_MODIFY)) {
if (virDomainIsActive(dom)) { if (virDomainIsActive(dom)) {
virDomainObjUnlock(dom);
continue; continue;
} }
if (umlReadPidFile(NULL, driver, dom) < 0) { if (umlReadPidFile(NULL, driver, dom) < 0) {
virDomainObjUnlock(dom);
continue; continue;
} }
@ -270,7 +283,11 @@ reread:
if (umlIdentifyChrPTY(NULL, driver, dom) < 0) if (umlIdentifyChrPTY(NULL, driver, dom) < 0)
umlShutdownVMDaemon(NULL, driver, dom); umlShutdownVMDaemon(NULL, driver, dom);
} }
virDomainObjUnlock(dom);
} }
cleanup:
umlDriverUnlock(driver);
} }
/** /**
@ -288,13 +305,16 @@ umlStartup(void) {
if (VIR_ALLOC(uml_driver) < 0) if (VIR_ALLOC(uml_driver) < 0)
return -1; return -1;
pthread_mutex_init(&uml_driver->lock, NULL);
umlDriverLock(uml_driver);
/* Don't have a dom0 so start from 1 */ /* Don't have a dom0 so start from 1 */
uml_driver->nextvmid = 1; uml_driver->nextvmid = 1;
if (!(pw = getpwuid(uid))) { if (!(pw = getpwuid(uid))) {
umlLog(UML_ERR, _("Failed to find user record for uid '%d': %s\n"), umlLog(UML_ERR, _("Failed to find user record for uid '%d': %s\n"),
uid, strerror(errno)); uid, strerror(errno));
goto out_nouid; goto error;
} }
if (!uid) { if (!uid) {
@ -338,49 +358,47 @@ umlStartup(void) {
if ((uml_driver->inotifyFD = inotify_init()) < 0) { if ((uml_driver->inotifyFD = inotify_init()) < 0) {
umlLog(UML_ERR, "%s", _("cannot initialize inotify")); umlLog(UML_ERR, "%s", _("cannot initialize inotify"));
goto out_nouid; goto error;
} }
if (virFileMakePath(uml_driver->monitorDir) < 0) { if (virFileMakePath(uml_driver->monitorDir) < 0) {
umlLog(UML_ERR, _("Failed to create monitor directory %s: %s"), umlLog(UML_ERR, _("Failed to create monitor directory %s: %s"),
uml_driver->monitorDir, strerror(errno)); uml_driver->monitorDir, strerror(errno));
umlShutdown(); goto error;
return -1;
} }
if (inotify_add_watch(uml_driver->inotifyFD, if (inotify_add_watch(uml_driver->inotifyFD,
uml_driver->monitorDir, uml_driver->monitorDir,
IN_CREATE | IN_MODIFY | IN_DELETE) < 0) { IN_CREATE | IN_MODIFY | IN_DELETE) < 0) {
umlShutdown(); goto error;
return -1;
} }
if ((uml_driver->inotifyWatch = if ((uml_driver->inotifyWatch =
virEventAddHandle(uml_driver->inotifyFD, POLLIN, virEventAddHandle(uml_driver->inotifyFD, POLLIN,
umlInotifyEvent, uml_driver, NULL)) < 0) { umlInotifyEvent, uml_driver, NULL)) < 0)
umlShutdown(); goto error;
return -1;
}
if (virDomainLoadAllConfigs(NULL, if (virDomainLoadAllConfigs(NULL,
uml_driver->caps, uml_driver->caps,
&uml_driver->domains, &uml_driver->domains,
uml_driver->configDir, uml_driver->configDir,
uml_driver->autostartDir, uml_driver->autostartDir,
NULL, NULL) < 0) { NULL, NULL) < 0)
umlShutdown(); goto error;
return -1;
}
umlAutostartConfigs(uml_driver); umlAutostartConfigs(uml_driver);
umlDriverUnlock(uml_driver);
return 0; return 0;
out_of_memory: out_of_memory:
umlLog (UML_ERR, umlLog (UML_ERR,
"%s", _("umlStartup: out of memory\n")); "%s", _("umlStartup: out of memory\n"));
out_nouid:
error:
VIR_FREE(base); VIR_FREE(base);
VIR_FREE(uml_driver); umlDriverUnlock(uml_driver);
umlShutdown();
return -1; return -1;
} }
@ -395,6 +413,7 @@ umlReload(void) {
if (!uml_driver) if (!uml_driver)
return 0; return 0;
umlDriverLock(uml_driver);
virDomainLoadAllConfigs(NULL, virDomainLoadAllConfigs(NULL,
uml_driver->caps, uml_driver->caps,
&uml_driver->domains, &uml_driver->domains,
@ -403,6 +422,7 @@ umlReload(void) {
NULL, NULL); NULL, NULL);
umlAutostartConfigs(uml_driver); umlAutostartConfigs(uml_driver);
umlDriverUnlock(uml_driver);
return 0; return 0;
} }
@ -418,16 +438,21 @@ umlReload(void) {
static int static int
umlActive(void) { umlActive(void) {
unsigned int i; unsigned int i;
int active = 0;
if (!uml_driver) if (!uml_driver)
return 0; return 0;
for (i = 0 ; i < uml_driver->domains.count ; i++) umlDriverLock(uml_driver);
for (i = 0 ; i < uml_driver->domains.count ; i++) {
virDomainObjLock(uml_driver->domains.objs[i]);
if (virDomainIsActive(uml_driver->domains.objs[i])) if (virDomainIsActive(uml_driver->domains.objs[i]))
return 1; active = 1;
virDomainObjUnlock(uml_driver->domains.objs[i]);
}
umlDriverUnlock(uml_driver);
/* Otherwise we're happy to deal with a shutdown */ return active;
return 0;
} }
/** /**
@ -442,6 +467,7 @@ umlShutdown(void) {
if (!uml_driver) if (!uml_driver)
return -1; return -1;
umlDriverLock(uml_driver);
virEventRemoveHandle(uml_driver->inotifyWatch); virEventRemoveHandle(uml_driver->inotifyWatch);
close(uml_driver->inotifyFD); close(uml_driver->inotifyFD);
virCapabilitiesFree(uml_driver->caps); virCapabilitiesFree(uml_driver->caps);
@ -449,11 +475,10 @@ umlShutdown(void) {
/* shutdown active VMs */ /* shutdown active VMs */
for (i = 0 ; i < uml_driver->domains.count ; i++) { for (i = 0 ; i < uml_driver->domains.count ; i++) {
virDomainObjPtr dom = uml_driver->domains.objs[i]; virDomainObjPtr dom = uml_driver->domains.objs[i];
virDomainObjLock(dom);
if (virDomainIsActive(dom)) if (virDomainIsActive(dom))
umlShutdownVMDaemon(NULL, uml_driver, dom); umlShutdownVMDaemon(NULL, uml_driver, dom);
if (!dom->persistent) virDomainObjUnlock(dom);
virDomainRemoveInactive(&uml_driver->domains,
dom);
} }
virDomainObjListFree(&uml_driver->domains); virDomainObjListFree(&uml_driver->domains);
@ -466,6 +491,7 @@ umlShutdown(void) {
if (uml_driver->brctl) if (uml_driver->brctl)
brShutdown(uml_driver->brctl); brShutdown(uml_driver->brctl);
umlDriverUnlock(uml_driver);
VIR_FREE(uml_driver); VIR_FREE(uml_driver);
return 0; return 0;
@ -904,9 +930,11 @@ static char *umlGetCapabilities(virConnectPtr conn) {
struct uml_driver *driver = (struct uml_driver *)conn->privateData; struct uml_driver *driver = (struct uml_driver *)conn->privateData;
char *xml; char *xml;
umlDriverLock(driver);
if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL) if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for capabilities support")); "%s", _("failed to allocate space for capabilities support"));
umlDriverUnlock(driver);
return xml; return xml;
} }
@ -1018,7 +1046,10 @@ static virDomainPtr umlDomainLookupByID(virConnectPtr conn,
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, id); vm = virDomainFindByID(&driver->domains, id);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL); umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup; goto cleanup;
@ -1028,6 +1059,8 @@ static virDomainPtr umlDomainLookupByID(virConnectPtr conn,
if (dom) dom->id = vm->def->id; if (dom) dom->id = vm->def->id;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return dom; return dom;
} }
@ -1037,7 +1070,10 @@ static virDomainPtr umlDomainLookupByUUID(virConnectPtr conn,
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, uuid); vm = virDomainFindByUUID(&driver->domains, uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL); umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup; goto cleanup;
@ -1047,6 +1083,8 @@ static virDomainPtr umlDomainLookupByUUID(virConnectPtr conn,
if (dom) dom->id = vm->def->id; if (dom) dom->id = vm->def->id;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return dom; return dom;
} }
@ -1056,7 +1094,10 @@ static virDomainPtr umlDomainLookupByName(virConnectPtr conn,
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
umlDriverLock(driver);
vm = virDomainFindByName(&driver->domains, name); vm = virDomainFindByName(&driver->domains, name);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL); umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup; goto cleanup;
@ -1066,24 +1107,33 @@ static virDomainPtr umlDomainLookupByName(virConnectPtr conn,
if (dom) dom->id = vm->def->id; if (dom) dom->id = vm->def->id;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return dom; return dom;
} }
static int umlGetVersion(virConnectPtr conn, unsigned long *version) { static int umlGetVersion(virConnectPtr conn, unsigned long *version) {
struct uml_driver *driver = conn->privateData;
struct utsname ut; struct utsname ut;
int major, minor, micro; int major, minor, micro;
int ret = -1;
uname(&ut); uname(&ut);
umlDriverLock(driver);
if (sscanf(ut.release, "%u.%u.%u", if (sscanf(ut.release, "%u.%u.%u",
&major, &minor, &micro) != 3) { &major, &minor, &micro) != 3) {
umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("cannot parse version %s"), ut.release); _("cannot parse version %s"), ut.release);
return -1; goto cleanup;
} }
*version = uml_driver->umlVersion; *version = driver->umlVersion;
return 0; ret = 0;
cleanup:
umlDriverUnlock(driver);
return ret;
} }
static char * static char *
@ -1112,9 +1162,14 @@ static int umlListDomains(virConnectPtr conn, int *ids, int nids) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int got = 0, i; int got = 0, i;
for (i = 0 ; i < driver->domains.count && got < nids ; i++) umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++) {
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i])) if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id; ids[got++] = driver->domains.objs[i]->def->id;
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver);
return got; return got;
} }
@ -1122,9 +1177,14 @@ static int umlNumDomains(virConnectPtr conn) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int n = 0, i; int n = 0, i;
for (i = 0 ; i < driver->domains.count ; i++) umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) {
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i])) if (virDomainIsActive(driver->domains.objs[i]))
n++; n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver);
return n; return n;
} }
@ -1132,9 +1192,10 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
unsigned int flags ATTRIBUTE_UNUSED) { unsigned int flags ATTRIBUTE_UNUSED) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
virDomainDefPtr def; virDomainDefPtr def;
virDomainObjPtr vm; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
umlDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml))) if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
goto cleanup; goto cleanup;
@ -1174,6 +1235,9 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
cleanup: cleanup:
virDomainDefFree(def); virDomainDefFree(def);
if (vm)
virDomainObjUnlock(vm);
umlDriverUnlock(driver);
return dom; return dom;
} }
@ -1184,7 +1248,9 @@ static int umlDomainShutdown(virDomainPtr dom) {
char *info = NULL; char *info = NULL;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id); vm = virDomainFindByID(&driver->domains, dom->id);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id); _("no domain with matching id %d"), dom->id);
@ -1202,6 +1268,8 @@ static int umlDomainShutdown(virDomainPtr dom) {
cleanup: cleanup:
VIR_FREE(info); VIR_FREE(info);
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1211,6 +1279,7 @@ static int umlDomainDestroy(virDomainPtr dom) {
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id); vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@ -1227,6 +1296,9 @@ static int umlDomainDestroy(virDomainPtr dom) {
ret = 0; ret = 0;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
umlDriverUnlock(driver);
return ret; return ret;
} }
@ -1236,7 +1308,9 @@ static char *umlDomainGetOSType(virDomainPtr dom) {
virDomainObjPtr vm; virDomainObjPtr vm;
char *type = NULL; char *type = NULL;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
@ -1248,6 +1322,8 @@ static char *umlDomainGetOSType(virDomainPtr dom) {
"%s", _("failed to allocate space for ostype")); "%s", _("failed to allocate space for ostype"));
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return type; return type;
} }
@ -1257,7 +1333,10 @@ static unsigned long umlDomainGetMaxMemory(virDomainPtr dom) {
virDomainObjPtr vm; virDomainObjPtr vm;
unsigned long ret = 0; unsigned long ret = 0;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
@ -1269,6 +1348,8 @@ static unsigned long umlDomainGetMaxMemory(virDomainPtr dom) {
ret = vm->def->maxmem; ret = vm->def->maxmem;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1277,7 +1358,10 @@ static int umlDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
@ -1297,6 +1381,8 @@ static int umlDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
ret = 0; ret = 0;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1305,7 +1391,10 @@ static int umlDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
@ -1331,6 +1420,8 @@ static int umlDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
ret = 0; ret = 0;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1340,7 +1431,10 @@ static int umlDomainGetInfo(virDomainPtr dom,
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
@ -1365,6 +1459,8 @@ static int umlDomainGetInfo(virDomainPtr dom,
ret = 0; ret = 0;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1375,7 +1471,10 @@ static char *umlDomainDumpXML(virDomainPtr dom,
virDomainObjPtr vm; virDomainObjPtr vm;
char *ret = NULL; char *ret = NULL;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
@ -1388,6 +1487,8 @@ static char *umlDomainDumpXML(virDomainPtr dom,
flags); flags);
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1397,21 +1498,27 @@ static int umlListDefinedDomains(virConnectPtr conn,
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int got = 0, i; int got = 0, i;
umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) { for (i = 0 ; i < driver->domains.count && got < nnames ; i++) {
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) { if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) { if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for VM name string")); "%s", _("failed to allocate space for VM name string"));
virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup; goto cleanup;
} }
} }
virDomainObjUnlock(driver->domains.objs[i]);
} }
umlDriverUnlock(driver);
return got; return got;
cleanup: cleanup:
for (i = 0 ; i < got ; i++) for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]); VIR_FREE(names[i]);
umlDriverUnlock(driver);
return -1; return -1;
} }
@ -1419,9 +1526,14 @@ static int umlNumDefinedDomains(virConnectPtr conn) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
int n = 0, i; int n = 0, i;
for (i = 0 ; i < driver->domains.count ; i++) umlDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++) {
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) if (!virDomainIsActive(driver->domains.objs[i]))
n++; n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
umlDriverUnlock(driver);
return n; return n;
} }
@ -1432,7 +1544,10 @@ static int umlDomainStart(virDomainPtr dom) {
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
@ -1442,6 +1557,9 @@ static int umlDomainStart(virDomainPtr dom) {
ret = umlStartVMDaemon(dom->conn, driver, vm); ret = umlStartVMDaemon(dom->conn, driver, vm);
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
umlDriverUnlock(driver);
return ret; return ret;
} }
@ -1449,9 +1567,10 @@ cleanup:
static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) { static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) {
struct uml_driver *driver = conn->privateData; struct uml_driver *driver = conn->privateData;
virDomainDefPtr def; virDomainDefPtr def;
virDomainObjPtr vm; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
umlDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml))) if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
goto cleanup; goto cleanup;
@ -1467,6 +1586,7 @@ static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) {
vm->newDef ? vm->newDef : vm->def) < 0) { vm->newDef ? vm->newDef : vm->def) < 0) {
virDomainRemoveInactive(&driver->domains, virDomainRemoveInactive(&driver->domains,
vm); vm);
vm = NULL;
goto cleanup; goto cleanup;
} }
@ -1475,6 +1595,9 @@ static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) {
cleanup: cleanup:
virDomainDefFree(def); virDomainDefFree(def);
if (vm)
virDomainObjUnlock(vm);
umlDriverUnlock(driver);
return dom; return dom;
} }
@ -1483,6 +1606,7 @@ static int umlDomainUndefine(virDomainPtr dom) {
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@ -1507,9 +1631,13 @@ static int umlDomainUndefine(virDomainPtr dom) {
virDomainRemoveInactive(&driver->domains, virDomainRemoveInactive(&driver->domains,
vm); vm);
vm = NULL;
ret = 0; ret = 0;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
umlDriverUnlock(driver);
return ret; return ret;
} }
@ -1521,7 +1649,9 @@ static int umlDomainGetAutostart(virDomainPtr dom,
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
@ -1532,16 +1662,22 @@ static int umlDomainGetAutostart(virDomainPtr dom,
ret = 0; ret = 0;
cleanup: cleanup:
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
static int umlDomainSetAutostart(virDomainPtr dom, static int umlDomainSetAutostart(virDomainPtr dom,
int autostart) { int autostart) {
struct uml_driver *driver = dom->conn->privateData; struct uml_driver *driver = dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid); virDomainObjPtr vm;
char *configFile = NULL, *autostartLink = NULL; char *configFile = NULL, *autostartLink = NULL;
int ret = -1; int ret = -1;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
@ -1594,7 +1730,8 @@ static int umlDomainSetAutostart(virDomainPtr dom,
cleanup: cleanup:
VIR_FREE(configFile); VIR_FREE(configFile);
VIR_FREE(autostartLink); VIR_FREE(autostartLink);
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }
@ -1610,7 +1747,10 @@ umlDomainBlockPeek (virDomainPtr dom,
virDomainObjPtr vm; virDomainObjPtr vm;
int fd = -1, ret = -1, i; int fd = -1, ret = -1, i;
umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
umlDriverUnlock(driver);
if (!vm) { if (!vm) {
umlReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, umlReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid")); _("no domain with matching uuid"));
@ -1661,6 +1801,8 @@ umlDomainBlockPeek (virDomainPtr dom,
cleanup: cleanup:
if (fd >= 0) close (fd); if (fd >= 0) close (fd);
if (vm)
virDomainObjUnlock(vm);
return ret; return ret;
} }