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; }