Stop accessing driver->caps directly in QEMU driver

The 'driver->caps' pointer can be changed on the fly. Accessing
it currently requires the global driver lock. Isolate this
access in a single helper, so a future patch can relax the
locking constraints.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2013-02-01 17:04:15 +00:00
parent 32803ba409
commit 020a030786
7 changed files with 571 additions and 204 deletions

View File

@ -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:

View File

@ -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)

View File

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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

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

View File

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