diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index e82d2e491e..33f2ecd533 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4396,7 +4396,7 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver, bool *hasHwVirt, bool migrating) { - const virCPUDefPtr host = driver->caps->host.cpu; + virCPUDefPtr host = NULL; virCPUDefPtr guest = NULL; virCPUDefPtr cpu = NULL; size_t ncpus = 0; @@ -4408,9 +4408,15 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver, int ret = -1; virBuffer buf = VIR_BUFFER_INITIALIZER; int i; + virCapsPtr caps = NULL; *hasHwVirt = false; + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + host = caps->host.cpu; + if (def->os.arch == VIR_ARCH_I686) default_model = "qemu32"; else @@ -4595,7 +4601,7 @@ cleanup: cpuDataFree(host->arch, data); virCPUDefFree(guest); virCPUDefFree(cpu); - + virObjectUnref(caps); return ret; no_memory: diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 17f7d45bfd..574d2cb477 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -526,6 +526,106 @@ virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver) return virObjectRef(driver->config); } + +virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) +{ + size_t i; + virCapsPtr caps; + virSecurityManagerPtr *sec_managers = NULL; + /* Security driver data */ + const char *doi, *model; + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + + /* Basic host arch / guest machine capabilities */ + if (!(caps = virQEMUCapsInit(driver->qemuCapsCache))) { + virReportOOMError(); + virObjectUnref(cfg); + return NULL; + } + + if (cfg->allowDiskFormatProbing) { + caps->defaultDiskDriverName = NULL; + caps->defaultDiskDriverType = VIR_STORAGE_FILE_AUTO; + } else { + caps->defaultDiskDriverName = "qemu"; + caps->defaultDiskDriverType = VIR_STORAGE_FILE_RAW; + } + + qemuDomainSetPrivateDataHooks(caps); + qemuDomainSetNamespaceHooks(caps); + + if (virGetHostUUID(caps->host.host_uuid)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot get the host uuid")); + goto err_exit; + } + + /* access sec drivers and create a sec model for each one */ + sec_managers = virSecurityManagerGetNested(driver->securityManager); + if (sec_managers == NULL) { + goto err_exit; + } + + /* calculate length */ + for (i = 0; sec_managers[i]; i++) + ; + caps->host.nsecModels = i; + + if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0) + goto no_memory; + + for (i = 0; sec_managers[i]; i++) { + doi = virSecurityManagerGetDOI(sec_managers[i]); + model = virSecurityManagerGetModel(sec_managers[i]); + if (!(caps->host.secModels[i].model = strdup(model))) + goto no_memory; + if (!(caps->host.secModels[i].doi = strdup(doi))) + goto no_memory; + VIR_DEBUG("Initialized caps for security driver \"%s\" with " + "DOI \"%s\"", model, doi); + } + VIR_FREE(sec_managers); + + virObjectUnref(cfg); + return caps; + +no_memory: + virReportOOMError(); +err_exit: + VIR_FREE(sec_managers); + virObjectUnref(caps); + virObjectUnref(cfg); + return NULL; +} + + +/** + * virQEMUDriverGetCapabilities: + * + * Get a reference to the virCapsPtr instance for the + * driver. If @refresh is true, the capabilities will be + * rebuilt first + * + * The caller must release the reference with virObjetUnref + * + * Returns: a reference to a virCapsPtr instance or NULL + */ +virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver, + bool refresh) +{ + if (refresh) { + virCapsPtr caps = NULL; + if ((caps = virQEMUDriverCreateCapabilities(driver)) == NULL) + return NULL; + + virObjectUnref(driver->caps); + driver->caps = caps; + } + + return virObjectRef(driver->caps); +} + + static void qemuDriverCloseCallbackFree(void *payload, const void *name ATTRIBUTE_UNUSED) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 14680b194f..9ff1c5a392 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -183,7 +183,9 @@ struct _virQEMUDriver { /* Immutable pointer, lockless APIs. Pointless abstraction */ ebtablesContext *ebtables; - /* Require lock while using. Unsafe. XXX */ + /* Require lock to get a reference on the object, + * lockless access thereafter + */ virCapsPtr caps; /* Immutable pointer, self-locking APIs */ @@ -244,6 +246,10 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver); +virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver); +virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver, + bool refresh); + struct qemuDomainDiskInfo { bool removable; bool locked; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b31cc16b34..4917721493 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -664,13 +664,19 @@ static void qemuDomainObjSaveJob(virQEMUDriverPtr driver, virDomainObjPtr obj) { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; if (virDomainObjIsActive(obj)) { - if (virDomainSaveStatus(driver->caps, cfg->stateDir, obj) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, obj) < 0) VIR_WARN("Failed to save status on vm %s", obj->def->name); } +cleanup: virObjectUnref(cfg); + virObjectUnref(caps); } void @@ -1244,21 +1250,24 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver, virCPUDefPtr def_cpu = def->cpu; virDomainControllerDefPtr *controllers = NULL; int ncontrollers = 0; + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; /* Update guest CPU requirements according to host CPU */ if ((flags & VIR_DOMAIN_XML_UPDATE_CPU) && def_cpu && (def_cpu->mode != VIR_CPU_MODE_CUSTOM || def_cpu->model)) { - if (!driver->caps || - !driver->caps->host.cpu || - !driver->caps->host.cpu->model) { + if (!caps->host.cpu || + !caps->host.cpu->model) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("cannot get host CPU capabilities")); goto cleanup; } if (!(cpu = virCPUDefCopy(def_cpu)) || - cpuUpdate(cpu, driver->caps->host.cpu) < 0) + cpuUpdate(cpu, caps->host.cpu) < 0) goto cleanup; def->cpu = cpu; } @@ -1310,6 +1319,7 @@ cleanup: def->controllers = controllers; def->ncontrollers = ncontrollers; } + virObjectUnref(caps); return ret; } @@ -1888,16 +1898,22 @@ qemuDomainSetFakeReboot(virQEMUDriverPtr driver, { qemuDomainObjPrivatePtr priv = vm->privateData; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; if (priv->fakeReboot == value) - return; + goto cleanup; priv->fakeReboot = value; - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) VIR_WARN("Failed to save status on vm %s", vm->def->name); +cleanup: virObjectUnref(cfg); + virObjectUnref(caps); } int diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4243cada21..0651bc87e5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -416,79 +416,6 @@ error: } -static virCapsPtr -qemuCreateCapabilities(virQEMUDriverPtr driver) -{ - size_t i; - virCapsPtr caps; - virSecurityManagerPtr *sec_managers = NULL; - /* Security driver data */ - const char *doi, *model; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - - /* Basic host arch / guest machine capabilities */ - if (!(caps = virQEMUCapsInit(driver->qemuCapsCache))) { - virReportOOMError(); - virObjectUnref(cfg); - return NULL; - } - - if (cfg->allowDiskFormatProbing) { - caps->defaultDiskDriverName = NULL; - caps->defaultDiskDriverType = VIR_STORAGE_FILE_AUTO; - } else { - caps->defaultDiskDriverName = "qemu"; - caps->defaultDiskDriverType = VIR_STORAGE_FILE_RAW; - } - - qemuDomainSetPrivateDataHooks(caps); - qemuDomainSetNamespaceHooks(caps); - - if (virGetHostUUID(caps->host.host_uuid)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot get the host uuid")); - goto err_exit; - } - - /* access sec drivers and create a sec model for each one */ - sec_managers = virSecurityManagerGetNested(driver->securityManager); - if (sec_managers == NULL) { - goto err_exit; - } - - /* calculate length */ - for (i = 0; sec_managers[i]; i++) - ; - caps->host.nsecModels = i; - - if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0) - goto no_memory; - - for (i = 0; sec_managers[i]; i++) { - doi = virSecurityManagerGetDOI(sec_managers[i]); - model = virSecurityManagerGetModel(sec_managers[i]); - if (!(caps->host.secModels[i].model = strdup(model))) - goto no_memory; - if (!(caps->host.secModels[i].doi = strdup(doi))) - goto no_memory; - VIR_DEBUG("Initialized caps for security driver \"%s\" with " - "DOI \"%s\"", model, doi); - } - VIR_FREE(sec_managers); - - virObjectUnref(cfg); - return caps; - -no_memory: - virReportOOMError(); -err_exit: - VIR_FREE(sec_managers); - virObjectUnref(caps); - virObjectUnref(cfg); - return NULL; -} - - static int qemuDomainSnapshotLoad(virDomainObjPtr vm, void *data) @@ -507,6 +434,7 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm, VIR_DOMAIN_SNAPSHOT_PARSE_DISKS | VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL); int ret = -1; + virCapsPtr caps = NULL; virObjectLock(vm); if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) { @@ -515,6 +443,9 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm, goto cleanup; } + if (!(caps = virQEMUDriverGetCapabilities(qemu_driver, false))) + goto cleanup; + VIR_INFO("Scanning for snapshots for domain %s in %s", vm->def->name, snapDir); @@ -547,7 +478,7 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm, continue; } - def = virDomainSnapshotDefParseString(xmlStr, qemu_driver->caps, + def = virDomainSnapshotDefParseString(xmlStr, caps, QEMU_EXPECTED_VIRT_TYPES, flags); if (def == NULL) { @@ -598,6 +529,7 @@ cleanup: if (dir) closedir(dir); VIR_FREE(snapDir); + virObjectUnref(caps); virObjectUnlock(vm); return ret; } @@ -822,7 +754,7 @@ qemuStartup(bool privileged, if (!qemu_driver->qemuCapsCache) goto error; - if ((qemu_driver->caps = qemuCreateCapabilities(qemu_driver)) == NULL) + if ((qemu_driver->caps = virQEMUDriverCreateCapabilities(qemu_driver)) == NULL) goto error; /* If hugetlbfs is present, then we need to create a sub-directory within @@ -955,21 +887,28 @@ static void qemuNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque) */ static int qemuReload(void) { - virQEMUDriverConfigPtr cfg; + virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; if (!qemu_driver) return 0; qemuDriverLock(qemu_driver); + if (!(caps = virQEMUDriverGetCapabilities(qemu_driver, false))) + goto cleanup; + cfg = virQEMUDriverGetConfig(qemu_driver); virDomainObjListLoadAllConfigs(qemu_driver->domains, - qemu_driver->caps, + caps, cfg->configDir, cfg->autostartDir, 0, QEMU_EXPECTED_VIRT_TYPES, qemuNotifyLoadDomain, qemu_driver); + +cleanup: qemuDriverUnlock(qemu_driver); virObjectUnref(cfg); + virObjectUnref(caps); return 0; } @@ -1281,14 +1220,12 @@ static char *qemuGetCapabilities(virConnectPtr conn) { qemuDriverLock(driver); - if ((caps = qemuCreateCapabilities(qemu_driver)) == NULL) + if (!(caps = virQEMUDriverGetCapabilities(qemu_driver, true))) goto cleanup; - virObjectUnref(qemu_driver->caps); - qemu_driver->caps = caps; - - if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL) + if ((xml = virCapabilitiesFormatXML(caps)) == NULL) virReportOOMError(); + virObjectUnref(caps); cleanup: qemuDriverUnlock(driver); @@ -1503,9 +1440,13 @@ static int qemuGetVersion(virConnectPtr conn, unsigned long *version) { virQEMUDriverPtr driver = conn->privateData; int ret = -1; unsigned int qemuVersion; + virCapsPtr caps = NULL; qemuDriverLock(driver); - if (virQEMUCapsGetDefaultVersion(driver->caps, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virQEMUCapsGetDefaultVersion(caps, driver->qemuCapsCache, &qemuVersion) < 0) goto cleanup; @@ -1514,6 +1455,7 @@ static int qemuGetVersion(virConnectPtr conn, unsigned long *version) { ret = 0; cleanup: + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -1566,13 +1508,14 @@ qemuCanonicalizeMachine(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml, unsigned int flags) { virQEMUDriverPtr driver = conn->privateData; - virDomainDefPtr def; + virDomainDefPtr def = NULL; virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; virDomainEventPtr event = NULL; virDomainEventPtr event2 = NULL; unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD; virQEMUCapsPtr qemuCaps = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_START_PAUSED | VIR_DOMAIN_START_AUTODESTROY, NULL); @@ -1583,7 +1526,11 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml, start_flags |= VIR_QEMU_PROCESS_START_AUTODESROY; qemuDriverLock(driver); - if (!(def = virDomainDefParseString(driver->caps, xml, + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!(def = virDomainDefParseString(caps, xml, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; @@ -1601,7 +1548,7 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml, goto cleanup; if (!(vm = virDomainObjListAdd(driver->domains, - driver->caps, + caps, def, VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL))) @@ -1653,6 +1600,7 @@ cleanup: if (event2) qemuDomainEventQueue(driver, event2); } + virObjectUnref(caps); virObjectUnref(qemuCaps); qemuDriverUnlock(driver); return dom; @@ -1669,6 +1617,7 @@ static int qemuDomainSuspend(virDomainPtr dom) { int eventDetail; int state; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; qemuDriverLock(driver); vm = virDomainObjListFindByUUID(driver->domains, dom->uuid); @@ -1725,7 +1674,9 @@ static int qemuDomainSuspend(virDomainPtr dom) { eventDetail); } } - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto endjob; + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto endjob; ret = 0; @@ -1740,6 +1691,7 @@ cleanup: if (event) qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -1752,6 +1704,7 @@ static int qemuDomainResume(virDomainPtr dom) { virDomainEventPtr event = NULL; int state; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; qemuDriverLock(driver); vm = virDomainObjListFindByUUID(driver->domains, dom->uuid); @@ -1793,7 +1746,9 @@ static int qemuDomainResume(virDomainPtr dom) { VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); } - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto endjob; + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto endjob; ret = 0; @@ -1807,6 +1762,7 @@ cleanup: if (event) qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -2171,6 +2127,7 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, virDomainDefPtr persistentDef = NULL; int ret = -1, r; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -2184,7 +2141,9 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto endjob; + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto endjob; @@ -2252,6 +2211,7 @@ endjob: cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -2879,6 +2839,10 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, int rc; virDomainEventPtr event = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; + virCapsPtr caps; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; if (!qemuMigrationIsAllowed(driver, vm, vm->def, false)) goto cleanup; @@ -2916,7 +2880,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, if (xmlin) { virDomainDefPtr def = NULL; - if (!(def = virDomainDefParseString(driver->caps, xmlin, + if (!(def = virDomainDefParseString(caps, xmlin, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) { goto endjob; @@ -2977,6 +2941,7 @@ cleanup: qemuDomainEventQueue(driver, event); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); return ret; } @@ -3806,13 +3771,14 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, unsigned int flags) { virQEMUDriverPtr driver = dom->conn->privateData; - virDomainObjPtr vm; + virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef; const char * type; int max; int ret = -1; bool maximum; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -3825,6 +3791,8 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, } cfg = virQEMUDriverGetConfig(driver); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; @@ -3835,7 +3803,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, maximum = (flags & VIR_DOMAIN_VCPU_MAXIMUM) != 0; flags &= ~VIR_DOMAIN_VCPU_MAXIMUM; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto endjob; @@ -3897,6 +3865,7 @@ endjob: cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -3927,6 +3896,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, virDomainVcpuPinDefPtr *newVcpuPin = NULL; virBitmapPtr pcpumap = NULL; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -3936,7 +3906,10 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -4027,7 +4000,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, if (newVcpuPin) virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto cleanup; } @@ -4074,6 +4047,7 @@ cleanup: if (vm) virObjectUnlock(vm); virBitmapFree(pcpumap); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -4104,6 +4078,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom, virBitmapPtr cpumask = NULL; unsigned char *cpumap; bool pinned; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -4111,7 +4086,10 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom, if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &targetDef) < 0) goto cleanup; @@ -4164,6 +4142,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom, cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); return ret; } @@ -4186,6 +4165,7 @@ qemuDomainPinEmulator(virDomainPtr dom, virDomainVcpuPinDefPtr *newVcpuPin = NULL; virBitmapPtr pcpumap = NULL; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -4195,6 +4175,9 @@ qemuDomainPinEmulator(virDomainPtr dom, if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Changing affinity for emulator thread dynamically " @@ -4202,7 +4185,7 @@ qemuDomainPinEmulator(virDomainPtr dom, goto cleanup; } - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -4283,7 +4266,7 @@ qemuDomainPinEmulator(virDomainPtr dom, goto cleanup; } - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto cleanup; } @@ -4317,7 +4300,7 @@ cleanup: if (cgroup_dom) virCgroupFree(&cgroup_dom); virBitmapFree(pcpumap); - + virObjectUnref(caps); if (vm) virObjectUnlock(vm); virObjectUnref(cfg); @@ -4337,6 +4320,7 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, int maxcpu, hostcpus, pcpu; virBitmapPtr cpumask = NULL; bool pinned; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -4344,7 +4328,10 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &targetDef) < 0) goto cleanup; @@ -4388,6 +4375,7 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); return ret; } @@ -4488,6 +4476,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) virDomainObjPtr vm; virDomainDefPtr def; int ret = -1; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -4496,7 +4485,10 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &def) < 0) + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &def) < 0) goto cleanup; if (flags & VIR_DOMAIN_AFFECT_LIVE) { @@ -4508,6 +4500,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); return ret; } @@ -4654,16 +4647,20 @@ static int qemuNodeGetSecurityModel(virConnectPtr conn, virQEMUDriverPtr driver = conn->privateData; char *p; int ret = 0; + virCapsPtr caps = NULL; qemuDriverLock(driver); memset(secmodel, 0, sizeof(*secmodel)); - /* We treat no driver as success, but simply return no data in *secmodel */ - if (driver->caps->host.nsecModels == 0 || - driver->caps->host.secModels[0].model == NULL) + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; - p = driver->caps->host.secModels[0].model; + /* We treat no driver as success, but simply return no data in *secmodel */ + if (caps->host.nsecModels == 0 || + caps->host.secModels[0].model == NULL) + goto cleanup; + + p = caps->host.secModels[0].model; if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) { virReportError(VIR_ERR_INTERNAL_ERROR, _("security model string exceeds max %d bytes"), @@ -4673,7 +4670,7 @@ static int qemuNodeGetSecurityModel(virConnectPtr conn, } strcpy(secmodel->model, p); - p = driver->caps->host.secModels[0].doi; + p = caps->host.secModels[0].doi; if (strlen(p) >= VIR_SECURITY_DOI_BUFLEN-1) { virReportError(VIR_ERR_INTERNAL_ERROR, _("security DOI string exceeds max %d bytes"), @@ -4685,6 +4682,7 @@ static int qemuNodeGetSecurityModel(virConnectPtr conn, cleanup: qemuDriverUnlock(driver); + virObjectUnref(caps); return ret; } @@ -4707,6 +4705,7 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, char *xml = NULL; virDomainDefPtr def = NULL; int oflags = edit ? O_RDWR : O_RDONLY; + virCapsPtr caps = NULL; if (bypass_cache) { int directFlag = virFileDirectFdFlag(); @@ -4718,6 +4717,9 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, oflags |= directFlag; } + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto error; + if ((fd = qemuOpenFile(driver, path, oflags, NULL, NULL)) < 0) goto error; if (bypass_cache && @@ -4802,14 +4804,14 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, header.was_running = state; /* Create a domain from this XML */ - if (!(def = virDomainDefParseString(driver->caps, xml, + if (!(def = virDomainDefParseString(caps, xml, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto error; if (xmlin) { virDomainDefPtr def2 = NULL; - if (!(def2 = virDomainDefParseString(driver->caps, xmlin, + if (!(def2 = virDomainDefParseString(caps, xmlin, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto error; @@ -4826,12 +4828,15 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, *ret_def = def; *ret_header = header; + virObjectUnref(caps); + return fd; error: virDomainDefFree(def); VIR_FREE(xml); VIR_FORCE_CLOSE(fd); + virObjectUnref(caps); return -1; } @@ -4851,6 +4856,10 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, virCommandPtr cmd = NULL; char *errbuf = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; if (header->version == 2) { const char *prog = qemuSaveCompressionTypeToString(header->compressed); @@ -4858,7 +4867,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, virReportError(VIR_ERR_OPERATION_FAILED, _("Invalid compressed save format %d"), header->compressed); - goto out; + goto cleanup; } if (header->compressed != QEMU_SAVE_FORMAT_RAW) { @@ -4876,7 +4885,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, _("Failed to start decompression binary %s"), prog); *fd = intermediatefd; - goto out; + goto cleanup; } } } @@ -4911,7 +4920,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, if (ret < 0) { virDomainAuditStart(vm, "restored", false); - goto out; + goto cleanup; } event = virDomainEventNewFromObj(vm, @@ -4930,11 +4939,11 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, if (virGetLastError() == NULL) virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to resume domain")); - goto out; + goto cleanup; } - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Failed to save status on vm %s", vm->def->name); - goto out; + goto cleanup; } } else { int detail = (start_paused ? VIR_DOMAIN_EVENT_SUSPENDED_PAUSED : @@ -4948,12 +4957,13 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, ret = 0; -out: +cleanup: virCommandFree(cmd); VIR_FREE(errbuf); if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager, vm->def, path) < 0) VIR_WARN("failed to restore save state label on %s", path); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -4972,6 +4982,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, virQEMUSaveHeader header; virFileWrapperFdPtr wrapperFd = NULL; int state = -1; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE | VIR_DOMAIN_SAVE_RUNNING | @@ -4984,6 +4995,9 @@ qemuDomainRestoreFlags(virConnectPtr conn, else if (flags & VIR_DOMAIN_SAVE_PAUSED) state = 0; + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + fd = qemuDomainSaveImageOpen(driver, path, &def, &header, (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, &wrapperFd, dxml, state, false, false); @@ -4991,7 +5005,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, goto cleanup; if (!(vm = virDomainObjListAdd(driver->domains, - driver->caps, + caps, def, VIR_DOMAIN_OBJ_LIST_ADD_LIVE | VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, @@ -5020,6 +5034,7 @@ cleanup: virFileWrapperFdFree(wrapperFd); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -5268,6 +5283,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn, virQEMUDriverPtr driver = conn->privateData; virDomainDefPtr def = NULL; char *xml = NULL; + virCapsPtr caps = NULL; virCheckFlags(0, NULL); @@ -5278,7 +5294,11 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn, } qemuDriverLock(driver); - def = qemuParseCommandLineString(driver->caps, config, + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + def = qemuParseCommandLineString(caps, config, NULL, NULL, NULL); qemuDriverUnlock(driver); if (!def) @@ -5294,6 +5314,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn, cleanup: virDomainDefFree(def); + virObjectUnref(caps); return xml; } @@ -5311,6 +5332,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, char *ret = NULL; int i; virQEMUDriverConfigPtr cfg; + virCapsPtr caps = NULL; virCheckFlags(0, NULL); @@ -5323,7 +5345,10 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, goto cleanup; } - def = virDomainDefParseString(driver->caps, xmlData, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + def = virDomainDefParseString(caps, xmlData, QEMU_EXPECTED_VIRT_TYPES, 0); if (!def) goto cleanup; @@ -5424,6 +5449,7 @@ cleanup: virObjectUnref(qemuCaps); virCommandFree(cmd); virDomainDefFree(def); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -5585,17 +5611,22 @@ qemuDomainStart(virDomainPtr dom) static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) { virQEMUDriverPtr driver = conn->privateData; - virDomainDefPtr def; + virDomainDefPtr def = NULL; virDomainDefPtr oldDef = NULL; virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; virDomainEventPtr event = NULL; virQEMUCapsPtr qemuCaps = NULL; virQEMUDriverConfigPtr cfg; + virCapsPtr caps = NULL; qemuDriverLock(driver); cfg = virQEMUDriverGetConfig(driver); - if (!(def = virDomainDefParseString(driver->caps, xml, + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!(def = virDomainDefParseString(caps, xml, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; @@ -5613,7 +5644,7 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) { goto cleanup; if (!(vm = virDomainObjListAdd(driver->domains, - driver->caps, + caps, def, 0, &oldDef))) @@ -5667,6 +5698,7 @@ cleanup: qemuDomainEventQueue(driver, event); virObjectUnref(qemuCaps); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return dom; } @@ -6403,6 +6435,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, virQEMUCapsPtr qemuCaps = NULL; qemuDomainObjPrivatePtr priv; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -6414,6 +6447,9 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, affect = flags & (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG); qemuDriverLock(driver); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + vm = virDomainObjListFindByUUID(driver->domains, dom->uuid); if (!vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; @@ -6448,7 +6484,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, goto endjob; } - dev = dev_copy = virDomainDeviceDefParse(driver->caps, vm->def, xml, + dev = dev_copy = virDomainDeviceDefParse(caps, vm->def, xml, VIR_DOMAIN_XML_INACTIVE); if (dev == NULL) goto endjob; @@ -6459,7 +6495,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, * create a deep copy of device as adding * to CONFIG takes one instance. */ - dev_copy = virDomainDeviceDefCopy(driver->caps, vm->def, dev); + dev_copy = virDomainDeviceDefCopy(caps, vm->def, dev); if (!dev_copy) goto endjob; } @@ -6474,7 +6510,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, goto endjob; /* Make a copy for updated domain. */ - vmdef = virDomainObjCopyPersistentDef(driver->caps, vm); + vmdef = virDomainObjCopyPersistentDef(caps, vm); if (!vmdef) goto endjob; switch (action) { @@ -6525,7 +6561,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, * changed even if we failed to attach the device. For example, * a new controller may be created. */ - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { ret = -1; goto endjob; } @@ -6553,6 +6589,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -6884,6 +6921,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, virDomainDefPtr persistentDef = NULL; int ret = -1; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -6903,8 +6941,10 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, goto cleanup; } cfg = virQEMUDriverGetConfig(driver); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7022,6 +7062,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -7040,6 +7081,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, unsigned int val; int ret = -1; int rc; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -7059,6 +7101,9 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, goto cleanup; } + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if ((*nparams) == 0) { /* Current number of blkio parameters supported by cgroups */ *nparams = QEMU_NB_BLKIO_PARAM; @@ -7066,7 +7111,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, goto cleanup; } - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7208,6 +7253,7 @@ cleanup: virCgroupFree(&group); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -7231,6 +7277,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, virQEMUDriverConfigPtr cfg = NULL; int ret = -1; int rc; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -7257,7 +7304,10 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, cfg = virQEMUDriverGetConfig(driver); - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7380,6 +7430,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -7397,6 +7448,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom, virDomainDefPtr persistentDef = NULL; int ret = -1; int rc; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -7415,7 +7467,10 @@ qemuDomainGetMemoryParameters(virDomainPtr dom, goto cleanup; } - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7540,6 +7595,7 @@ cleanup: virCgroupFree(&group); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -7557,6 +7613,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom, virDomainObjPtr vm = NULL; int ret = -1; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -7579,7 +7636,10 @@ qemuDomainSetNumaParameters(virDomainPtr dom, } cfg = virQEMUDriverGetConfig(driver); - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7692,6 +7752,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -7710,6 +7771,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom, char *nodeset = NULL; int ret = -1; int rc; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -7730,7 +7792,10 @@ qemuDomainGetNumaParameters(virDomainPtr dom, goto cleanup; } - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7805,6 +7870,7 @@ cleanup: virCgroupFree(&group); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -7909,6 +7975,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, int ret = -1; int rc; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -7938,13 +8005,16 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, cfg = virQEMUDriverGetConfig(driver); - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &vmdef) < 0) goto cleanup; if (flags & VIR_DOMAIN_AFFECT_CONFIG) { /* Make a copy for updated domain. */ - vmdef = virDomainObjCopyPersistentDef(driver->caps, vm); + vmdef = virDomainObjCopyPersistentDef(caps, vm); if (!vmdef) goto cleanup; } @@ -8039,7 +8109,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, } } - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto cleanup; @@ -8060,6 +8130,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -8197,6 +8268,7 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, bool cpu_bw_status = false; int saved_nparams = 0; virDomainDefPtr persistentDef; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -8222,7 +8294,10 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; } - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -8319,6 +8394,7 @@ cleanup: virCgroupFree(&group); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -8725,6 +8801,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, virDomainNetDefPtr net = NULL, persistentNet = NULL; virNetDevBandwidthPtr bandwidth = NULL, newBandwidth = NULL; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -8755,7 +8832,10 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, cfg = virQEMUDriverGetConfig(driver); - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -8883,6 +8963,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -8902,6 +8983,7 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom, virDomainDefPtr persistentDef = NULL; virDomainNetDefPtr net = NULL; int ret = -1; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -8919,7 +9001,10 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom, goto cleanup; } - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -9005,6 +9090,7 @@ cleanup: virCgroupFree(&group); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -10138,24 +10224,26 @@ qemuCPUCompare(virConnectPtr conn, { virQEMUDriverPtr driver = conn->privateData; int ret = VIR_CPU_COMPARE_ERROR; + virCapsPtr caps = NULL; virCheckFlags(0, VIR_CPU_COMPARE_ERROR); qemuDriverLock(driver); - if (!driver->caps) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot get host capabilities")); - } else if (!driver->caps->host.cpu || - !driver->caps->host.cpu->model) { + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!caps->host.cpu || + !caps->host.cpu->model) { VIR_WARN("cannot get host CPU capabilities"); ret = VIR_CPU_COMPARE_INCOMPATIBLE; } else { - ret = cpuCompareXML(driver->caps->host.cpu, xmlDesc); + ret = cpuCompareXML(caps->host.cpu, xmlDesc); } +cleanup: + virObjectUnref(caps); qemuDriverUnlock(driver); - return ret; } @@ -11019,6 +11107,10 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0; virCgroupPtr cgroup = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_OPERATION_INVALID, @@ -11113,10 +11205,11 @@ cleanup: virCgroupFree(&cgroup); if (ret == 0 || !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) { - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0 || + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0 || (persist && virDomainSaveConfig(cfg->configDir, vm->newDef) < 0)) ret = -1; } + virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -11322,6 +11415,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL; int align_match = true; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE | VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT | @@ -11358,6 +11452,9 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, cfg = virQEMUDriverGetConfig(driver); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if (qemuProcessAutoDestroyActive(driver, vm)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is marked for auto destroy")); @@ -11378,7 +11475,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, !virDomainObjIsActive(vm)) parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE; - if (!(def = virDomainSnapshotDefParseString(xmlDesc, driver->caps, + if (!(def = virDomainSnapshotDefParseString(xmlDesc, caps, QEMU_EXPECTED_VIRT_TYPES, parse_flags))) goto cleanup; @@ -11554,7 +11651,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, /* Easiest way to clone inactive portion of vm->def is via * conversion in and back out of xml. */ if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) || - !(def->dom = virDomainDefParseString(driver->caps, xml, + !(def->dom = virDomainDefParseString(caps, xml, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; @@ -11680,6 +11777,7 @@ cleanup: virDomainSnapshotDefFree(def); VIR_FREE(xml); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return snapshot; } @@ -12031,6 +12129,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, int rc; virDomainDefPtr config = NULL; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING | VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED | @@ -12061,6 +12160,9 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, cfg = virQEMUDriverGetConfig(driver); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if (virDomainHasDiskMirror(vm)) { virReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s", _("domain has active block copy job")); @@ -12122,7 +12224,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, * than inactive xml? */ snap->def->current = true; if (snap->def->dom) { - config = virDomainDefCopy(driver->caps, snap->def->dom, true); + config = virDomainDefCopy(caps, snap->def->dom, true); if (!config) goto cleanup; } @@ -12350,6 +12452,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -12577,12 +12680,16 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, pid_t pid = pid_value; char *pidfile = NULL; virQEMUCapsPtr qemuCaps = NULL; + virCapsPtr caps = NULL; virCheckFlags(0, NULL); qemuDriverLock(driver); - if (!(def = qemuParseCommandLinePid(driver->caps, pid, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!(def = qemuParseCommandLinePid(caps, pid, &pidfile, &monConfig, &monJSON))) goto cleanup; @@ -12616,7 +12723,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, goto cleanup; if (!(vm = virDomainObjListAdd(driver->domains, - driver->caps, + caps, def, VIR_DOMAIN_OBJ_LIST_ADD_LIVE | VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, @@ -12653,6 +12760,7 @@ cleanup: virObjectUnlock(vm); qemuDriverUnlock(driver); VIR_FREE(pidfile); + virObjectUnref(caps); return dom; } @@ -13652,6 +13760,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, bool set_bytes = false; bool set_iops = false; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -13684,6 +13793,9 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, priv = vm->privateData; cfg = virQEMUDriverGetConfig(driver); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("block I/O throttling not supported with this " @@ -13699,7 +13811,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto endjob; @@ -13803,6 +13915,7 @@ cleanup: if (vm) virObjectUnlock(vm); qemuDriverUnlock(driver); + virObjectUnref(caps); virObjectUnref(cfg); return ret; } @@ -13823,6 +13936,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, const char *device = NULL; int ret = -1; int i; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -13840,6 +13954,9 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, goto cleanup; } + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if ((*nparams) == 0) { /* Current number of parameters supported by QEMU Block I/O Throttling */ *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; @@ -13856,7 +13973,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto endjob; @@ -13939,6 +14056,7 @@ cleanup: VIR_FREE(device); if (vm) virObjectUnlock(vm); + virObjectUnref(caps); qemuDriverUnlock(driver); return ret; } @@ -14032,6 +14150,7 @@ qemuDomainSetMetadata(virDomainPtr dom, virDomainDefPtr persistentDef; int ret = -1; virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -14041,7 +14160,10 @@ qemuDomainSetMetadata(virDomainPtr dom, cfg = virQEMUDriverGetConfig(driver); - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -14108,6 +14230,7 @@ qemuDomainSetMetadata(virDomainPtr dom, cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); virObjectUnref(cfg); return ret; no_memory: @@ -14126,6 +14249,7 @@ qemuDomainGetMetadata(virDomainPtr dom, virDomainDefPtr def; char *ret = NULL; char *field = NULL; + virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, NULL); @@ -14133,7 +14257,10 @@ qemuDomainGetMetadata(virDomainPtr dom, if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; - if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &def) < 0) + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &def) < 0) goto cleanup; /* use correct domain definition according to flags */ @@ -14174,6 +14301,7 @@ qemuDomainGetMetadata(virDomainPtr dom, cleanup: if (vm) virObjectUnlock(vm); + virObjectUnref(caps); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 82d269924a..815f7a5cb6 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -742,9 +742,13 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, unsigned int flags) { char uuidstr[VIR_UUID_STRING_BUFLEN]; - char *tmp; + char *tmp = NULL; xmlNodePtr *nodes = NULL; int i, n; + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto error; /* We don't store the uuid, name, hostname, or hostuuid * values. We just compare them to local data to do some @@ -870,7 +874,7 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, n); goto error; } - mig->persistent = virDomainDefParseNode(driver->caps, doc, nodes[0], + mig->persistent = virDomainDefParseNode(caps, doc, nodes[0], -1, VIR_DOMAIN_XML_INACTIVE); if (!mig->persistent) { /* virDomainDefParseNode already reported @@ -885,11 +889,13 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, (!(mig->network = qemuMigrationCookieNetworkXMLParse(ctxt)))) goto error; + virObjectUnref(caps); return 0; error: VIR_FREE(tmp); VIR_FREE(nodes); + virObjectUnref(caps); return -1; } @@ -1434,12 +1440,16 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver, qemuMigrationCookiePtr mig = NULL; virDomainDefPtr def = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; + virCapsPtr caps = NULL; VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s," " cookieout=%p, cookieoutlen=%p, flags=%lx", driver, vm, NULLSTR(xmlin), NULLSTR(dname), cookieout, cookieoutlen, flags); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + /* Only set the phase if we are inside QEMU_ASYNC_JOB_MIGRATION_OUT. * Otherwise we will start the async job later in the perform phase losing * change protection. @@ -1484,7 +1494,7 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver, } if (xmlin) { - if (!(def = virDomainDefParseString(driver->caps, xmlin, + if (!(def = virDomainDefParseString(caps, xmlin, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; @@ -1505,6 +1515,7 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver, cleanup: qemuMigrationCookieFree(mig); + virObjectUnref(caps); virDomainDefFree(def); return rv; } @@ -1555,6 +1566,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, char *origname = NULL; char *xmlout = NULL; unsigned int cookieFlags; + virCapsPtr caps = NULL; if (virTimeMillisNow(&now) < 0) return -1; @@ -1581,7 +1593,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, } } - if (!(def = virDomainDefParseString(driver->caps, dom_xml, + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!(def = virDomainDefParseString(caps, dom_xml, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; @@ -1622,7 +1637,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, virDomainDefPtr newdef; VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout); - newdef = virDomainDefParseString(driver->caps, xmlout, + newdef = virDomainDefParseString(caps, xmlout, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE); if (!newdef) @@ -1640,7 +1655,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, } if (!(vm = virDomainObjListAdd(driver->domains, - driver->caps, + caps, def, VIR_DOMAIN_OBJ_LIST_ADD_LIVE | VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, @@ -1760,6 +1775,7 @@ cleanup: if (event) qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); + virObjectUnref(caps); return ret; endjob: @@ -3323,12 +3339,16 @@ qemuMigrationFinish(virQEMUDriverPtr driver, int cookie_flags = 0; qemuDomainObjPrivatePtr priv = vm->privateData; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, " "cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d", driver, dconn, vm, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, flags, retcode); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN)) goto cleanup; @@ -3379,7 +3399,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver, if (mig->persistent) vm->newDef = vmdef = mig->persistent; else - vmdef = virDomainObjGetPersistentDef(driver->caps, vm); + vmdef = virDomainObjGetPersistentDef(caps, vm); if (!vmdef || virDomainSaveConfig(cfg->configDir, vmdef) < 0) { /* Hmpf. Migration was successful, but making it persistent * was not. If we report successful, then when this domain @@ -3474,7 +3494,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver, } if (virDomainObjIsActive(vm) && - virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Failed to save status on vm %s", vm->def->name); goto endjob; } @@ -3513,6 +3533,7 @@ cleanup: virSetError(orig_err); virFreeError(orig_err); } + virObjectUnref(caps); virObjectUnref(cfg); return dom; } @@ -3530,6 +3551,7 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver, virDomainEventPtr event = NULL; int rv = -1; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; VIR_DEBUG("driver=%p, conn=%p, vm=%p, cookiein=%s, cookieinlen=%d, " "flags=%x, retcode=%d", @@ -3538,6 +3560,9 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver, virCheckFlags(QEMU_MIGRATION_FLAGS, -1); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + qemuMigrationJobSetPhase(driver, vm, retcode == 0 ? QEMU_MIGRATION_PHASE_CONFIRM3 @@ -3578,7 +3603,7 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver, event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_MIGRATED); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Failed to save status on vm %s", vm->def->name); goto cleanup; } @@ -3591,6 +3616,7 @@ done: cleanup: if (event) qemuDomainEventQueue(driver, event); + virObjectUnref(caps); virObjectUnref(cfg); return rv; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8e7c09cb31..abbee5e890 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -660,9 +660,13 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuDomainObjPrivatePtr priv; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; VIR_DEBUG("vm=%p", vm); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + virObjectLock(vm); priv = vm->privateData; @@ -686,7 +690,7 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_DOMAIN_EVENT_SHUTDOWN, VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after state change", vm->def->name); } @@ -698,12 +702,13 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED, unlock: virObjectUnlock(vm); - +cleanup: if (event) { qemuDriverLock(driver); qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); } + virObjectUnref(caps); virObjectUnref(cfg); return 0; @@ -717,6 +722,10 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virQEMUDriverPtr driver = qemu_driver; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { @@ -740,7 +749,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_WARN("Unable to release lease on %s", vm->def->name); VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after state change", vm->def->name); } @@ -749,11 +758,13 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, unlock: virObjectUnlock(vm); +cleanup: if (event) { qemuDriverLock(driver); qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); } + virObjectUnref(caps); virObjectUnref(cfg); return 0; @@ -767,6 +778,10 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virQEMUDriverPtr driver = qemu_driver; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { @@ -797,7 +812,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, } VIR_FREE(priv->lockState); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after state change", vm->def->name); } @@ -805,12 +820,13 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, unlock: virObjectUnlock(vm); - +cleanup: if (event) { qemuDriverLock(driver); qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); } + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -822,8 +838,12 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, long long offset) { virQEMUDriverPtr driver = qemu_driver; - virDomainEventPtr event; + virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); event = virDomainEventRTCChangeNewFromObj(vm, offset); @@ -831,17 +851,18 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) vm->def->clock.data.variable.adjustment = offset; - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) VIR_WARN("unable to save domain status with RTC change"); virObjectUnlock(vm); +cleanup: if (event) { qemuDriverLock(driver); qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); } - + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -856,6 +877,10 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainEventPtr watchdogEvent = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action); @@ -875,7 +900,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_WARN("Unable to release lease on %s", vm->def->name); VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after watchdog event", vm->def->name); } @@ -903,6 +928,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, if (vm) virObjectUnlock(vm); +cleanup: if (watchdogEvent || lifecycleEvent) { qemuDriverLock(driver); if (watchdogEvent) @@ -912,6 +938,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuDriverUnlock(driver); } + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -932,6 +959,10 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, const char *devAlias; virDomainDiskDefPtr disk; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias); @@ -962,11 +993,12 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_WARN("Unable to release lease on %s", vm->def->name); VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name); } virObjectUnlock(vm); +cleanup: if (ioErrorEvent || ioErrorEvent2 || lifecycleEvent) { qemuDriverLock(driver); if (ioErrorEvent) @@ -977,7 +1009,7 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuDomainEventQueue(driver, lifecycleEvent); qemuDriverUnlock(driver); } - + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -1134,6 +1166,10 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainEventPtr event = NULL; virDomainDiskDefPtr disk; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); disk = qemuProcessFindDomainDiskByAlias(vm, devAlias); @@ -1148,19 +1184,20 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE) disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED; - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after tray moved event", vm->def->name); } } virObjectUnlock(vm); - +cleanup: if (event) { qemuDriverLock(driver); qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); } + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -1173,6 +1210,10 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainEventPtr event = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); event = virDomainEventPMWakeupNewFromObj(vm); @@ -1190,7 +1231,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_WAKEUP); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after wakeup event", vm->def->name); } @@ -1198,6 +1239,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virObjectUnlock(vm); +cleanup: if (event || lifecycleEvent) { qemuDriverLock(driver); if (event) @@ -1206,7 +1248,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuDomainEventQueue(driver, lifecycleEvent); qemuDriverUnlock(driver); } - + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -1219,6 +1261,10 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainEventPtr event = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); event = virDomainEventPMSuspendNewFromObj(vm); @@ -1235,7 +1281,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_DOMAIN_EVENT_PMSUSPENDED, VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after suspend event", vm->def->name); } @@ -1246,6 +1292,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virObjectUnlock(vm); +cleanup: if (event || lifecycleEvent) { qemuDriverLock(driver); if (event) @@ -1254,6 +1301,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuDomainEventQueue(driver, lifecycleEvent); qemuDriverUnlock(driver); } + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -1264,8 +1312,12 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, unsigned long long actual) { virQEMUDriverPtr driver = qemu_driver; - virDomainEventPtr event; + virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); event = virDomainEventBalloonChangeNewFromObj(vm, actual); @@ -1274,17 +1326,18 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, vm->def->mem.cur_balloon, actual); vm->def->mem.cur_balloon = actual; - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) VIR_WARN("unable to save domain status with balloon change"); virObjectUnlock(vm); +cleanup: if (event) { qemuDriverLock(driver); qemuDomainEventQueue(driver, event); qemuDriverUnlock(driver); } - + virObjectUnref(caps); virObjectUnref(cfg); return 0; } @@ -1297,6 +1350,10 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainEventPtr event = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; virObjectLock(vm); event = virDomainEventPMSuspendDiskNewFromObj(vm); @@ -1313,7 +1370,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_DOMAIN_EVENT_PMSUSPENDED, VIR_DOMAIN_EVENT_PMSUSPENDED_DISK); - if (virDomainSaveStatus(driver->caps,cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { VIR_WARN("Unable to save status on vm %s after suspend event", vm->def->name); } @@ -1324,6 +1381,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virObjectUnlock(vm); +cleanup: if (event || lifecycleEvent) { qemuDriverLock(driver); if (event) @@ -1332,7 +1390,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuDomainEventQueue(driver, lifecycleEvent); qemuDriverUnlock(driver); } - + virObjectUnref(caps); virObjectUnref(cfg); return 0; @@ -2029,6 +2087,7 @@ qemuPrepareCpumap(virQEMUDriverPtr driver, { int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN; virBitmapPtr cpumap = NULL; + virCapsPtr caps = NULL; /* setaffinity fails if you set bits for CPUs which * aren't present, so we have to limit ourselves */ @@ -2044,24 +2103,33 @@ qemuPrepareCpumap(virQEMUDriverPtr driver, } if (nodemask) { - for (i = 0; i < driver->caps->host.nnumaCell; i++) { + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) { + virBitmapFree(cpumap); + cpumap = NULL; + goto cleanup; + } + + for (i = 0; i < caps->host.nnumaCell; i++) { int j; - int cur_ncpus = driver->caps->host.numaCell[i]->ncpus; + int cur_ncpus = caps->host.numaCell[i]->ncpus; bool result; if (virBitmapGetBit(nodemask, i, &result) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to convert nodeset to cpuset")); virBitmapFree(cpumap); - return NULL; + cpumap = NULL; + goto cleanup; } if (result) { for (j = 0; j < cur_ncpus; j++) ignore_value(virBitmapSetBit(cpumap, - driver->caps->host.numaCell[i]->cpus[j].id)); + caps->host.numaCell[i]->cpus[j].id)); } } } +cleanup: + virObjectUnref(caps); return cpumap; } @@ -3185,6 +3253,7 @@ qemuProcessReconnect(void *opaque) int state; int reason; virQEMUDriverConfigPtr cfg; + virCapsPtr caps = NULL; memcpy(&oldjob, &data->oldjob, sizeof(oldjob)); @@ -3205,6 +3274,9 @@ qemuProcessReconnect(void *opaque) * deleted if qemuConnectMonitor() failed */ virObjectRef(obj); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto error; + /* XXX check PID liveliness & EXE path */ if (qemuConnectMonitor(driver, obj) < 0) goto error; @@ -3275,7 +3347,7 @@ qemuProcessReconnect(void *opaque) goto error; /* update domain state XML with possibly updated state in virDomainObj */ - if (virDomainSaveStatus(driver->caps, cfg->stateDir, obj) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, obj) < 0) goto error; /* Run an hook to allow admins to do some magic */ @@ -3310,6 +3382,7 @@ endjob: virConnectClose(conn); virObjectUnref(cfg); + virObjectUnref(caps); return; @@ -3348,8 +3421,8 @@ error: } } qemuDriverUnlock(driver); - virConnectClose(conn); + virObjectUnref(caps); virObjectUnref(cfg); } @@ -3550,6 +3623,7 @@ int qemuProcessStart(virConnectPtr conn, virBitmapPtr nodemask = NULL; unsigned int stop_flags; virQEMUDriverConfigPtr cfg; + virCapsPtr caps = NULL; /* Okay, these are just internal flags, * but doesn't hurt to check */ @@ -3578,12 +3652,15 @@ int qemuProcessStart(virConnectPtr conn, return -1; } + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + /* Do this upfront, so any part of the startup process can add * runtime state to vm->def that won't be persisted. This let's us * report implicit runtime defaults in the XML, like vnc listen/socket */ VIR_DEBUG("Setting current domain def as transient"); - if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0) + if (virDomainObjSetDefTransient(caps, vm, true) < 0) goto cleanup; vm->def->id = qemuDriverAllocateID(driver); @@ -3925,7 +4002,7 @@ int qemuProcessStart(virConnectPtr conn, } VIR_DEBUG("Writing early domain status to disk"); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) { + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) { goto cleanup; } @@ -4076,7 +4153,7 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; VIR_DEBUG("Writing domain status to disk"); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto cleanup; /* finally we can call the 'started' hook script if any */ @@ -4099,6 +4176,7 @@ int qemuProcessStart(virConnectPtr conn, virCommandFree(cmd); VIR_FORCE_CLOSE(logfile); virObjectUnref(cfg); + virObjectUnref(caps); return 0; @@ -4112,6 +4190,7 @@ cleanup: VIR_FORCE_CLOSE(logfile); qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags); virObjectUnref(cfg); + virObjectUnref(caps); return -1; } @@ -4420,6 +4499,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, virSecurityManagerPtr* sec_managers = NULL; const char *model; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virCapsPtr caps = NULL; VIR_DEBUG("Beginning VM attach process"); @@ -4430,12 +4510,15 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, return -1; } + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + /* Do this upfront, so any part of the startup process can add * runtime state to vm->def that won't be persisted. This let's us * report implicit runtime defaults in the XML, like vnc listen/socket */ VIR_DEBUG("Setting current domain def as transient"); - if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0) + if (virDomainObjSetDefTransient(caps, vm, true) < 0) goto cleanup; vm->def->id = qemuDriverAllocateID(driver); @@ -4580,7 +4663,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason); VIR_DEBUG("Writing domain status to disk"); - if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) + if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) goto cleanup; /* Run an hook to allow admins to do some magic */ @@ -4604,6 +4687,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, VIR_FREE(seclabel); VIR_FREE(sec_managers); virObjectUnref(cfg); + virObjectUnref(caps); return 0; @@ -4618,6 +4702,7 @@ cleanup: VIR_FREE(sec_managers); virDomainChrSourceDefFree(monConfig); virObjectUnref(cfg); + virObjectUnref(caps); return -1; }