There is one problem that causes various errors in the daemon. When domain is waiting for a job, it is unlocked while waiting on the condition. However, if that domain is for example transient and being removed in another API (e.g. cancelling incoming migration), it get's unref'd. If the first call, that was waiting, fails to get the job, it unref's the domain object, and because it was the last reference, it causes clearing of the whole domain object. However, when finishing the call, the domain must be unlocked, but there is no way for the API to know whether it was cleaned or not (unless there is some ugly temporary variable, but let's scratch that). The root cause is that our APIs don't ref the objects they are using and all use the implicit reference that the object has when it is in the domain list. That reference can be removed when the API is waiting for a job. And because each domain doesn't do its ref'ing, it results in the ugly checking of the return value of virObjectUnref() that we have everywhere. This patch changes qemuDomObjFromDomain() to ref the domain (using virDomainObjListFindByUUIDRef()) and adds qemuDomObjEndAPI() which should be the only function in which the return value of virObjectUnref() is checked. This makes all reference counting deterministic and makes the code a bit clearer. Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx> --- v2: - Comments from Peter and Daniel on v1 implemented, rather not listing them here as the list was pretty comprehensive and it would make the reviewer focus on that. src/qemu/THREADS.txt | 40 ++- src/qemu/qemu_domain.c | 49 ++-- src/qemu/qemu_domain.h | 12 +- src/qemu/qemu_driver.c | 708 ++++++++++++++++------------------------------ src/qemu/qemu_migration.c | 111 +++----- src/qemu/qemu_migration.h | 10 +- src/qemu/qemu_process.c | 77 ++--- 7 files changed, 371 insertions(+), 636 deletions(-) diff --git a/src/qemu/THREADS.txt b/src/qemu/THREADS.txt index 50a0cf9..add2a35 100644 --- a/src/qemu/THREADS.txt +++ b/src/qemu/THREADS.txt @@ -26,12 +26,20 @@ There are a number of locks on various objects * virDomainObjPtr Will be locked after calling any of the virDomainFindBy{ID,Name,UUID} - methods. + methods. However, preferred method is qemuDomObjFromDomain() that uses + virDomainFindByUUIDRef() which also increases the reference counter and + finds the domain in the domain list without blocking all other lookups. + When the domain is locked and the reference increased, the prefered way of + decrementing the reference counter and unlocking the domain is using the + qemuDomObjEndAPI() function. Lock must be held when changing/reading any variable in the virDomainObjPtr If the lock needs to be dropped & then re-acquired for a short period of time, the reference count must be incremented first using virDomainObjRef(). + There is no need to increase the reference count if qemuDomObjFromDomain() + was used for looking up the domain. In this case there is one reference + already added by that function. This lock must not be held for anything which sleeps/waits (i.e. monitor commands). @@ -109,7 +117,6 @@ To lock the virDomainObjPtr To acquire the normal job condition qemuDomainObjBeginJob() - - Increments ref count on virDomainObjPtr - Waits until the job is compatible with current async job or no async job is running - Waits for job.cond condition 'job.active != 0' using virDomainObjPtr @@ -122,14 +129,12 @@ To acquire the normal job condition qemuDomainObjEndJob() - Sets job.active to 0 - Signals on job.cond condition - - Decrements ref count on virDomainObjPtr To acquire the asynchronous job condition qemuDomainObjBeginAsyncJob() - - Increments ref count on virDomainObjPtr - Waits until no async job is running - Waits for job.cond condition 'job.active != 0' using virDomainObjPtr mutex @@ -141,7 +146,6 @@ To acquire the asynchronous job condition qemuDomainObjEndAsyncJob() - Sets job.asyncJob to 0 - Broadcasts on job.asyncCond condition - - Decrements ref count on virDomainObjPtr @@ -179,12 +183,10 @@ To acquire the QEMU monitor lock as part of an asynchronous job To keep a domain alive while waiting on a remote command qemuDomainObjEnterRemote() - - Increments ref count on virDomainObjPtr - Releases the virDomainObjPtr lock qemuDomainObjExitRemote() - Acquires the virDomainObjPtr lock - - Decrements ref count on virDomainObjPtr Design patterns @@ -195,18 +197,18 @@ Design patterns virDomainObjPtr obj; - obj = virDomainFindByUUID(driver->domains, dom->uuid); + obj = qemuDomObjFromDomain(dom); ...do work... - virDomainObjUnlock(obj); + qemuDomObjEndAPI(&obj); * Updating something directly to do with a virDomainObjPtr virDomainObjPtr obj; - obj = virDomainFindByUUID(driver->domains, dom->uuid); + obj = qemuDomObjFromDomain(dom); qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE); @@ -214,18 +216,15 @@ Design patterns qemuDomainObjEndJob(obj); - virDomainObjUnlock(obj); - - + qemuDomObjEndAPI(&obj); * Invoking a monitor command on a virDomainObjPtr - virDomainObjPtr obj; qemuDomainObjPrivatePtr priv; - obj = virDomainFindByUUID(driver->domains, dom->uuid); + obj = qemuDomObjFromDomain(dom); qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE); @@ -240,8 +239,7 @@ Design patterns ...do final work... qemuDomainObjEndJob(obj); - virDomainObjUnlock(obj); - + qemuDomObjEndAPI(&obj); * Running asynchronous job @@ -249,7 +247,7 @@ Design patterns virDomainObjPtr obj; qemuDomainObjPrivatePtr priv; - obj = virDomainFindByUUID(driver->domains, dom->uuid); + obj = qemuDomObjFromDomain(dom); qemuDomainObjBeginAsyncJob(obj, QEMU_ASYNC_JOB_TYPE); qemuDomainObjSetAsyncJobMask(obj, allowedJobs); @@ -281,7 +279,7 @@ Design patterns ...do final work... qemuDomainObjEndAsyncJob(obj); - virDomainObjUnlock(obj); + qemuDomObjEndAPI(&obj); * Coordinating with a remote server for migration @@ -289,7 +287,7 @@ Design patterns virDomainObjPtr obj; qemuDomainObjPrivatePtr priv; - obj = virDomainFindByUUID(driver->domains, dom->uuid); + obj = qemuDomObjFromDomain(dom); qemuDomainObjBeginAsyncJob(obj, QEMU_ASYNC_JOB_TYPE); @@ -309,4 +307,4 @@ Design patterns ...do final work... qemuDomainObjEndAsyncJob(obj); - virDomainObjUnlock(obj); + qemuDomObjEndAPI(&obj); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 220304f..46a844f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1318,8 +1318,6 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver, priv->jobs_queued++; then = now + QEMU_JOB_WAIT_TIME; - virObjectRef(obj); - retry: if (cfg->maxQueuedJobs && priv->jobs_queued > cfg->maxQueuedJobs) { @@ -1398,7 +1396,6 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver, cleanup: priv->jobs_queued--; - virObjectUnref(obj); virObjectUnref(cfg); return ret; } @@ -1409,8 +1406,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver, * This must be called by anything that will change the VM state * in any way, or anything that will use the QEMU monitor. * - * Upon successful return, the object will have its ref count increased, - * successful calls must be followed by EndJob eventually + * Successful calls must be followed by EndJob eventually */ int qemuDomainObjBeginJob(virQEMUDriverPtr driver, virDomainObjPtr obj, @@ -1459,15 +1455,13 @@ qemuDomainObjBeginNestedJob(virQEMUDriverPtr driver, /* - * obj must be locked before calling + * obj must be locked and have a reference before calling * * To be called after completing the work associated with the * earlier qemuDomainBeginJob() call - * - * Returns true if @obj was still referenced, false if it was - * disposed of. */ -bool qemuDomainObjEndJob(virQEMUDriverPtr driver, virDomainObjPtr obj) +void +qemuDomainObjEndJob(virQEMUDriverPtr driver, virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj->privateData; qemuDomainJob job = priv->job.active; @@ -1483,11 +1477,9 @@ bool qemuDomainObjEndJob(virQEMUDriverPtr driver, virDomainObjPtr obj) if (qemuDomainTrackJob(job)) qemuDomainObjSaveJob(driver, obj); virCondSignal(&priv->job.cond); - - return virObjectUnref(obj); } -bool +void qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj->privateData; @@ -1501,8 +1493,6 @@ qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj) qemuDomainObjResetAsyncJob(priv); qemuDomainObjSaveJob(driver, obj); virCondBroadcast(&priv->job.asyncCond); - - return virObjectUnref(obj); } void @@ -1540,8 +1530,7 @@ qemuDomainObjEnterMonitorInternal(virQEMUDriverPtr driver, if (!virDomainObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("domain is no longer running")); - /* Still referenced by the containing async job. */ - ignore_value(qemuDomainObjEndJob(driver, obj)); + qemuDomainObjEndJob(driver, obj); return -1; } } else if (priv->job.asyncOwner == virThreadSelfID()) { @@ -1680,7 +1669,6 @@ void qemuDomainObjEnterRemote(virDomainObjPtr obj) { VIR_DEBUG("Entering remote (vm=%p name=%s)", obj, obj->def->name); - virObjectRef(obj); virObjectUnlock(obj); } @@ -1689,7 +1677,6 @@ void qemuDomainObjExitRemote(virDomainObjPtr obj) virObjectLock(obj); VIR_DEBUG("Exited remote (vm=%p name=%s)", obj, obj->def->name); - virObjectUnref(obj); } @@ -2390,8 +2377,7 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver, } /* - * The caller must hold a lock the vm and there must - * be no remaining references to vm. + * The caller must hold a lock the vm. */ void qemuDomainRemoveInactive(virQEMUDriverPtr driver, @@ -2422,7 +2408,7 @@ qemuDomainRemoveInactive(virQEMUDriverPtr driver, virObjectUnref(cfg); if (haveJob) - ignore_value(qemuDomainObjEndJob(driver, vm)); + qemuDomainObjEndJob(driver, vm); } void @@ -2795,3 +2781,22 @@ qemuDomainAgentAvailable(qemuDomainObjPrivatePtr priv, } return true; } + +/* + * Finish working with a domain object in an API. This function + * clears whatever was left of a domain that was gathered using + * qemuDomObjFromDomain(). Currently that means only unlocking and + * decrementing the reference counter of that domain. And in order to + * make sure the caller does not access the domain, the pointer is + * cleared. + */ +void +qemuDomObjEndAPI(virDomainObjPtr *vm) +{ + if (!*vm) + return; + + virObjectUnlock(*vm); + virObjectUnref(*vm); + *vm = NULL; +} diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index efabd82..8b1a1b4 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -225,12 +225,10 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob) ATTRIBUTE_RETURN_CHECK; -bool qemuDomainObjEndJob(virQEMUDriverPtr driver, - virDomainObjPtr obj) - ATTRIBUTE_RETURN_CHECK; -bool qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver, - virDomainObjPtr obj) - ATTRIBUTE_RETURN_CHECK; +void qemuDomainObjEndJob(virQEMUDriverPtr driver, + virDomainObjPtr obj); +void qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver, + virDomainObjPtr obj); void qemuDomainObjAbortAsyncJob(virDomainObjPtr obj); void qemuDomainObjSetJobPhase(virQEMUDriverPtr driver, virDomainObjPtr obj, @@ -411,4 +409,6 @@ int qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); +void qemuDomObjEndAPI(virDomainObjPtr *vm); + #endif /* __QEMU_DOMAIN_H__ */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f652237..30ea9df 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -205,11 +205,11 @@ struct qemuAutostartData { * qemuDomObjFromDomain: * @domain: Domain pointer that has to be looked up * - * This function looks up @domain and returns the appropriate - * virDomainObjPtr. + * This function looks up @domain and returns the appropriate virDomainObjPtr + * that has to be released by calling qemuDomObjEndAPI(). * - * Returns the domain object which is locked on success, NULL - * otherwise. + * Returns the domain object with incremented reference counter which is locked + * on success, NULL otherwise. */ static virDomainObjPtr qemuDomObjFromDomain(virDomainPtr domain) @@ -218,7 +218,7 @@ qemuDomObjFromDomain(virDomainPtr domain) virQEMUDriverPtr driver = domain->conn->privateData; char uuidstr[VIR_UUID_STRING_BUFLEN]; - vm = virDomainObjListFindByUUID(driver->domains, domain->uuid); + vm = virDomainObjListFindByUUIDRef(driver->domains, domain->uuid); if (!vm) { virUUIDFormat(domain->uuid, uuidstr); virReportError(VIR_ERR_NO_DOMAIN, @@ -230,9 +230,9 @@ qemuDomObjFromDomain(virDomainPtr domain) return vm; } -/* Looks up the domain object from snapshot and unlocks the driver. The - * returned domain object is locked and the caller is responsible for - * unlocking it */ +/* Looks up the domain object from snapshot and unlocks the + * driver. The returned domain object is locked and ref'd and the + * caller must call qemuDomObjEndAPI() on it. */ static virDomainObjPtr qemuDomObjFromSnapshot(virDomainSnapshotPtr snapshot) { @@ -278,6 +278,7 @@ qemuAutostartDomain(virDomainObjPtr vm, flags |= VIR_DOMAIN_START_BYPASS_CACHE; virObjectLock(vm); + virObjectRef(vm); virResetLastError(); if (vm->autostart && !virDomainObjIsActive(vm)) { @@ -297,14 +298,12 @@ qemuAutostartDomain(virDomainObjPtr vm, err ? err->message : _("unknown error")); } - if (!qemuDomainObjEndJob(data->driver, vm)) - vm = NULL; + qemuDomainObjEndJob(data->driver, vm); } ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -1473,7 +1472,7 @@ static virDomainPtr qemuDomainLookupByUUID(virConnectPtr conn, virDomainObjPtr vm; virDomainPtr dom = NULL; - vm = virDomainObjListFindByUUID(driver->domains, uuid); + vm = virDomainObjListFindByUUIDRef(driver->domains, uuid); if (!vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; @@ -1490,8 +1489,7 @@ static virDomainPtr qemuDomainLookupByUUID(virConnectPtr conn, if (dom) dom->id = vm->def->id; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return dom; } @@ -1517,8 +1515,7 @@ static virDomainPtr qemuDomainLookupByName(virConnectPtr conn, if (dom) dom->id = vm->def->id; cleanup: - if (vm) - virObjectUnlock(vm); + virObjectUnlock(vm); return dom; } @@ -1537,8 +1534,7 @@ static int qemuDomainIsActive(virDomainPtr dom) ret = virDomainObjIsActive(obj); cleanup: - if (obj) - virObjectUnlock(obj); + qemuDomObjEndAPI(&obj); return ret; } @@ -1556,8 +1552,7 @@ static int qemuDomainIsPersistent(virDomainPtr dom) ret = obj->persistent; cleanup: - if (obj) - virObjectUnlock(obj); + qemuDomObjEndAPI(&obj); return ret; } @@ -1575,8 +1570,7 @@ static int qemuDomainIsUpdated(virDomainPtr dom) ret = obj->updated; cleanup: - if (obj) - virObjectUnlock(obj); + qemuDomObjEndAPI(&obj); return ret; } @@ -1717,12 +1711,11 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn, VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL))) goto cleanup; - + virObjectRef(vm); def = NULL; if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) { qemuDomainRemoveInactive(driver, vm); - vm = NULL; goto cleanup; } @@ -1731,9 +1724,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags) < 0) { virDomainAuditStart(vm, "booted", false); - if (qemuDomainObjEndJob(driver, vm)) - qemuDomainRemoveInactive(driver, vm); - vm = NULL; + qemuDomainObjEndJob(driver, vm); + qemuDomainRemoveInactive(driver, vm); goto cleanup; } @@ -1756,13 +1748,11 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn, if (dom) dom->id = vm->def->id; - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virDomainDefFree(def); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) { qemuDomainEventQueue(driver, event); if (event2) @@ -1842,12 +1832,10 @@ static int qemuDomainSuspend(virDomainPtr dom) ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); @@ -1905,12 +1893,10 @@ static int qemuDomainResume(virDomainPtr dom) ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); virObjectUnref(cfg); @@ -1994,12 +1980,10 @@ static int qemuDomainShutdownFlags(virDomainPtr dom, unsigned int flags) } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2094,12 +2078,10 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2137,12 +2119,10 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags) priv->fakeReboot = false; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2222,20 +2202,14 @@ qemuDomainDestroyFlags(virDomainPtr dom, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); virDomainAuditStop(vm, "destroyed"); - if (!vm->persistent) { - if (qemuDomainObjEndJob(driver, vm)) - qemuDomainRemoveInactive(driver, vm); - vm = NULL; - } ret = 0; - endjob: - if (vm && !qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); + if (ret == 0 && !vm->persistent) + qemuDomainRemoveInactive(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); return ret; @@ -2260,8 +2234,7 @@ static char *qemuDomainGetOSType(virDomainPtr dom) { ignore_value(VIR_STRDUP(type, vm->def->os.type)); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return type; } @@ -2281,8 +2254,7 @@ qemuDomainGetMaxMemory(virDomainPtr dom) ret = vm->def->mem.max_balloon; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2384,12 +2356,10 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -2464,12 +2434,10 @@ static int qemuDomainSetMemoryStatsPeriod(virDomainPtr dom, int period, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -2512,12 +2480,10 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags) qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2576,12 +2542,10 @@ static int qemuDomainSendKey(virDomainPtr domain, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2632,10 +2596,7 @@ static int qemuDomainGetInfo(virDomainPtr dom, err = qemuMonitorGetBalloonInfo(priv->mon, &balloon); qemuDomainObjExitMonitor(driver, vm); } - if (!qemuDomainObjEndJob(driver, vm)) { - vm = NULL; - goto cleanup; - } + qemuDomainObjEndJob(driver, vm); if (err < 0) { /* We couldn't get current memory allocation but that's not @@ -2660,8 +2621,7 @@ static int qemuDomainGetInfo(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2686,8 +2646,7 @@ qemuDomainGetState(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -2737,8 +2696,7 @@ qemuDomainGetControlInfo(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -3233,37 +3191,28 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); - if (!vm->persistent) { - if (qemuDomainObjEndAsyncJob(driver, vm) > 0) - qemuDomainRemoveInactive(driver, vm); - vm = NULL; - } - endjob: - if (vm) { - if (ret != 0) { - if (was_running && virDomainObjIsActive(vm)) { - rc = qemuProcessStartCPUs(driver, vm, dom->conn, - VIR_DOMAIN_RUNNING_SAVE_CANCELED, - QEMU_ASYNC_JOB_SAVE); - if (rc < 0) { - VIR_WARN("Unable to resume guest CPUs after save failure"); - event = virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_SUSPENDED, - VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); - } + qemuDomainObjEndAsyncJob(driver, vm); + if (ret != 0) { + if (was_running && virDomainObjIsActive(vm)) { + rc = qemuProcessStartCPUs(driver, vm, dom->conn, + VIR_DOMAIN_RUNNING_SAVE_CANCELED, + QEMU_ASYNC_JOB_SAVE); + if (rc < 0) { + VIR_WARN("Unable to resume guest CPUs after save failure"); + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); } } - if (qemuDomainObjEndAsyncJob(driver, vm) == 0) - vm = NULL; + } else if (!vm->persistent) { + qemuDomainRemoveInactive(driver, vm); } cleanup: VIR_FREE(xml); if (event) qemuDomainEventQueue(driver, event); - if (vm) - virObjectUnlock(vm); virObjectUnref(caps); return ret; } @@ -3329,11 +3278,9 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, ret = qemuDomainSaveInternal(driver, dom, vm, path, compressed, dxml, flags); - vm = NULL; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -3412,15 +3359,13 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) VIR_INFO("Saving state of domain '%s' to '%s'", vm->def->name, name); - if ((ret = qemuDomainSaveInternal(driver, dom, vm, name, compressed, - NULL, flags)) == 0) + ret = qemuDomainSaveInternal(driver, dom, vm, name, + compressed, NULL, flags); + if (ret == 0) vm->hasManagedSave = true; - vm = NULL; - cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); VIR_FREE(name); virObjectUnref(cfg); @@ -3467,7 +3412,7 @@ qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) ret = vm->hasManagedSave; cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -3502,7 +3447,7 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) cleanup: VIR_FREE(name); - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -3761,16 +3706,12 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom, } } - if (qemuDomainObjEndAsyncJob(driver, vm) == 0) { - vm = NULL; - } else if ((ret == 0) && (flags & VIR_DUMP_CRASH) && !vm->persistent) { + qemuDomainObjEndAsyncJob(driver, vm); + if (ret == 0 && flags & VIR_DUMP_CRASH && !vm->persistent) qemuDomainRemoveInactive(driver, vm); - vm = NULL; - } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); return ret; @@ -3869,12 +3810,10 @@ qemuDomainScreenshot(virDomainPtr dom, unlink(tmp); VIR_FREE(tmp); - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -3933,10 +3872,7 @@ static void processWatchdogEvent(virQEMUDriverPtr driver, virDomainObjPtr vm, in } endjob: - /* Safe to ignore value since ref count was incremented in - * qemuProcessHandleWatchdog(). - */ - ignore_value(qemuDomainObjEndAsyncJob(driver, vm)); + qemuDomainObjEndAsyncJob(driver, vm); cleanup: virObjectUnref(cfg); @@ -3983,10 +3919,7 @@ doCoreDumpToAutoDumpPath(virQEMUDriverPtr driver, "%s", _("Dump failed")); endjob: - /* Safe to ignore value since ref count was incremented in - * qemuProcessHandleGuestPanic(). - */ - ignore_value(qemuDomainObjEndAsyncJob(driver, vm)); + qemuDomainObjEndAsyncJob(driver, vm); cleanup: VIR_FREE(dumpfile); @@ -4116,10 +4049,7 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver, devAlias); endjob: - /* We had an extra reference to vm before starting a new job so ending the - * job is guaranteed not to remove the last reference. - */ - ignore_value(qemuDomainObjEndJob(driver, vm)); + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(devAlias); @@ -4306,10 +4236,7 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver, } endjob: - /* We had an extra reference to vm before starting a new job so ending the - * job is guaranteed not to remove the last reference. - */ - ignore_value(qemuDomainObjEndJob(driver, vm)); + qemuDomainObjEndJob(driver, vm); cleanup: virNetDevRxFilterFree(hostFilter); @@ -4367,10 +4294,7 @@ processSerialChangedEvent(virQEMUDriverPtr driver, "channel %s", vm->def->name, devAlias); endjob: - /* We had an extra reference to vm before starting a new job so ending the - * job is guaranteed not to remove the last reference. - */ - ignore_value(qemuDomainObjEndJob(driver, vm)); + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(devAlias); @@ -4409,8 +4333,7 @@ static void qemuProcessEventHandler(void *data, void *opaque) break; } - if (virObjectUnref(vm)) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); VIR_FREE(processEvent); } @@ -4744,12 +4667,10 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); VIR_FREE(cpuinfo); virObjectUnref(cfg); @@ -4941,8 +4862,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, cleanup: if (cgroup_vcpu) virCgroupFree(&cgroup_vcpu); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); VIR_FREE(str); @@ -5043,8 +4963,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom, ret = ncpumaps; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); return ret; } @@ -5222,8 +5141,7 @@ qemuDomainPinEmulator(virDomainPtr dom, VIR_FREE(str); virBitmapFree(pcpumap); virObjectUnref(caps); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -5296,8 +5214,7 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, ret = 1; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); return ret; } @@ -5328,8 +5245,7 @@ qemuDomainGetVcpus(virDomainPtr dom, ret = qemuDomainHelperGetVcpus(vm, info, maxinfo, cpumaps, maplen); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -5395,8 +5311,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) qemuDomainObjExitAgent(vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); if (ncpuinfo < 0) goto cleanup; @@ -5421,8 +5336,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); VIR_FREE(cpuinfo); return ret; @@ -5482,8 +5396,7 @@ static int qemuDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr secl ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -5548,8 +5461,7 @@ static int qemuDomainGetSecurityLabelList(virDomainPtr dom, } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -5986,6 +5898,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL))) goto cleanup; + virObjectRef(vm); def = NULL; if (flags & VIR_DOMAIN_SAVE_RUNNING) @@ -6006,12 +5919,9 @@ qemuDomainRestoreFlags(virConnectPtr conn, if (virFileWrapperFdClose(wrapperFd) < 0) VIR_WARN("Failed to close %s", path); - if (!qemuDomainObjEndJob(driver, vm)) { - vm = NULL; - } else if (ret < 0 && !vm->persistent) { + qemuDomainObjEndJob(driver, vm); + if (ret < 0 && !vm->persistent) qemuDomainRemoveInactive(driver, vm); - vm = NULL; - } cleanup: virDomainDefFree(def); @@ -6019,8 +5929,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, VIR_FREE(xml); VIR_FREE(xmlout); virFileWrapperFdFree(wrapperFd); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virNWFilterUnlockFilterUpdates(); return ret; } @@ -6269,10 +6178,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) { - vm = NULL; - goto cleanup; - } + qemuDomainObjEndJob(driver, vm); if (err < 0) goto cleanup; if (err > 0) @@ -6287,8 +6193,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, ret = qemuDomainFormatXML(driver, vm, flags); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -6683,12 +6588,10 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virNWFilterUnlockFilterUpdates(); return ret; } @@ -6741,6 +6644,7 @@ static virDomainPtr qemuDomainDefineXML(virConnectPtr conn, const char *xml) 0, &oldDef))) goto cleanup; + virObjectRef(vm); def = NULL; if (virDomainHasDiskMirror(vm)) { virReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s", @@ -6765,7 +6669,6 @@ static virDomainPtr qemuDomainDefineXML(virConnectPtr conn, const char *xml) /* Brand new domain. Remove it */ VIR_INFO("Deleting domain '%s'", vm->def->name); qemuDomainRemoveInactive(driver, vm); - vm = NULL; } goto cleanup; } @@ -6783,8 +6686,7 @@ static virDomainPtr qemuDomainDefineXML(virConnectPtr conn, const char *xml) cleanup: virDomainDefFree(oldDef); virDomainDefFree(def); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); virObjectUnref(qemuCaps); @@ -6890,15 +6792,13 @@ qemuDomainUndefineFlags(virDomainPtr dom, vm->persistent = 0; } else { qemuDomainRemoveInactive(driver, vm); - vm = NULL; } ret = 0; cleanup: VIR_FREE(name); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); virObjectUnref(cfg); @@ -7675,8 +7575,7 @@ static int qemuDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virObjectUnref(qemuCaps); @@ -7684,8 +7583,7 @@ static int qemuDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, if (dev != dev_copy) virDomainDeviceDefFree(dev_copy); virDomainDeviceDefFree(dev); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); virNWFilterUnlockFilterUpdates(); @@ -7824,8 +7722,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virObjectUnref(qemuCaps); @@ -7833,8 +7730,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, if (dev != dev_copy) virDomainDeviceDefFree(dev_copy); virDomainDeviceDefFree(dev); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); virNWFilterUnlockFilterUpdates(); @@ -7966,8 +7862,7 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virObjectUnref(qemuCaps); @@ -7975,8 +7870,7 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, if (dev != dev_copy) virDomainDeviceDefFree(dev_copy); virDomainDeviceDefFree(dev); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -8004,8 +7898,7 @@ static int qemuDomainGetAutostart(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -8070,8 +7963,7 @@ static int qemuDomainSetAutostart(virDomainPtr dom, cleanup: VIR_FREE(configFile); VIR_FREE(autostartLink); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -8125,8 +8017,7 @@ static char *qemuDomainGetSchedulerType(virDomainPtr dom, ignore_value(VIR_STRDUP(ret, "posix")); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -8510,12 +8401,10 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -8928,8 +8817,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -9073,7 +8961,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, ret = 0; cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -9226,8 +9114,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -9439,13 +9326,11 @@ qemuDomainSetNumaParameters(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virBitmapFree(nodeset); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -9549,8 +9434,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom, cleanup: VIR_FREE(nodeset); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); return ret; } @@ -9837,8 +9721,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, cleanup: virDomainDefFree(vmdef); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (eventNparams) virTypedParamsFree(eventParams, eventNparams); virObjectUnref(caps); @@ -10075,8 +9958,7 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -10174,13 +10056,11 @@ qemuDomainBlockResize(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(device); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -10251,12 +10131,10 @@ qemuDomainBlockStats(virDomainPtr dom, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -10426,12 +10304,10 @@ qemuDomainBlockStatsFlags(virDomainPtr dom, *nparams = tmp; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -10472,8 +10348,7 @@ qemuDomainInterfaceStats(virDomainPtr dom, _("invalid path, '%s' is not a known interface"), path); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -10657,14 +10532,12 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virNetDevBandwidthFree(bandwidth); virNetDevBandwidthFree(newBandwidth); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -10784,8 +10657,7 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); return ret; } @@ -10834,12 +10706,10 @@ qemuDomainMemoryStats(virDomainPtr dom, } } - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -10896,8 +10766,7 @@ qemuDomainBlockPeek(virDomainPtr dom, cleanup: VIR_FORCE_CLOSE(fd); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -10977,16 +10846,14 @@ qemuDomainMemoryPeek(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FORCE_CLOSE(fd); if (tmp) unlink(tmp); VIR_FREE(tmp); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -11164,8 +11031,7 @@ qemuDomainGetBlockInfo(virDomainPtr dom, ret = 0; } - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); } else { ret = 0; } @@ -11186,7 +11052,7 @@ qemuDomainGetBlockInfo(virDomainPtr dom, _("domain is not running")); ret = -1; } - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -11427,7 +11293,7 @@ qemuDomainMigratePerform(virDomainPtr dom, goto cleanup; if (virDomainMigratePerformEnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); goto cleanup; } @@ -11481,6 +11347,7 @@ qemuDomainMigrateFinish2(virConnectPtr dconn, goto cleanup; } + virObjectRef(vm); /* Do not use cookies in v2 protocol, since the cookie * length was not sufficiently large, causing failures * migrating between old & new libvirtd @@ -11515,7 +11382,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain, return NULL; if (virDomainMigrateBegin3EnsureACL(domain->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return NULL; } @@ -11551,7 +11418,7 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain, return NULL; if (virDomainMigrateBegin3ParamsEnsureACL(domain->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return NULL; } @@ -11795,7 +11662,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, return -1; if (virDomainMigratePerform3EnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -11854,7 +11721,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, return -1; if (virDomainMigratePerform3ParamsEnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -11895,6 +11762,8 @@ qemuDomainMigrateFinish3(virConnectPtr dconn, return NULL; } + virObjectRef(vm); + return qemuMigrationFinish(driver, dconn, vm, cookiein, cookieinlen, cookieout, cookieoutlen, @@ -11938,6 +11807,8 @@ qemuDomainMigrateFinish3Params(virConnectPtr dconn, return NULL; } + virObjectRef(vm); + return qemuMigrationFinish(driver, dconn, vm, cookiein, cookieinlen, cookieout, cookieoutlen, @@ -11960,7 +11831,7 @@ qemuDomainMigrateConfirm3(virDomainPtr domain, return -1; if (virDomainMigrateConfirm3EnsureACL(domain->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -11988,7 +11859,7 @@ qemuDomainMigrateConfirm3Params(virDomainPtr domain, return -1; if (virDomainMigrateConfirm3ParamsEnsureACL(domain->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -12291,8 +12162,7 @@ static int qemuDomainGetJobInfo(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12358,8 +12228,7 @@ qemuDomainGetJobStats(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12406,12 +12275,10 @@ static int qemuDomainAbortJob(virDomainPtr dom) qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12451,12 +12318,10 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12506,12 +12371,10 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12562,12 +12425,10 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12617,16 +12478,14 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, priv->migMaxBandwidth = bandwidth; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); } else { priv->migMaxBandwidth = bandwidth; ret = 0; } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -12653,8 +12512,7 @@ qemuDomainMigrateGetMaxSpeed(virDomainPtr dom, ret = 0; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -14117,12 +13975,10 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, virDomainSnapshotObjListRemove(vm->snapshots, snap); } - if (!qemuDomainObjEndAsyncJob(driver, vm)) - vm = NULL; + qemuDomainObjEndAsyncJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virDomainSnapshotDefFree(def); VIR_FREE(xml); virObjectUnref(caps); @@ -14153,7 +14009,7 @@ qemuDomainSnapshotListNames(virDomainPtr domain, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return n; } @@ -14177,7 +14033,7 @@ qemuDomainSnapshotNum(virDomainPtr domain, n = virDomainSnapshotObjListNum(vm->snapshots, NULL, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return n; } @@ -14202,7 +14058,7 @@ qemuDomainListAllSnapshots(virDomainPtr domain, n = virDomainListSnapshots(vm->snapshots, NULL, domain, snaps, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return n; } @@ -14233,7 +14089,7 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return n; } @@ -14261,7 +14117,7 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, n = virDomainSnapshotObjListNum(vm->snapshots, snap, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return n; } @@ -14291,7 +14147,7 @@ qemuDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return n; } @@ -14319,7 +14175,7 @@ qemuDomainSnapshotLookupByName(virDomainPtr domain, snapshot = virGetDomainSnapshot(domain, snap->def->name); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return snapshot; } @@ -14342,7 +14198,7 @@ qemuDomainHasCurrentSnapshot(virDomainPtr domain, ret = (vm->current_snapshot != NULL); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -14376,7 +14232,7 @@ qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot, parent = virGetDomainSnapshot(snapshot->domain, snap->def->parent); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return parent; } @@ -14405,7 +14261,7 @@ qemuDomainSnapshotCurrent(virDomainPtr domain, snapshot = virGetDomainSnapshot(domain, vm->current_snapshot->def->name); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return snapshot; } @@ -14435,7 +14291,7 @@ qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot, xml = virDomainSnapshotDefFormat(uuidstr, snap->def, flags, 0); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return xml; } @@ -14463,7 +14319,7 @@ qemuDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot, STREQ(snapshot->name, vm->current_snapshot->def->name)); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -14493,7 +14349,7 @@ qemuDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot, ret = 1; cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -14782,9 +14638,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, if (qemuDomainSnapshotRevertInactive(driver, vm, snap) < 0) { if (!vm->persistent) { - if (qemuDomainObjEndJob(driver, vm)) - qemuDomainRemoveInactive(driver, vm); - vm = NULL; + qemuDomainObjEndJob(driver, vm); + qemuDomainRemoveInactive(driver, vm); goto cleanup; } goto endjob; @@ -14809,9 +14664,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, virDomainAuditStart(vm, "from-snapshot", rc >= 0); if (rc < 0) { if (!vm->persistent) { - if (qemuDomainObjEndJob(driver, vm)) - qemuDomainRemoveInactive(driver, vm); - vm = NULL; + qemuDomainObjEndJob(driver, vm); + qemuDomainRemoveInactive(driver, vm); goto cleanup; } goto endjob; @@ -14848,11 +14702,10 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, ret = 0; endjob: - if (vm && !qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm && ret == 0) { + if (ret == 0) { if (qemuDomainSnapshotWriteMetadata(vm, snap, cfg->snapshotDir) < 0) ret = -1; @@ -14866,8 +14719,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, if (event2) qemuDomainEventQueue(driver, event2); } - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); virNWFilterUnlockFilterUpdates(); @@ -15017,12 +14869,10 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -15070,12 +14920,10 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -15144,20 +14992,19 @@ static virDomainPtr qemuDomainQemuAttach(virConnectPtr conn, NULL))) goto cleanup; + virObjectRef(vm); def = NULL; if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) { qemuDomainRemoveInactive(driver, vm); - vm = NULL; goto cleanup; } if (qemuProcessAttach(conn, driver, vm, pid, pidfile, monConfig, monJSON) < 0) { - if (qemuDomainObjEndJob(driver, vm)) - qemuDomainRemoveInactive(driver, vm); - vm = NULL; monConfig = NULL; + qemuDomainObjEndJob(driver, vm); + qemuDomainRemoveInactive(driver, vm); goto cleanup; } @@ -15167,14 +15014,12 @@ static virDomainPtr qemuDomainQemuAttach(virConnectPtr conn, if (dom) dom->id = vm->def->id; - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: virDomainDefFree(def); virDomainChrSourceDefFree(monConfig); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); VIR_FREE(pidfile); virObjectUnref(caps); virObjectUnref(qemuCaps); @@ -15259,8 +15104,7 @@ qemuDomainOpenConsole(virDomainPtr dom, } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -15334,8 +15178,7 @@ qemuDomainOpenChannel(virDomainPtr dom, } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -15750,18 +15593,14 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm, } endjob: - if (!qemuDomainObjEndJob(driver, vm)) { - vm = NULL; - goto cleanup; - } + qemuDomainObjEndJob(driver, vm); cleanup: virObjectUnref(cfg); VIR_FREE(basePath); VIR_FREE(backingPath); VIR_FREE(device); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); if (event2) @@ -15781,7 +15620,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom, const char *path, unsigned int flags) return -1; if (virDomainBlockJobAbortEnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -15808,7 +15647,7 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom, const char *path, return -1; if (virDomainGetBlockJobInfoEnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -15869,12 +15708,10 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom, const char *path, virObjectUnref(cfg); } endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -15889,7 +15726,7 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom, const char *path, return -1; if (virDomainBlockJobSetSpeedEnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -15899,8 +15736,7 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom, const char *path, /* bandwidth in bytes/s. Caller must lock vm beforehand, and not - * access it afterwards; likewise, caller must not access mirror - * afterwards. */ + * access mirror afterwards. */ static int qemuDomainBlockCopyCommon(virDomainObjPtr vm, virConnectPtr conn, @@ -16078,13 +15914,10 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, if (need_unlink && unlink(mirror->path)) VIR_WARN("unable to unlink just-created %s", mirror->path); virStorageSourceFree(mirror); - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(device); - if (vm) - virObjectUnlock(vm); virObjectUnref(cfg); return ret; } @@ -16155,12 +15988,10 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base, VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT); ret = qemuDomainBlockCopyCommon(vm, dom->conn, path, dest, bandwidth, 0, 0, flags, true); - vm = NULL; dest = NULL; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virStorageSourceFree(dest); return ret; } @@ -16229,11 +16060,9 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *disk, const char *destxml, ret = qemuDomainBlockCopyCommon(vm, dom->conn, disk, dest, bandwidth, granularity, buf_size, flags, false); - vm = NULL; cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -16249,7 +16078,7 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth, return -1; if (virDomainBlockPullEnsureACL(dom->conn, vm->def) < 0) { - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return -1; } @@ -16488,16 +16317,14 @@ qemuDomainBlockCommit(virDomainPtr dom, VIR_DISK_CHAIN_READ_ONLY); } virStorageSourceFree(mirror); - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(topPath); VIR_FREE(basePath); VIR_FREE(backingPath); VIR_FREE(device); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -16558,12 +16385,10 @@ qemuDomainOpenGraphics(virDomainPtr dom, ret = qemuMonitorOpenGraphics(priv->mon, protocol, fd, "graphicsfd", (flags & VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) != 0); qemuDomainObjExitMonitor(driver, vm); - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -16629,8 +16454,7 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom, ret = qemuMonitorOpenGraphics(priv->mon, protocol, pair[1], "graphicsfd", (flags & VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH)); qemuDomainObjExitMonitor(driver, vm); - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); if (ret < 0) goto cleanup; @@ -16640,8 +16464,7 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom, cleanup: VIR_FORCE_CLOSE(pair[0]); VIR_FORCE_CLOSE(pair[1]); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -16995,14 +16818,11 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, } endjob: - - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(device); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (eventNparams) virTypedParamsFree(eventParams, eventNparams); virObjectUnref(caps); @@ -17198,13 +17018,11 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(device); - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); return ret; } @@ -17272,12 +17090,10 @@ qemuDomainGetDiskErrors(virDomainPtr dom, ret = n; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virHashFree(table); if (ret < 0) { for (i = 0; i < n; i++) @@ -17319,7 +17135,7 @@ qemuDomainSetMetadata(virDomainPtr dom, cfg->configDir, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); virObjectUnref(cfg); return ret; @@ -17348,7 +17164,7 @@ qemuDomainGetMetadata(virDomainPtr dom, ret = virDomainObjGetMetadata(vm, type, uri, caps, driver->xmlopt, flags); cleanup: - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(caps); return ret; } @@ -17397,8 +17213,7 @@ qemuDomainGetCPUStats(virDomainPtr domain, ret = virCgroupGetPercpuStats(priv->cgroup, params, nparams, start_cpu, ncpus, priv->nvcpupids); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -17487,12 +17302,10 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom, qemuDomainObjExitAgent(vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -17536,12 +17349,10 @@ qemuDomainPMWakeup(virDomainPtr dom, qemuDomainObjExitMonitor(driver, vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -17612,12 +17423,10 @@ qemuDomainQemuAgentCommand(virDomainPtr domain, VIR_FREE(result); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return result; } @@ -17721,12 +17530,10 @@ qemuDomainFSTrim(virDomainPtr dom, qemuDomainObjExitAgent(vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -17906,12 +17713,10 @@ qemuDomainGetTime(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -17980,12 +17785,10 @@ qemuDomainSetTime(virDomainPtr dom, ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -18020,12 +17823,10 @@ qemuDomainFSFreeze(virDomainPtr dom, ret = qemuDomainSnapshotFSFreeze(driver, vm, mountpoints, nmountpoints); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -18066,12 +17867,10 @@ qemuDomainFSThaw(virDomainPtr dom, ret = qemuDomainSnapshotFSThaw(driver, vm, true); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } @@ -18759,8 +18558,7 @@ qemuConnectGetAllDomainStats(virConnectPtr conn, if (doms != domlist && !virConnectGetAllDomainStatsCheckACL(conn, dom->def)) { - virObjectUnlock(dom); - dom = NULL; + qemuDomObjEndAPI(&dom); continue; } @@ -18775,16 +18573,10 @@ qemuConnectGetAllDomainStats(virConnectPtr conn, if (tmp) tmpstats[nstats++] = tmp; - if (HAVE_JOB(domflags)) { - domflags = 0; - if (!qemuDomainObjEndJob(driver, dom)) { - dom = NULL; - continue; - } - } + if (HAVE_JOB(domflags)) + qemuDomainObjEndJob(driver, dom); - virObjectUnlock(dom); - dom = NULL; + qemuDomObjEndAPI(&dom); } *retStats = tmpstats; @@ -18794,12 +18586,10 @@ qemuConnectGetAllDomainStats(virConnectPtr conn, endjob: if (HAVE_JOB(domflags) && dom) - if (!qemuDomainObjEndJob(driver, dom)) - dom = NULL; + qemuDomainObjEndJob(driver, dom); cleanup: - if (dom) - virObjectUnlock(dom); + qemuDomObjEndAPI(&dom); virDomainStatsRecordListFree(tmpstats); virDomainListFree(domlist); @@ -18866,12 +18656,10 @@ qemuDomainGetFSInfo(virDomainPtr dom, qemuDomainObjExitAgent(vm); endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 0acbb57..a0d5d69 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2736,31 +2736,20 @@ qemuMigrationBegin(virConnectPtr conn, if (virCloseCallbacksSet(driver->closeCallbacks, vm, conn, qemuMigrationCleanup) < 0) goto endjob; - if (qemuMigrationJobContinue(vm) == 0) { - vm = NULL; - virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("domain disappeared")); - VIR_FREE(xml); - if (cookieout) - VIR_FREE(*cookieout); - } + qemuMigrationJobContinue(vm); } else { goto endjob; } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); return xml; endjob: - if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { - if (qemuMigrationJobFinish(driver, vm) == 0) - vm = NULL; - } else { - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; - } + if (flags & VIR_MIGRATE_CHANGE_PROTECTION) + qemuMigrationJobFinish(driver, vm); + else + qemuDomainObjEndJob(driver, vm); goto cleanup; } @@ -2973,6 +2962,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, NULL))) goto cleanup; + virObjectRef(vm); *def = NULL; priv = vm->privateData; if (VIR_STRDUP(priv->origname, origname) < 0) @@ -3099,12 +3089,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, * This prevents any other APIs being invoked while incoming * migration is taking place. */ - if (!qemuMigrationJobContinue(vm)) { - vm = NULL; - virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("domain disappeared")); - goto cleanup; - } + qemuMigrationJobContinue(vm); if (autoPort) priv->migrationPort = port; @@ -3115,16 +3100,12 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, VIR_FREE(xmlout); VIR_FORCE_CLOSE(dataFD[0]); VIR_FORCE_CLOSE(dataFD[1]); - if (vm) { - if (ret < 0) { - virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort); - priv->nbdPort = 0; - } - if (ret >= 0 || vm->persistent) - virObjectUnlock(vm); - else - qemuDomainRemoveInactive(driver, vm); + if (ret < 0) { + virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort); + priv->nbdPort = 0; + qemuDomainRemoveInactive(driver, vm); } + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); @@ -3137,8 +3118,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, 0); endjob: - if (!qemuMigrationJobFinish(driver, vm)) - vm = NULL; + qemuMigrationJobFinish(driver, vm); goto cleanup; } @@ -3507,19 +3487,16 @@ qemuMigrationConfirm(virConnectPtr conn, cookiein, cookieinlen, flags, cancelled); - if (qemuMigrationJobFinish(driver, vm) == 0) { - vm = NULL; - } else if (!virDomainObjIsActive(vm) && - (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) { + qemuMigrationJobFinish(driver, vm); + if (!virDomainObjIsActive(vm) && + (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) { if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm); qemuDomainRemoveInactive(driver, vm); - vm = NULL; } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); virObjectUnref(cfg); return ret; } @@ -4877,15 +4854,13 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, VIR_DOMAIN_EVENT_RESUMED_MIGRATED); } - if (!qemuMigrationJobFinish(driver, vm)) { - vm = NULL; - } else if (!virDomainObjIsActive(vm) && - (!vm->persistent || - (ret == 0 && (flags & VIR_MIGRATE_UNDEFINE_SOURCE)))) { + qemuMigrationJobFinish(driver, vm); + if (!virDomainObjIsActive(vm) && + (!vm->persistent || + (ret == 0 && (flags & VIR_MIGRATE_UNDEFINE_SOURCE)))) { if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm); qemuDomainRemoveInactive(driver, vm); - vm = NULL; } if (orig_err) { @@ -4894,8 +4869,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); virObjectUnref(cfg); @@ -4920,7 +4894,6 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver, { virObjectEventPtr event = NULL; int ret = -1; - bool hasrefs; /* If we didn't start the job in the begin phase, start it now. */ if (!(flags & VIR_MIGRATE_CHANGE_PROTECTION)) { @@ -4955,19 +4928,14 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver, endjob: if (ret < 0) - hasrefs = qemuMigrationJobFinish(driver, vm); + qemuMigrationJobFinish(driver, vm); else - hasrefs = qemuMigrationJobContinue(vm); - if (!hasrefs) { - vm = NULL; - } else if (!virDomainObjIsActive(vm) && !vm->persistent) { + qemuMigrationJobContinue(vm); + if (!virDomainObjIsActive(vm) && !vm->persistent) qemuDomainRemoveInactive(driver, vm); - vm = NULL; - } cleanup: - if (vm) - virObjectUnlock(vm); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); return ret; @@ -5301,21 +5269,16 @@ qemuMigrationFinish(virQEMUDriverPtr driver, VIR_WARN("Unable to encode migration cookie"); endjob: - if (qemuMigrationJobFinish(driver, vm) == 0) { - vm = NULL; - } else if (!vm->persistent && !virDomainObjIsActive(vm)) { + qemuMigrationJobFinish(driver, vm); + if (!vm->persistent && !virDomainObjIsActive(vm)) qemuDomainRemoveInactive(driver, vm); - vm = NULL; - } cleanup: virPortAllocatorRelease(driver->migrationPorts, port); - if (vm) { - if (priv->mon) - qemuMonitorSetDomainLog(priv->mon, -1); - VIR_FREE(priv->origname); - virObjectUnlock(vm); - } + if (priv->mon) + qemuMonitorSetDomainLog(priv->mon, -1); + VIR_FREE(priv->origname); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); @@ -5563,15 +5526,13 @@ qemuMigrationJobStartPhase(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuMigrationJobPhase phase) { - virObjectRef(vm); qemuMigrationJobSetPhase(driver, vm, phase); } -bool +void qemuMigrationJobContinue(virDomainObjPtr vm) { qemuDomainObjReleaseAsyncJob(vm); - return virObjectUnref(vm); } bool @@ -5594,8 +5555,8 @@ qemuMigrationJobIsActive(virDomainObjPtr vm, return true; } -bool +void qemuMigrationJobFinish(virQEMUDriverPtr driver, virDomainObjPtr vm) { - return qemuDomainObjEndAsyncJob(driver, vm); + qemuDomainObjEndAsyncJob(driver, vm); } diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index e7a90c3..1726455 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -1,7 +1,7 @@ /* * qemu_migration.h: QEMU migration handling * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2011, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -82,13 +82,13 @@ void qemuMigrationJobStartPhase(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuMigrationJobPhase phase) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -bool qemuMigrationJobContinue(virDomainObjPtr obj) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +void qemuMigrationJobContinue(virDomainObjPtr obj) + ATTRIBUTE_NONNULL(1); bool qemuMigrationJobIsActive(virDomainObjPtr vm, qemuDomainAsyncJob job) ATTRIBUTE_NONNULL(1); -bool qemuMigrationJobFinish(virQEMUDriverPtr driver, virDomainObjPtr obj) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +void qemuMigrationJobFinish(virQEMUDriverPtr driver, virDomainObjPtr obj) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int qemuMigrationSetOffline(virQEMUDriverPtr driver, virDomainObjPtr vm); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index a19e71a..4d9ce09 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -572,6 +572,7 @@ qemuProcessFakeReboot(void *opaque) virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED; int ret = -1; + VIR_DEBUG("vm=%p", vm); virObjectLock(vm); if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) @@ -620,16 +621,12 @@ qemuProcessFakeReboot(void *opaque) ret = 0; endjob: - if (!qemuDomainObjEndJob(driver, vm)) - vm = NULL; + qemuDomainObjEndJob(driver, vm); cleanup: - if (vm) { - if (ret == -1) - ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE)); - if (virObjectUnref(vm)) - virObjectUnlock(vm); - } + if (ret == -1) + ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE)); + qemuDomObjEndAPI(&vm); if (event) qemuDomainEventQueue(driver, event); virObjectUnref(cfg); @@ -1447,7 +1444,7 @@ qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED, cleanup: if (vm) - virObjectUnlock(vm); + virObjectUnlock(vm); return 0; } @@ -3542,7 +3539,7 @@ struct qemuProcessReconnectData { * this thread function has increased the reference counter to it * so that we now have to close it. * - * This function also inherits a locked domain object. + * This function also inherits a locked and ref'd domain object. * * This function needs to: * 1. Enter job @@ -3575,10 +3572,6 @@ qemuProcessReconnect(void *opaque) qemuDomainObjRestoreJob(obj, &oldjob); - /* Hold an extra reference because we can't allow 'vm' to be - * deleted if qemuConnectMonitor() failed */ - virObjectRef(obj); - cfg = virQEMUDriverGetConfig(driver); priv = obj->privateData; @@ -3667,7 +3660,8 @@ qemuProcessReconnect(void *opaque) VIR_DEBUG("Finishing shutdown sequence for domain %s", obj->def->name); qemuProcessShutdownOrReboot(driver, obj); - goto endjob; + qemuDomainObjEndJob(driver, obj); + goto cleanup; } if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) @@ -3719,23 +3713,11 @@ qemuProcessReconnect(void *opaque) if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback) driver->inhibitCallback(true, driver->inhibitOpaque); - endjob: - /* we hold an extra reference, so this will never fail */ - ignore_value(qemuDomainObjEndJob(driver, obj)); - - if (virObjectUnref(obj)) - virObjectUnlock(obj); - - virObjectUnref(conn); - virObjectUnref(cfg); - virNWFilterUnlockFilterUpdates(); - - return; + qemuDomainObjEndJob(driver, obj); + goto cleanup; error: - /* we hold an extra reference, so this will never fail */ - ignore_value(qemuDomainObjEndJob(driver, obj)); - + qemuDomainObjEndJob(driver, obj); killvm: if (virDomainObjIsActive(obj)) { /* We can't get the monitor back, so must kill the VM @@ -3755,13 +3737,11 @@ qemuProcessReconnect(void *opaque) qemuProcessStop(driver, obj, state, 0); } - if (virObjectUnref(obj)) { - if (!obj->persistent) - qemuDomainRemoveInactive(driver, obj); - else - virObjectUnlock(obj); - } + if (!obj->persistent) + qemuDomainRemoveInactive(driver, obj); + cleanup: + qemuDomObjEndAPI(&obj); virObjectUnref(conn); virObjectUnref(cfg); virNWFilterUnlockFilterUpdates(); @@ -3785,9 +3765,10 @@ qemuProcessReconnectHelper(virDomainObjPtr obj, memcpy(data, src, sizeof(*data)); data->obj = obj; - /* this lock will be eventually transferred to the thread that handles the - * reconnect */ + /* this lock and reference will be eventually transferred to the thread + * that handles the reconnect */ virObjectLock(obj); + virObjectRef(obj); /* Since we close the connection later on, we have to make sure that the * threads we start see a valid connection throughout their lifetime. We @@ -3803,9 +3784,8 @@ qemuProcessReconnectHelper(virDomainObjPtr obj, qemuProcessStop(src->driver, obj, VIR_DOMAIN_SHUTOFF_FAILED, 0); if (!obj->persistent) qemuDomainRemoveInactive(src->driver, obj); - else - virObjectUnlock(obj); + qemuDomObjEndAPI(&obj); virObjectUnref(data->conn); VIR_FREE(data); return -1; @@ -5473,12 +5453,11 @@ qemuProcessAutoDestroy(virDomainObjPtr dom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - if (!qemuDomainObjEndJob(driver, dom)) - dom = NULL; - if (dom && !dom->persistent) { + qemuDomainObjEndJob(driver, dom); + + if (!dom->persistent) qemuDomainRemoveInactive(driver, dom); - dom = NULL; - } + if (event) qemuDomainEventQueue(driver, event); @@ -5491,6 +5470,7 @@ int qemuProcessAutoDestroyAdd(virQEMUDriverPtr driver, virConnectPtr conn) { VIR_DEBUG("vm=%s, conn=%p", vm->def->name, conn); + virObjectRef(vm); return virCloseCallbacksSet(driver->closeCallbacks, vm, conn, qemuProcessAutoDestroy); } @@ -5498,9 +5478,12 @@ int qemuProcessAutoDestroyAdd(virQEMUDriverPtr driver, int qemuProcessAutoDestroyRemove(virQEMUDriverPtr driver, virDomainObjPtr vm) { + int ret; VIR_DEBUG("vm=%s", vm->def->name); - return virCloseCallbacksUnset(driver->closeCallbacks, vm, - qemuProcessAutoDestroy); + ret = virCloseCallbacksUnset(driver->closeCallbacks, vm, + qemuProcessAutoDestroy); + virObjectUnref(vm); + return ret; } bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver, -- 2.2.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list