#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,
struct uml_driver *driver,
struct uml_driver *driver = data;
virDomainObjPtr dom;
+ umlDriverLock(driver);
if (watch != driver->inotifyWatch)
- return;
+ goto cleanup;
reread:
got = read(fd, buf, sizeof(buf));
if (got == -1) {
if (errno == EINTR)
goto reread;
- return;
+ goto cleanup;
}
tmp = buf;
while (got) {
if (got < sizeof(struct inotify_event))
- return; /* bad */
+ goto cleanup; /* bad */
e = (struct inotify_event *)tmp;
tmp += sizeof(struct inotify_event);
got -= sizeof(struct inotify_event);
if (got < e->len)
- return;
+ goto cleanup;
tmp += e->len;
got -= e->len;
if (e->mask & IN_DELETE) {
if (!virDomainIsActive(dom)) {
+ virDomainObjUnlock(dom);
continue;
}
dom->state = VIR_DOMAIN_SHUTOFF;
} else if (e->mask & (IN_CREATE | IN_MODIFY)) {
if (virDomainIsActive(dom)) {
+ virDomainObjUnlock(dom);
continue;
}
if (umlReadPidFile(NULL, driver, dom) < 0) {
+ virDomainObjUnlock(dom);
continue;
}
if (umlIdentifyChrPTY(NULL, driver, dom) < 0)
umlShutdownVMDaemon(NULL, driver, dom);
}
+ virDomainObjUnlock(dom);
}
+
+cleanup:
+ umlDriverUnlock(driver);
}
/**
if (VIR_ALLOC(uml_driver) < 0)
return -1;
+ pthread_mutex_init(¨_driver->lock, NULL);
+ umlDriverLock(uml_driver);
+
/* Don't have a dom0 so start from 1 */
uml_driver->nextvmid = 1;
if (!(pw = getpwuid(uid))) {
umlLog(UML_ERR, _("Failed to find user record for uid '%d': %s\n"),
uid, strerror(errno));
- goto out_nouid;
+ goto error;
}
if (!uid) {
if ((uml_driver->inotifyFD = inotify_init()) < 0) {
umlLog(UML_ERR, "%s", _("cannot initialize inotify"));
- goto out_nouid;
+ goto error;
}
if (virFileMakePath(uml_driver->monitorDir) < 0) {
umlLog(UML_ERR, _("Failed to create monitor directory %s: %s"),
uml_driver->monitorDir, strerror(errno));
- umlShutdown();
- return -1;
+ goto error;
}
if (inotify_add_watch(uml_driver->inotifyFD,
uml_driver->monitorDir,
IN_CREATE | IN_MODIFY | IN_DELETE) < 0) {
- umlShutdown();
- return -1;
+ goto error;
}
if ((uml_driver->inotifyWatch =
virEventAddHandle(uml_driver->inotifyFD, POLLIN,
- umlInotifyEvent, uml_driver, NULL)) < 0) {
- umlShutdown();
- return -1;
- }
+ umlInotifyEvent, uml_driver, NULL)) < 0)
+ goto error;
if (virDomainLoadAllConfigs(NULL,
uml_driver->caps,
¨_driver->domains,
uml_driver->configDir,
uml_driver->autostartDir,
- NULL, NULL) < 0) {
- umlShutdown();
- return -1;
- }
+ NULL, NULL) < 0)
+ goto error;
+
umlAutostartConfigs(uml_driver);
+ umlDriverUnlock(uml_driver);
return 0;
- out_of_memory:
+out_of_memory:
umlLog (UML_ERR,
"%s", _("umlStartup: out of memory\n"));
- out_nouid:
+
+error:
VIR_FREE(base);
- VIR_FREE(uml_driver);
+ umlDriverUnlock(uml_driver);
+ umlShutdown();
return -1;
}
if (!uml_driver)
return 0;
+ umlDriverLock(uml_driver);
virDomainLoadAllConfigs(NULL,
uml_driver->caps,
¨_driver->domains,
NULL, NULL);
umlAutostartConfigs(uml_driver);
+ umlDriverUnlock(uml_driver);
return 0;
}
static int
umlActive(void) {
unsigned int i;
+ int active = 0;
if (!uml_driver)
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]))
- return 1;
+ active = 1;
+ virDomainObjUnlock(uml_driver->domains.objs[i]);
+ }
+ umlDriverUnlock(uml_driver);
- /* Otherwise we're happy to deal with a shutdown */
- return 0;
+ return active;
}
/**
if (!uml_driver)
return -1;
+ umlDriverLock(uml_driver);
virEventRemoveHandle(uml_driver->inotifyWatch);
close(uml_driver->inotifyFD);
virCapabilitiesFree(uml_driver->caps);
/* shutdown active VMs */
for (i = 0 ; i < uml_driver->domains.count ; i++) {
virDomainObjPtr dom = uml_driver->domains.objs[i];
+ virDomainObjLock(dom);
if (virDomainIsActive(dom))
umlShutdownVMDaemon(NULL, uml_driver, dom);
- if (!dom->persistent)
- virDomainRemoveInactive(¨_driver->domains,
- dom);
+ virDomainObjUnlock(dom);
}
virDomainObjListFree(¨_driver->domains);
if (uml_driver->brctl)
brShutdown(uml_driver->brctl);
+ umlDriverUnlock(uml_driver);
VIR_FREE(uml_driver);
return 0;
struct uml_driver *driver = (struct uml_driver *)conn->privateData;
char *xml;
+ umlDriverLock(driver);
if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for capabilities support"));
+ umlDriverUnlock(driver);
return xml;
}
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, id);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
if (dom) dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
if (dom) dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ umlDriverLock(driver);
vm = virDomainFindByName(&driver->domains, name);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
if (dom) dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
static int umlGetVersion(virConnectPtr conn, unsigned long *version) {
+ struct uml_driver *driver = conn->privateData;
struct utsname ut;
int major, minor, micro;
+ int ret = -1;
uname(&ut);
+ umlDriverLock(driver);
if (sscanf(ut.release, "%u.%u.%u",
&major, &minor, µ) != 3) {
umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("cannot parse version %s"), ut.release);
- return -1;
+ goto cleanup;
}
- *version = uml_driver->umlVersion;
- return 0;
+ *version = driver->umlVersion;
+ ret = 0;
+
+cleanup:
+ umlDriverUnlock(driver);
+ return ret;
}
static char *
struct uml_driver *driver = conn->privateData;
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]))
ids[got++] = driver->domains.objs[i]->def->id;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ umlDriverUnlock(driver);
return got;
}
struct uml_driver *driver = conn->privateData;
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]))
n++;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ umlDriverUnlock(driver);
return n;
}
unsigned int flags ATTRIBUTE_UNUSED) {
struct uml_driver *driver = conn->privateData;
virDomainDefPtr def;
- virDomainObjPtr vm;
+ virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
+ umlDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
goto cleanup;
cleanup:
virDomainDefFree(def);
+ if (vm)
+ virDomainObjUnlock(vm);
+ umlDriverUnlock(driver);
return dom;
}
char *info = NULL;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id);
+ umlDriverUnlock(driver);
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
cleanup:
VIR_FREE(info);
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ umlDriverUnlock(driver);
return ret;
}
virDomainObjPtr vm;
char *type = NULL;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
"%s", _("failed to allocate space for ostype"));
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return type;
}
virDomainObjPtr vm;
unsigned long ret = 0;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
ret = vm->def->maxmem;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
virDomainObjPtr vm;
char *ret = NULL;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
flags);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
struct uml_driver *driver = conn->privateData;
int got = 0, i;
+ umlDriverLock(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))) {
umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for VM name string"));
+ virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup;
}
}
+ virDomainObjUnlock(driver->domains.objs[i]);
}
+ umlDriverUnlock(driver);
return got;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
+ umlDriverUnlock(driver);
return -1;
}
struct uml_driver *driver = conn->privateData;
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]))
n++;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ umlDriverUnlock(driver);
return n;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
ret = umlStartVMDaemon(dom->conn, driver, vm);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ umlDriverUnlock(driver);
return ret;
}
static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) {
struct uml_driver *driver = conn->privateData;
virDomainDefPtr def;
- virDomainObjPtr vm;
+ virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
+ umlDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
goto cleanup;
vm->newDef ? vm->newDef : vm->def) < 0) {
virDomainRemoveInactive(&driver->domains,
vm);
+ vm = NULL;
goto cleanup;
}
cleanup:
virDomainDefFree(def);
+ if (vm)
+ virDomainObjUnlock(vm);
+ umlDriverUnlock(driver);
return dom;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
virDomainRemoveInactive(&driver->domains,
vm);
+ vm = NULL;
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ umlDriverUnlock(driver);
return ret;
}
virDomainObjPtr vm;
int ret = -1;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
static int umlDomainSetAutostart(virDomainPtr dom,
int autostart) {
struct uml_driver *driver = dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ virDomainObjPtr vm;
char *configFile = NULL, *autostartLink = NULL;
int ret = -1;
+ umlDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
cleanup:
VIR_FREE(configFile);
VIR_FREE(autostartLink);
-
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
virDomainObjPtr vm;
int fd = -1, ret = -1, i;
+ umlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ umlDriverUnlock(driver);
+
if (!vm) {
umlReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid"));
cleanup:
if (fd >= 0) close (fd);
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}