Remove qemuDriverLock from almost everywhere

With the majority of fields in the virQEMUDriverPtr struct
now immutable or self-locking, there is no need for practically
any methods to be using the QEMU driver lock. Only a handful
of helper APIs in qemu_conf.c now need it
This commit is contained in:
Daniel P. Berrange 2013-02-06 18:17:20 +00:00
parent 3178df9afa
commit a9e97e0c30
10 changed files with 388 additions and 984 deletions

View File

@ -14,35 +14,24 @@ Basic locking primitives
There are a number of locks on various objects
* struct qemud_driver: RWLock
* virQEMUDriverPtr
This is the top level lock on the entire driver. Every API call in
the QEMU driver is blocked while this is held, though some internal
callbacks may still run asynchronously. This lock must never be held
for anything which sleeps/waits (i.e. monitor commands)
The qemu_conf.h file has inline comments describing the locking
needs for each field. Any field marked immutable, self-locking
can be accessed without the driver lock. For other fields there
are typically helper APIs in qemu_conf.c that provide serialized
access to the data. No code outside qemu_conf.c should ever
acquire this lock
When obtaining the driver lock, under *NO* circumstances must
any lock be held on a virDomainObjPtr. This *WILL* result in
deadlock.
* virDomainObjPtr: Mutex
* virDomainObjPtr
Will be locked after calling any of the virDomainFindBy{ID,Name,UUID}
methods.
Lock must be held when changing/reading any variable in the virDomainObjPtr
Once the lock is held, you must *NOT* try to lock the driver. You must
release all virDomainObjPtr locks before locking the driver, or deadlock
*WILL* occur.
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().
If the reference count is incremented in this way, it is not necessary
to have the driver locked when re-acquiring the dropped locked, since the
reference count prevents it being freed by another thread.
This lock must not be held for anything which sleeps/waits (i.e. monitor
commands).
@ -103,26 +92,10 @@ There are a number of locks on various objects
The virDomainObjPtr lock *MUST* then be released when invoking the
monitor command.
The driver lock *MUST* be released when invoking the monitor commands.
This ensures that the virDomainObjPtr & driver are both unlocked while
sleeping/waiting for the monitor response.
Helper methods
--------------
To lock the driver
qemuDriverLock()
- Acquires the driver lock
qemuDriverUnlock()
- Releases the driver lock
To lock the virDomainObjPtr
virObjectLock()
@ -135,7 +108,7 @@ To lock the virDomainObjPtr
To acquire the normal job condition
qemuDomainObjBeginJob() (if driver is unlocked)
qemuDomainObjBeginJob()
- Increments ref count on virDomainObjPtr
- Waits until the job is compatible with current async job or no
async job is running
@ -145,23 +118,6 @@ To acquire the normal job condition
isn't
- Sets job.active to the job type
qemuDomainObjBeginJobWithDriver() (if driver needs to be locked)
- Increments ref count on virDomainObjPtr
- Unlocks driver
- 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
mutex
- Rechecks if the job is still compatible and repeats waiting if it
isn't
- Sets job.active to the job type
- Unlocks virDomainObjPtr
- Locks driver
- Locks virDomainObjPtr
NB: this variant is required in order to comply with lock ordering
rules for virDomainObjPtr vs. driver
qemuDomainObjEndJob()
- Sets job.active to 0
@ -172,7 +128,7 @@ To acquire the normal job condition
To acquire the asynchronous job condition
qemuDomainObjBeginAsyncJob() (if driver is unlocked)
qemuDomainObjBeginAsyncJob()
- Increments ref count on virDomainObjPtr
- Waits until no async job is running
- Waits for job.cond condition 'job.active != 0' using virDomainObjPtr
@ -181,22 +137,6 @@ To acquire the asynchronous job condition
and repeats waiting in that case
- Sets job.asyncJob to the asynchronous job type
qemuDomainObjBeginAsyncJobWithDriver() (if driver needs to be locked)
- Increments ref count on virDomainObjPtr
- Unlocks driver
- Waits until no async job is running
- Waits for job.cond condition 'job.active != 0' using virDomainObjPtr
mutex
- Rechecks if any async job was started while waiting on job.cond
and repeats waiting in that case
- Sets job.asyncJob to the asynchronous job type
- Unlocks virDomainObjPtr
- Locks driver
- Locks virDomainObjPtr
NB: this variant is required in order to comply with lock ordering
rules for virDomainObjPtr vs driver
qemuDomainObjEndAsyncJob()
- Sets job.asyncJob to 0
@ -215,61 +155,34 @@ To acquire the QEMU monitor lock
- Releases the qemuMonitorObjPtr lock
- Acquires the virDomainObjPtr lock
NB: caller must take care to drop the driver lock if necessary
These functions must not be used by an asynchronous job.
To acquire the QEMU monitor lock with the driver lock held
qemuDomainObjEnterMonitorWithDriver()
- Acquires the qemuMonitorObjPtr lock
- Releases the virDomainObjPtr lock
- Releases the driver lock
qemuDomainObjExitMonitorWithDriver()
- Releases the qemuMonitorObjPtr lock
- Acquires the driver lock
- Acquires the virDomainObjPtr lock
NB: caller must take care to drop the driver lock if necessary
These functions must not be used inside an asynchronous job.
To acquire the QEMU monitor lock with the driver lock held and as part
of an asynchronous job
To acquire the QEMU monitor lock as part of an asynchronous job
qemuDomainObjEnterMonitorAsync()
- Validates that the right async job is still running
- Acquires the qemuMonitorObjPtr lock
- Releases the virDomainObjPtr lock
- Releases the driver lock
- Validates that the VM is still active
qemuDomainObjExitMonitorWithDriver()
qemuDomainObjExitMonitor()
- Releases the qemuMonitorObjPtr lock
- Acquires the driver lock
- Acquires the virDomainObjPtr lock
NB: caller must take care to drop the driver lock if necessary
These functions are for use inside an asynchronous job; the caller
must check for a return of -1 (VM not running, so nothing to exit).
Helper functions may also call this with QEMU_ASYNC_JOB_NONE when
used from a sync job (such as when first starting a domain).
To keep a domain alive while waiting on a remote command, starting
with the driver lock held
To keep a domain alive while waiting on a remote command
qemuDomainObjEnterRemoterWithDriver()
qemuDomainObjEnterRemote()
- Increments ref count on virDomainObjPtr
- Releases the virDomainObjPtr lock
- Releases the driver lock
qemuDomainObjExitRemoteWithDriver()
- Acquires the driver lock
qemuDomainObjExitRemote()
- Acquires the virDomainObjPtr lock
- Decrements ref count on virDomainObjPtr
@ -278,51 +191,22 @@ Design patterns
---------------
* Accessing or updating something with just the driver
qemuDriverLock(driver);
...do work...
qemuDriverUnlock(driver);
* Accessing something directly to do with a virDomainObjPtr
virDomainObjPtr obj;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDriverUnlock(driver);
...do work...
virDomainObjUnlock(obj);
* Accessing something directly to do with a virDomainObjPtr and driver
virDomainObjPtr obj;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
...do work...
virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
* Updating something directly to do with a virDomainObjPtr
virDomainObjPtr obj;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDriverUnlock(driver);
qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE);
@ -341,9 +225,7 @@ Design patterns
virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDriverUnlock(driver);
qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE);
@ -362,42 +244,14 @@ Design patterns
* Invoking a monitor command on a virDomainObjPtr with driver locked too
* Running asynchronous job
virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDomainObjBeginJobWithDriver(obj, QEMU_JOB_TYPE);
...do prep work...
if (virDomainObjIsActive(vm)) {
qemuDomainObjEnterMonitorWithDriver(driver, obj);
qemuMonitorXXXX(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, obj);
}
...do final work...
qemuDomainObjEndJob(obj);
virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
* Running asynchronous job with driver lock held
virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDomainObjBeginAsyncJobWithDriver(obj, QEMU_ASYNC_JOB_TYPE);
qemuDomainObjBeginAsyncJob(obj, QEMU_ASYNC_JOB_TYPE);
qemuDomainObjSetAsyncJobMask(obj, allowedJobs);
...do prep work...
@ -408,7 +262,7 @@ Design patterns
goto error;
}
...start qemu job...
qemuDomainObjExitMonitorWithDriver(driver, obj);
qemuDomainObjExitMonitor(driver, obj);
while (!finished) {
if (qemuDomainObjEnterMonitorAsync(driver, obj,
@ -417,7 +271,7 @@ Design patterns
goto error;
}
...monitor job progress...
qemuDomainObjExitMonitorWithDriver(driver, obj);
qemuDomainObjExitMonitor(driver, obj);
virObjectUnlock(obj);
sleep(aWhile);
@ -428,7 +282,6 @@ Design patterns
qemuDomainObjEndAsyncJob(obj);
virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
* Coordinating with a remote server for migration
@ -436,17 +289,16 @@ Design patterns
virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDomainObjBeginAsyncJobWithDriver(obj, QEMU_ASYNC_JOB_TYPE);
qemuDomainObjBeginAsyncJob(obj, QEMU_ASYNC_JOB_TYPE);
...do prep work...
if (virDomainObjIsActive(vm)) {
qemuDomainObjEnterRemoteWithDriver(driver, obj);
qemuDomainObjEnterRemote(obj);
...communicate with remote...
qemuDomainObjExitRemoteWithDriver(driver, obj);
qemuDomainObjExitRemote(obj);
/* domain may have been stopped while we were talking to remote */
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -458,14 +310,3 @@ Design patterns
qemuDomainObjEndAsyncJob(obj);
virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
Summary
-------
* Respect lock ordering rules: never lock driver if anything else is
already locked
* Don't hold locks in code which sleeps: unlock driver & virDomainObjPtr
when using monitor

View File

@ -1,7 +1,7 @@
/*
* qemu_conf.c: QEMU configuration management
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -79,11 +79,13 @@ struct _qemuDriverCloseDef {
qemuDriverCloseCallback cb;
};
void qemuDriverLock(virQEMUDriverPtr driver)
static void
qemuDriverLock(virQEMUDriverPtr driver)
{
virMutexLock(&driver->lock);
}
void qemuDriverUnlock(virQEMUDriverPtr driver)
static void
qemuDriverUnlock(virQEMUDriverPtr driver)
{
virMutexUnlock(&driver->lock);
}
@ -523,7 +525,11 @@ no_memory:
virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver)
{
return virObjectRef(driver->config);
virQEMUDriverConfigPtr conf;
qemuDriverLock(driver);
conf = virObjectRef(driver->config);
qemuDriverUnlock(driver);
return conf;
}
@ -613,16 +619,22 @@ err_exit:
virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
bool refresh)
{
virCapsPtr ret = NULL;
if (refresh) {
virCapsPtr caps = NULL;
if ((caps = virQEMUDriverCreateCapabilities(driver)) == NULL)
return NULL;
qemuDriverLock(driver);
virObjectUnref(driver->caps);
driver->caps = caps;
} else {
qemuDriverLock(driver);
}
return virObjectRef(driver->caps);
ret = virObjectRef(driver->caps);
qemuDriverUnlock(driver);
return ret;
}
@ -657,7 +669,9 @@ qemuDriverCloseCallbackSet(virQEMUDriverPtr driver,
{
char uuidstr[VIR_UUID_STRING_BUFLEN];
qemuDriverCloseDefPtr closeDef;
int ret = -1;
qemuDriverLock(driver);
virUUIDFormat(vm->def->uuid, uuidstr);
VIR_DEBUG("vm=%s, uuid=%s, conn=%p, cb=%p",
vm->def->name, uuidstr, conn, cb);
@ -669,30 +683,34 @@ qemuDriverCloseCallbackSet(virQEMUDriverPtr driver,
_("Close callback for domain %s already registered"
" with another connection %p"),
vm->def->name, closeDef->conn);
return -1;
goto cleanup;
}
if (closeDef->cb && closeDef->cb != cb) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Another close callback is already defined for"
" domain %s"), vm->def->name);
return -1;
goto cleanup;
}
closeDef->cb = cb;
} else {
if (VIR_ALLOC(closeDef) < 0) {
virReportOOMError();
return -1;
goto cleanup;
}
closeDef->conn = conn;
closeDef->cb = cb;
if (virHashAddEntry(driver->closeCallbacks, uuidstr, closeDef) < 0) {
VIR_FREE(closeDef);
return -1;
goto cleanup;
}
}
return 0;
ret = 0;
cleanup:
qemuDriverUnlock(driver);
return ret;
}
int
@ -702,23 +720,28 @@ qemuDriverCloseCallbackUnset(virQEMUDriverPtr driver,
{
char uuidstr[VIR_UUID_STRING_BUFLEN];
qemuDriverCloseDefPtr closeDef;
int ret = -1;
qemuDriverLock(driver);
virUUIDFormat(vm->def->uuid, uuidstr);
VIR_DEBUG("vm=%s, uuid=%s, cb=%p",
vm->def->name, uuidstr, cb);
closeDef = virHashLookup(driver->closeCallbacks, uuidstr);
if (!closeDef)
return -1;
goto cleanup;
if (closeDef->cb && closeDef->cb != cb) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Trying to remove mismatching close callback for"
" domain %s"), vm->def->name);
return -1;
goto cleanup;
}
return virHashRemoveEntry(driver->closeCallbacks, uuidstr);
ret = virHashRemoveEntry(driver->closeCallbacks, uuidstr);
cleanup:
qemuDriverUnlock(driver);
return ret;
}
qemuDriverCloseCallback
@ -730,6 +753,7 @@ qemuDriverCloseCallbackGet(virQEMUDriverPtr driver,
qemuDriverCloseDefPtr closeDef;
qemuDriverCloseCallback cb = NULL;
qemuDriverLock(driver);
virUUIDFormat(vm->def->uuid, uuidstr);
VIR_DEBUG("vm=%s, uuid=%s, conn=%p",
vm->def->name, uuidstr, conn);
@ -739,6 +763,7 @@ qemuDriverCloseCallbackGet(virQEMUDriverPtr driver,
cb = closeDef->cb;
VIR_DEBUG("cb=%p", cb);
qemuDriverUnlock(driver);
return cb;
}
@ -794,8 +819,9 @@ qemuDriverCloseCallbackRunAll(virQEMUDriverPtr driver,
driver, conn
};
VIR_DEBUG("conn=%p", conn);
qemuDriverLock(driver);
virHashForEach(driver->closeCallbacks, qemuDriverCloseCallbackRun, &data);
qemuDriverUnlock(driver);
}
/* Construct the hash key for sharedDisks as "major:minor" */
@ -832,6 +858,7 @@ qemuAddSharedDisk(virQEMUDriverPtr driver,
char *key = NULL;
int ret = -1;
qemuDriverLock(driver);
if (!(key = qemuGetSharedDiskKey(disk_path)))
goto cleanup;
@ -845,6 +872,7 @@ qemuAddSharedDisk(virQEMUDriverPtr driver,
ret = 0;
cleanup:
qemuDriverUnlock(driver);
VIR_FREE(key);
return ret;
}
@ -860,6 +888,7 @@ qemuRemoveSharedDisk(virQEMUDriverPtr driver,
char *key = NULL;
int ret = -1;
qemuDriverLock(driver);
if (!(key = qemuGetSharedDiskKey(disk_path)))
goto cleanup;
@ -876,6 +905,7 @@ qemuRemoveSharedDisk(virQEMUDriverPtr driver,
ret = 0;
cleanup:
qemuDriverUnlock(driver);
VIR_FREE(key);
return ret;
}

View File

@ -1,7 +1,7 @@
/*
* qemu_conf.h: QEMU configuration management
*
* Copyright (C) 2006-2007, 2009-2012 Red Hat, Inc.
* Copyright (C) 2006-2007, 2009-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -236,9 +236,6 @@ struct _qemuDomainCmdlineDef {
# define QEMUD_MIGRATION_NUM_PORTS 64
void qemuDriverLock(virQEMUDriverPtr driver);
void qemuDriverUnlock(virQEMUDriverPtr driver);
virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged);
int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,

View File

@ -1,7 +1,7 @@
/*
* qemu_domain.h: QEMU domain private state
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -116,7 +116,6 @@ qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job,
}
/* driver must be locked before calling */
void qemuDomainEventQueue(virQEMUDriverPtr driver,
virDomainEventPtr event)
{
@ -760,12 +759,10 @@ qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv, enum qemuDomainJob job)
#define QEMU_JOB_WAIT_TIME (1000ull * 30)
/*
* obj must be locked before calling; driver_locked says if qemu_driver is
* locked or not.
* obj must be locked before calling
*/
static int ATTRIBUTE_NONNULL(1)
qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
bool driver_locked,
virDomainObjPtr obj,
enum qemuDomainJob job,
enum qemuDomainAsyncJob asyncJob)
@ -786,8 +783,6 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
then = now + QEMU_JOB_WAIT_TIME;
virObjectRef(obj);
if (driver_locked)
qemuDriverUnlock(driver);
retry:
if (cfg->maxQueuedJobs &&
@ -827,12 +822,6 @@ retry:
priv->job.start = now;
}
if (driver_locked) {
virObjectUnlock(obj);
qemuDriverLock(driver);
virObjectLock(obj);
}
if (qemuDomainTrackJob(job))
qemuDomainObjSaveJob(driver, obj);
@ -861,18 +850,13 @@ error:
virReportSystemError(errno,
"%s", _("cannot acquire job mutex"));
priv->jobs_queued--;
if (driver_locked) {
virObjectUnlock(obj);
qemuDriverLock(driver);
virObjectLock(obj);
}
virObjectUnref(obj);
virObjectUnref(cfg);
return -1;
}
/*
* obj must be locked before calling, driver must NOT be locked
* obj must be locked before calling
*
* This must be called by anything that will change the VM state
* in any way, or anything that will use the QEMU monitor.
@ -884,7 +868,7 @@ int qemuDomainObjBeginJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainJob job)
{
return qemuDomainObjBeginJobInternal(driver, false, obj, job,
return qemuDomainObjBeginJobInternal(driver, obj, job,
QEMU_ASYNC_JOB_NONE);
}
@ -892,43 +876,13 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
{
return qemuDomainObjBeginJobInternal(driver, false, obj, QEMU_JOB_ASYNC,
return qemuDomainObjBeginJobInternal(driver, obj, QEMU_JOB_ASYNC,
asyncJob);
}
/*
* obj and driver must be locked before calling.
*
* 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
*/
int qemuDomainObjBeginJobWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainJob job)
{
if (job <= QEMU_JOB_NONE || job >= QEMU_JOB_ASYNC) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Attempt to start invalid job"));
return -1;
}
return qemuDomainObjBeginJobInternal(driver, true, obj, job,
QEMU_ASYNC_JOB_NONE);
}
int qemuDomainObjBeginAsyncJobWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
{
return qemuDomainObjBeginJobInternal(driver, true, obj, QEMU_JOB_ASYNC,
asyncJob);
}
/*
* obj must be locked before calling, driver does not matter
* obj must be locked before calling
*
* To be called after completing the work associated with the
* earlier qemuDomainBeginJob() call
@ -983,9 +937,17 @@ qemuDomainObjAbortAsyncJob(virDomainObjPtr obj)
priv->job.asyncAbort = true;
}
/*
* obj must be locked before calling
*
* To be called immediately before any QEMU monitor API call
* Must have already either called qemuDomainObjBeginJob() and checked
* that the VM is still active; may not be used for nested async jobs.
*
* To be followed with qemuDomainObjExitMonitor() once complete
*/
static int
qemuDomainObjEnterMonitorInternal(virQEMUDriverPtr driver,
bool driver_locked,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
{
@ -1000,7 +962,7 @@ qemuDomainObjEnterMonitorInternal(virQEMUDriverPtr driver,
if (priv->job.asyncOwner != virThreadSelfID())
VIR_WARN("This thread doesn't seem to be the async job owner: %d",
priv->job.asyncOwner);
if (qemuDomainObjBeginJobInternal(driver, driver_locked, obj,
if (qemuDomainObjBeginJobInternal(driver, obj,
QEMU_JOB_ASYNC_NESTED,
QEMU_ASYNC_JOB_NONE) < 0)
return -1;
@ -1020,15 +982,12 @@ qemuDomainObjEnterMonitorInternal(virQEMUDriverPtr driver,
virObjectRef(priv->mon);
ignore_value(virTimeMillisNow(&priv->monStart));
virObjectUnlock(obj);
if (driver_locked)
qemuDriverUnlock(driver);
return 0;
}
static void ATTRIBUTE_NONNULL(1)
qemuDomainObjExitMonitorInternal(virQEMUDriverPtr driver,
bool driver_locked,
virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
@ -1039,8 +998,6 @@ qemuDomainObjExitMonitorInternal(virQEMUDriverPtr driver,
if (hasRefs)
virObjectUnlock(priv->mon);
if (driver_locked)
qemuDriverLock(driver);
virObjectLock(obj);
priv->monStart = 0;
@ -1056,59 +1013,34 @@ qemuDomainObjExitMonitorInternal(virQEMUDriverPtr driver,
}
}
/*
* obj must be locked before calling, driver must be unlocked
*
* To be called immediately before any QEMU monitor API call
* Must have already either called qemuDomainObjBeginJob() and checked
* that the VM is still active; may not be used for nested async jobs.
*
* To be followed with qemuDomainObjExitMonitor() once complete
*/
void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
ignore_value(qemuDomainObjEnterMonitorInternal(driver, false, obj,
ignore_value(qemuDomainObjEnterMonitorInternal(driver, obj,
QEMU_ASYNC_JOB_NONE));
}
/* obj must NOT be locked before calling, driver must be unlocked
/* obj must NOT be locked before calling
*
* Should be paired with an earlier qemuDomainObjEnterMonitor() call
*/
void qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
qemuDomainObjExitMonitorInternal(driver, false, obj);
qemuDomainObjExitMonitorInternal(driver, obj);
}
/*
* obj must be locked before calling, driver must be locked
*
* To be called immediately before any QEMU monitor API call
* Must have already either called qemuDomainObjBeginJobWithDriver() and
* checked that the VM is still active; may not be used for nested async jobs.
*
* To be followed with qemuDomainObjExitMonitorWithDriver() once complete
*/
void qemuDomainObjEnterMonitorWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
ignore_value(qemuDomainObjEnterMonitorInternal(driver, true, obj,
QEMU_ASYNC_JOB_NONE));
}
/*
* obj and driver must be locked before calling
* obj must be locked before calling
*
* To be called immediately before any QEMU monitor API call.
* Must have already either called qemuDomainObjBeginJobWithDriver()
* Must have already either called qemuDomainObjBeginJob()
* and checked that the VM is still active, with asyncJob of
* QEMU_ASYNC_JOB_NONE; or already called qemuDomainObjBeginAsyncJob,
* with the same asyncJob.
*
* Returns 0 if job was started, in which case this must be followed with
* qemuDomainObjExitMonitorWithDriver(); or -1 if the job could not be
* qemuDomainObjExitMonitor(); or -1 if the job could not be
* started (probably because the vm exited in the meantime).
*/
int
@ -1116,26 +1048,22 @@ qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
{
return qemuDomainObjEnterMonitorInternal(driver, true, obj, asyncJob);
return qemuDomainObjEnterMonitorInternal(driver, obj, asyncJob);
}
/* obj must NOT be locked before calling, driver must be unlocked,
* and will be locked after returning
/*
* obj must be locked before calling
*
* Should be paired with an earlier qemuDomainObjEnterMonitorWithDriver() call
* To be called immediately before any QEMU agent API call.
* Must have already called qemuDomainObjBeginJob() and checked
* that the VM is still active.
*
* To be followed with qemuDomainObjExitAgent() once complete
*/
void qemuDomainObjExitMonitorWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
qemuDomainObjExitMonitorInternal(driver, true, obj);
}
static int
qemuDomainObjEnterAgentInternal(virQEMUDriverPtr driver,
bool driver_locked,
virDomainObjPtr obj)
void
qemuDomainObjEnterAgent(virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
@ -1143,16 +1071,15 @@ qemuDomainObjEnterAgentInternal(virQEMUDriverPtr driver,
virObjectRef(priv->agent);
ignore_value(virTimeMillisNow(&priv->agentStart));
virObjectUnlock(obj);
if (driver_locked)
qemuDriverUnlock(driver);
return 0;
}
static void ATTRIBUTE_NONNULL(1)
qemuDomainObjExitAgentInternal(virQEMUDriverPtr driver,
bool driver_locked,
virDomainObjPtr obj)
/* obj must NOT be locked before calling
*
* Should be paired with an earlier qemuDomainObjEnterAgent() call
*/
void
qemuDomainObjExitAgent(virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
bool hasRefs;
@ -1162,8 +1089,6 @@ qemuDomainObjExitAgentInternal(virQEMUDriverPtr driver,
if (hasRefs)
virObjectUnlock(priv->agent);
if (driver_locked)
qemuDriverLock(driver);
virObjectLock(obj);
priv->agentStart = 0;
@ -1171,69 +1096,14 @@ qemuDomainObjExitAgentInternal(virQEMUDriverPtr driver,
priv->agent = NULL;
}
/*
* obj must be locked before calling, driver must be unlocked
*
* To be called immediately before any QEMU agent API call.
* Must have already called qemuDomainObjBeginJob() and checked
* that the VM is still active.
*
* To be followed with qemuDomainObjExitAgent() once complete
*/
void qemuDomainObjEnterAgent(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
ignore_value(qemuDomainObjEnterAgentInternal(driver, false, obj));
}
/* obj must NOT be locked before calling, driver must be unlocked
*
* Should be paired with an earlier qemuDomainObjEnterAgent() call
*/
void qemuDomainObjExitAgent(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
qemuDomainObjExitAgentInternal(driver, false, obj);
}
/*
* obj must be locked before calling, driver must be locked
*
* To be called immediately before any QEMU agent API call.
* Must have already called qemuDomainObjBeginJobWithDriver() and
* checked that the VM is still active; may not be used for nested async jobs.
*
* To be followed with qemuDomainObjExitAgentWithDriver() once complete
*/
void qemuDomainObjEnterAgentWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
ignore_value(qemuDomainObjEnterAgentInternal(driver, true, obj));
}
/* obj must NOT be locked before calling, driver must be unlocked,
* and will be locked after returning
*
* Should be paired with an earlier qemuDomainObjEnterAgentWithDriver() call
*/
void qemuDomainObjExitAgentWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
{
qemuDomainObjExitAgentInternal(driver, true, obj);
}
void qemuDomainObjEnterRemoteWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
void qemuDomainObjEnterRemote(virDomainObjPtr obj)
{
virObjectRef(obj);
virObjectUnlock(obj);
qemuDriverUnlock(driver);
}
void qemuDomainObjExitRemoteWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
void qemuDomainObjExitRemote(virDomainObjPtr obj)
{
qemuDriverLock(driver);
virObjectLock(obj);
virObjectUnref(obj);
}
@ -1783,10 +1653,10 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
goto cleanup;
} else {
priv = vm->privateData;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
/* we continue on even in the face of error */
qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
}
@ -1863,7 +1733,7 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
}
/*
* The caller must hold a lock on both driver and vm, and there must
* The caller must hold a lock the vm and there must
* be no remaining references to vm.
*/
void

View File

@ -1,7 +1,7 @@
/*
* qemu_domain.h: QEMU domain private state
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -175,7 +175,6 @@ int qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job,
void qemuDomainEventFlush(int timer, void *opaque);
/* driver must be locked before calling */
void qemuDomainEventQueue(virQEMUDriverPtr driver,
virDomainEventPtr event);
@ -190,14 +189,6 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_RETURN_CHECK;
int qemuDomainObjBeginJobWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainJob job)
ATTRIBUTE_RETURN_CHECK;
int qemuDomainObjBeginAsyncJobWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_RETURN_CHECK;
bool qemuDomainObjEndJob(virQEMUDriverPtr driver,
virDomainObjPtr obj)
@ -224,38 +215,22 @@ void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
void qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjEnterMonitorWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
void qemuDomainObjExitMonitorWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjEnterAgent(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjExitAgent(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjEnterAgentWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjExitAgentWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjEnterAgent(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
void qemuDomainObjExitAgent(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
void qemuDomainObjEnterRemoteWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjExitRemoteWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjEnterRemote(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
void qemuDomainObjExitRemote(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
int qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
virDomainDefPtr vm,

File diff suppressed because it is too large Load Diff

View File

@ -107,7 +107,7 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps)))
goto error;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
/* we don't want to report errors from media tray_open polling */
@ -144,7 +144,7 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
disk->src, format);
}
exit_monitor:
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, origdisk->src, disk->src, "update", ret >= 0);
@ -194,7 +194,7 @@ qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
table = qemuMonitorGetBlockInfo(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
if (!table)
@ -276,7 +276,7 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
goto error;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) {
@ -305,7 +305,7 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
}
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
@ -381,7 +381,7 @@ int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDevice(priv->mon, devstr);
} else {
@ -389,7 +389,7 @@ int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver,
type,
&controller->info.addr.pci);
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (ret == 0) {
controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
@ -529,7 +529,7 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn,
goto error;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) {
@ -555,7 +555,7 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn,
disk->info.addr.drive.unit = driveAddr.unit;
}
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
@ -633,7 +633,7 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
goto error;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) {
@ -648,7 +648,7 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
} else {
ret = qemuMonitorAddUSBDisk(priv->mon, disk->src);
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
@ -807,24 +807,24 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name,
vhostfd, vhostfd_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false);
goto cleanup;
}
} else {
if (qemuMonitorAddHostNetwork(priv->mon, netstr, tapfd, tapfd_name,
vhostfd, vhostfd_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false);
goto cleanup;
}
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
VIR_FORCE_CLOSE(tapfd);
VIR_FORCE_CLOSE(vhostfd);
@ -843,10 +843,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
goto try_remove;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false);
goto try_remove;
}
@ -854,14 +854,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
guestAddr = net->info.addr.pci;
if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
&guestAddr) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false);
goto try_remove;
}
net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
/* set link state */
if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
@ -869,11 +869,11 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("device alias not found: cannot set link state to down"));
} else {
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false);
goto try_remove;
}
@ -882,7 +882,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
_("setting of link state not supported: Link is up"));
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
/* link set to down */
}
@ -934,11 +934,11 @@ try_remove:
char *netdev_name;
if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0)
goto no_memory;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
VIR_WARN("Failed to remove network backend for netdev %s",
netdev_name);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
VIR_FREE(netdev_name);
} else {
VIR_WARN("Unable to remove network backend");
@ -947,11 +947,11 @@ try_remove:
char *hostnet_name;
if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
goto no_memory;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
VIR_WARN("Failed to remove network backend for vlan %d, net %s",
vlan, hostnet_name);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
VIR_FREE(hostnet_name);
}
goto cleanup;
@ -1009,18 +1009,18 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
priv->qemuCaps)))
goto error;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
configfd, configfd_name);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
} else {
virDevicePCIAddress guestAddr = hostdev->info->addr.pci;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorAddPCIHostDevice(priv->mon,
&hostdev->source.subsys.u.pci,
&guestAddr);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
memcpy(&hostdev->info->addr.pci, &guestAddr, sizeof(guestAddr));
@ -1076,13 +1076,13 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
goto error;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
ret = qemuMonitorAddDevice(priv->mon, devstr);
else
goto error;
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
if (ret < 0)
goto error;
@ -1146,14 +1146,14 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
virUSBDeviceFree(usb);
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
ret = qemuMonitorAddDevice(priv->mon, devstr);
else
ret = qemuMonitorAddUSBDeviceExact(priv->mon,
hostdev->source.subsys.u.usb.bus,
hostdev->source.subsys.u.usb.device);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
if (ret < 0)
goto error;
@ -1421,7 +1421,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
return -1;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
if (ret < 0)
@ -1431,7 +1431,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
dev->linkstate = linkstate;
cleanup:
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
return ret;
}
@ -2059,17 +2059,17 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
goto cleanup;
}
} else {
if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
goto cleanup;
}
@ -2078,7 +2078,7 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
/* disconnect guest from host device */
qemuMonitorDriveDel(priv->mon, drivestr);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", true);
@ -2165,9 +2165,9 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
goto cleanup;
}
@ -2175,7 +2175,7 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
/* disconnect guest from host device */
qemuMonitorDriveDel(priv->mon, drivestr);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", true);
@ -2301,20 +2301,20 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
} else {
if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainControllerRemove(vm->def, idx);
virDomainControllerDefFree(detach);
@ -2357,13 +2357,13 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
rv = qemuMonitorDelDevice(priv->mon, detach->info->alias);
} else {
rv = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditHostdev(vm, detach, "detach", rv == 0);
if (rv < 0)
goto cleanup;
@ -2427,9 +2427,9 @@ qemuDomainDetachHostUsbDevice(virQEMUDriverPtr driver,
return -1;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditHostdev(vm, detach, "detach", ret == 0);
if (ret < 0)
return -1;
@ -2613,17 +2613,17 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup;
}
} else {
if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup;
}
@ -2632,18 +2632,18 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup;
}
} else {
if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup;
}
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", true);
@ -2713,7 +2713,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
if (auth->connected)
connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetPassword(priv->mon,
type,
auth->passwd ? auth->passwd : defaultPasswd,
@ -2756,7 +2756,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
}
end_job:
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
cleanup:
virObjectUnref(cfg);
return ret;

View File

@ -2,7 +2,7 @@
/*
* qemu_migration.c: QEMU migration handling
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2013 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
@ -1188,7 +1188,7 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
ret = qemuMonitorGetSpiceMigrationStatus(priv->mon,
&spice_migrated);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (ret < 0 || virTimeMillisNow(&priv->job.info.timeElapsed) < 0) {
priv->job.info.type = VIR_DOMAIN_JOB_FAILED;
@ -1277,11 +1277,9 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver, virDomainObjPtr vm,
}
virObjectUnlock(vm);
qemuDriverUnlock(driver);
nanosleep(&ts, NULL);
qemuDriverLock(driver);
virObjectLock(vm);
}
@ -1322,7 +1320,7 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
cookie->graphics->port,
cookie->graphics->tlsPort,
cookie->graphics->tlsSubject);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
return ret;
@ -2265,7 +2263,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
/* explicitly do this *after* we entered the monitor,
* as this is a critical section so we are guaranteed
* priv->job.asyncAbort will not change */
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
_("canceled by client"));
@ -2273,7 +2271,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
}
if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
@ -2286,7 +2284,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
/* connect to the destination qemu if needed */
if (spec->destType == MIGRATION_DEST_CONNECT_HOST &&
qemuMigrationConnect(driver, vm, spec) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
@ -2323,7 +2321,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
VIR_FORCE_CLOSE(spec->dest.fd.qemu);
break;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (ret < 0)
goto cleanup;
ret = -1;
@ -2412,7 +2410,7 @@ cancel:
if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
qemuMonitorMigrateCancel(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
}
goto cleanup;
@ -2615,23 +2613,23 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver,
if (!(st = virStreamNew(dconn, 0)))
goto cleanup;
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
ret = dconn->driver->domainMigratePrepareTunnel
(dconn, st, flags, dname, resource, dom_xml);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
} else {
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
ret = dconn->driver->domainMigratePrepare2
(dconn, &cookie, &cookielen, NULL, &uri_out,
flags, dname, resource, dom_xml);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
}
VIR_FREE(dom_xml);
if (ret == -1)
goto cleanup;
/* the domain may have shutdown or crashed while we had the locks dropped
* in qemuDomainObjEnterRemoteWithDriver, so check again
* in qemuDomainObjEnterRemote, so check again
*/
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -2678,11 +2676,11 @@ finish:
*/
dname = dname ? dname : vm->def->name;
VIR_DEBUG("Finish2 %p ret=%d", dconn, ret);
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
ddomain = dconn->driver->domainMigrateFinish2
(dconn, dname, cookie, cookielen,
uri_out ? uri_out : dconnuri, flags, cancelled);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
cleanup:
if (ddomain) {
@ -2759,18 +2757,18 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
if (!(st = virStreamNew(dconn, 0)))
goto cleanup;
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
ret = dconn->driver->domainMigratePrepareTunnel3
(dconn, st, cookiein, cookieinlen,
&cookieout, &cookieoutlen,
flags, dname, resource, dom_xml);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
} else {
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
ret = dconn->driver->domainMigratePrepare3
(dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
uri, &uri_out, flags, dname, resource, dom_xml);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
}
VIR_FREE(dom_xml);
if (ret == -1)
@ -2842,11 +2840,11 @@ finish:
cookieout = NULL;
cookieoutlen = 0;
dname = dname ? dname : vm->def->name;
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
ddomain = dconn->driver->domainMigrateFinish3
(dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
dconnuri, uri_out ? uri_out : uri, flags, cancelled);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
/* If ddomain is NULL, then we were unable to start
* the guest on the target, and must restart on the
@ -2934,9 +2932,9 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
* destination side is completely setup before we touch the source
*/
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
dconn = virConnectOpen(dconnuri);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
if (dconn == NULL) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("Failed to connect to remote libvirt URI %s"), dconnuri);
@ -2948,7 +2946,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
cfg->keepAliveCount) < 0)
goto cleanup;
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
p2p = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_P2P);
/* v3proto reflects whether the caller used Perform3, but with
@ -2960,7 +2958,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
if (flags & VIR_MIGRATE_OFFLINE)
offline = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_OFFLINE);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
if (!p2p) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
@ -2998,9 +2996,9 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
cleanup:
orig_err = virSaveLastError();
qemuDomainObjEnterRemoteWithDriver(driver, vm);
qemuDomainObjEnterRemote(vm);
virConnectClose(dconn);
qemuDomainObjExitRemoteWithDriver(driver, vm);
qemuDomainObjExitRemote(vm);
if (orig_err) {
virSetError(orig_err);
virFreeError(orig_err);
@ -3622,7 +3620,7 @@ cleanup:
}
/* Helper function called while driver lock is held and vm is active. */
/* Helper function called while vm is active. */
int
qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
int fd, off_t offset, const char *path,
@ -3646,7 +3644,7 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
qemuMonitorSetMigrationSpeed(priv->mon,
QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
@ -3726,11 +3724,11 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
if (virSetCloseExec(pipeFD[1]) < 0) {
virReportSystemError(errno, "%s",
_("Unable to set cloexec flag"));
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
if (virCommandRunAsync(cmd, NULL) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
rc = qemuMonitorMigrateToFd(priv->mon,
@ -3745,7 +3743,7 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
args, path, offset);
}
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (rc < 0)
goto cleanup;
@ -3765,7 +3763,7 @@ cleanup:
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth);
priv->migMaxBandwidth = saveMigBandwidth;
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
VIR_FORCE_CLOSE(pipeFD[0]);
@ -3799,7 +3797,7 @@ qemuMigrationJobStart(virQEMUDriverPtr driver,
{
qemuDomainObjPrivatePtr priv = vm->privateData;
if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm, job) < 0)
if (qemuDomainObjBeginAsyncJob(driver, vm, job) < 0)
return -1;
if (job == QEMU_ASYNC_JOB_MIGRATION_IN) {

View File

@ -1,7 +1,7 @@
/*
* qemu_process.h: QEMU process management
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2013 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
@ -129,12 +129,10 @@ static void
qemuProcessHandleAgentEOF(qemuAgentPtr agent,
virDomainObjPtr vm)
{
virQEMUDriverPtr driver = qemu_driver;
qemuDomainObjPrivatePtr priv;
VIR_DEBUG("Received EOF from agent on %p '%s'", vm, vm->def->name);
qemuDriverLock(driver);
virObjectLock(vm);
priv = vm->privateData;
@ -152,14 +150,12 @@ qemuProcessHandleAgentEOF(qemuAgentPtr agent,
priv->agent = NULL;
virObjectUnlock(vm);
qemuDriverUnlock(driver);
qemuAgentClose(agent);
return;
unlock:
virObjectUnlock(vm);
qemuDriverUnlock(driver);
return;
}
@ -174,12 +170,10 @@ static void
qemuProcessHandleAgentError(qemuAgentPtr agent ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
virQEMUDriverPtr driver = qemu_driver;
qemuDomainObjPrivatePtr priv;
VIR_DEBUG("Received error from agent on %p '%s'", vm, vm->def->name);
qemuDriverLock(driver);
virObjectLock(vm);
priv = vm->privateData;
@ -187,7 +181,6 @@ qemuProcessHandleAgentError(qemuAgentPtr agent ATTRIBUTE_UNUSED,
priv->agentError = true;
virObjectUnlock(vm);
qemuDriverUnlock(driver);
}
static void qemuProcessHandleAgentDestroy(qemuAgentPtr agent,
@ -250,13 +243,11 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
ignore_value(virTimeMillisNow(&priv->agentStart));
virObjectUnlock(vm);
qemuDriverUnlock(driver);
agent = qemuAgentOpen(vm,
config,
&agentCallbacks);
qemuDriverLock(driver);
virObjectLock(vm);
priv->agentStart = 0;
@ -307,7 +298,6 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name);
qemuDriverLock(driver);
virObjectLock(vm);
priv = vm->privateData;
@ -347,7 +337,6 @@ unlock:
cleanup:
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
@ -366,7 +355,6 @@ qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_DEBUG("Received error on %p '%s'", vm, vm->def->name);
qemuDriverLock(driver);
virObjectLock(vm);
((qemuDomainObjPrivatePtr) vm->privateData)->monError = true;
@ -375,7 +363,6 @@ qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
qemuDomainEventQueue(driver, event);
virObjectUnlock(vm);
qemuDriverUnlock(driver);
}
@ -543,11 +530,8 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
return 0;
}
@ -570,7 +554,6 @@ qemuProcessFakeReboot(void *opaque)
virDomainEventPtr event = NULL;
int ret = -1;
VIR_DEBUG("vm=%p", vm);
qemuDriverLock(driver);
virObjectLock(vm);
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
@ -581,12 +564,12 @@ qemuProcessFakeReboot(void *opaque)
goto endjob;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorSystemReset(priv->mon) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto endjob;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -616,15 +599,13 @@ endjob:
cleanup:
if (vm) {
if (ret == -1) {
ignore_value(qemuProcessKill(driver, vm,
VIR_QEMU_PROCESS_KILL_FORCE));
ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE));
}
if (virObjectUnref(vm))
virObjectUnlock(vm);
}
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
@ -643,12 +624,11 @@ qemuProcessShutdownOrReboot(virQEMUDriverPtr driver,
qemuProcessFakeReboot,
vm) < 0) {
VIR_ERROR(_("Failed to create reboot thread, killing domain"));
ignore_value(qemuProcessKill(driver, vm,
VIR_QEMU_PROCESS_KILL_NOWAIT));
ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
virObjectUnref(vm);
}
} else {
ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
}
}
@ -703,11 +683,8 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
unlock:
virObjectUnlock(vm);
cleanup:
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
virObjectUnref(caps);
virObjectUnref(cfg);
@ -759,11 +736,8 @@ unlock:
virObjectUnlock(vm);
cleanup:
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
virObjectUnref(caps);
virObjectUnref(cfg);
@ -821,11 +795,8 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
unlock:
virObjectUnlock(vm);
cleanup:
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -857,11 +828,8 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -929,14 +897,10 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (watchdogEvent || lifecycleEvent) {
qemuDriverLock(driver);
if (watchdogEvent)
qemuDomainEventQueue(driver, watchdogEvent);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
qemuDriverUnlock(driver);
}
if (watchdogEvent)
qemuDomainEventQueue(driver, watchdogEvent);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(caps);
virObjectUnref(cfg);
@ -999,16 +963,12 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (ioErrorEvent || ioErrorEvent2 || lifecycleEvent) {
qemuDriverLock(driver);
if (ioErrorEvent)
qemuDomainEventQueue(driver, ioErrorEvent);
if (ioErrorEvent2)
qemuDomainEventQueue(driver, ioErrorEvent2);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
qemuDriverUnlock(driver);
}
if (ioErrorEvent)
qemuDomainEventQueue(driver, ioErrorEvent);
if (ioErrorEvent2)
qemuDomainEventQueue(driver, ioErrorEvent2);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -1050,11 +1010,8 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
return 0;
}
@ -1117,11 +1074,8 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject);
virObjectUnlock(vm);
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
return 0;
@ -1192,11 +1146,8 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -1240,14 +1191,10 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (event || lifecycleEvent) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
qemuDriverUnlock(driver);
}
if (event)
qemuDomainEventQueue(driver, event);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -1293,14 +1240,10 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (event || lifecycleEvent) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
qemuDriverUnlock(driver);
}
if (event)
qemuDomainEventQueue(driver, event);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -1332,11 +1275,8 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (event) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
@ -1382,14 +1322,10 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectUnlock(vm);
cleanup:
if (event || lifecycleEvent) {
qemuDriverLock(driver);
if (event)
qemuDomainEventQueue(driver, event);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
qemuDriverUnlock(driver);
}
if (event)
qemuDomainEventQueue(driver, event);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(caps);
virObjectUnref(cfg);
@ -1438,14 +1374,12 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm)
ignore_value(virTimeMillisNow(&priv->monStart));
virObjectUnlock(vm);
qemuDriverUnlock(driver);
mon = qemuMonitorOpen(vm,
priv->monConfig,
priv->monJSON,
&monitorCallbacks);
qemuDriverLock(driver);
virObjectLock(vm);
priv->monStart = 0;
@ -1469,12 +1403,12 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm)
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetCapabilities(priv->mon);
if (ret == 0 &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON))
ret = virQEMUCapsProbeQMP(priv->qemuCaps, priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
error:
@ -1850,9 +1784,9 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
goto cleanup;
priv = vm->privateData;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorGetPtyPaths(priv->mon, paths);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
VIR_DEBUG("qemuMonitorGetPtyPaths returned %i", ret);
if (ret == 0)
@ -1900,12 +1834,12 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
int ncpupids;
qemuDomainObjPrivatePtr priv = vm->privateData;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
/* failure to get the VCPU<-> PID mapping or to execute the query
* command will not be treated fatal as some versions of qemu don't
* support this command */
if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) <= 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
virResetLastError();
priv->nvcpupids = 1;
@ -1916,7 +1850,7 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
priv->vcpupids[0] = vm->pid;
return 0;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (ncpupids != vm->def->vcpus) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@ -2309,10 +2243,10 @@ qemuProcessInitPasswords(virConnectPtr conn,
goto cleanup;
alias = vm->def->disks[i]->info.alias;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret);
VIR_FREE(secret);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (ret < 0)
goto cleanup;
}
@ -2701,10 +2635,10 @@ qemuProcessInitPCIAddresses(virQEMUDriverPtr driver,
int ret;
qemuMonitorPCIAddress *addrs = NULL;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
naddrs = qemuMonitorGetAllPCIAddresses(priv->mon,
&addrs);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
ret = qemuProcessDetectPCIAddresses(vm, addrs, naddrs);
@ -2860,9 +2794,8 @@ qemuProcessPrepareMonitorChr(virQEMUDriverConfigPtr cfg,
/*
* Precondition: Both driver and vm must be locked,
* and a job must be active. This method will call
* {Enter,Exit}MonitorWithDriver
* Precondition: vm must be locked, and a job must be active.
* This method will call {Enter,Exit}Monitor
*/
int
qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
@ -2887,7 +2820,7 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
if (ret == 0) {
ret = qemuMonitorStartCPUs(priv->mon, conn);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
if (ret == 0) {
@ -2916,7 +2849,7 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
if (ret == 0) {
ret = qemuMonitorStopCPUs(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
}
if (ret == 0) {
@ -2979,9 +2912,9 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
char *msg = NULL;
int ret;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorGetStatus(priv->mon, &running, &reason);
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (ret < 0 || !virDomainObjIsActive(vm))
return -1;
@ -3264,7 +3197,6 @@ qemuProcessReconnect(void *opaque)
VIR_FREE(data);
qemuDriverLock(driver);
virObjectLock(obj);
cfg = virQEMUDriverGetConfig(driver);
@ -3383,8 +3315,6 @@ endjob:
if (obj && virObjectUnref(obj))
virObjectUnlock(obj);
qemuDriverUnlock(driver);
virConnectClose(conn);
virObjectUnref(cfg);
virObjectUnref(caps);
@ -3399,7 +3329,6 @@ error:
if (!virDomainObjIsActive(obj)) {
if (virObjectUnref(obj))
virObjectUnlock(obj);
qemuDriverUnlock(driver);
return;
}
@ -3425,7 +3354,6 @@ error:
virObjectUnlock(obj);
}
}
qemuDriverUnlock(driver);
virConnectClose(conn);
virObjectUnref(caps);
virObjectUnref(cfg);
@ -3447,23 +3375,15 @@ qemuProcessReconnectHelper(virDomainObjPtr obj,
memcpy(data, src, sizeof(*data));
data->payload = obj;
/* This iterator is called with driver being locked.
/*
* We create a separate thread to run qemuProcessReconnect in it.
* However, qemuProcessReconnect needs to:
* 1. lock driver
* 2. just before monitor reconnect do lightweight MonitorEnter
* 1. just before monitor reconnect do lightweight MonitorEnter
* (increase VM refcount, unlock VM & driver)
* 3. reconnect to monitor
* 4. do lightweight MonitorExit (lock driver & VM)
* 5. continue reconnect process
* 6. EndJob
* 7. unlock driver
*
* It is necessary to NOT hold driver lock for the entire run
* of reconnect, otherwise we will get blocked if there is
* unresponsive qemu.
* However, iterating over hash table MUST be done on locked
* driver.
* 2. reconnect to monitor
* 3. do lightweight MonitorExit (lock VM)
* 4. continue reconnect process
* 5. EndJob
*
* NB, we can't do normal MonitorEnter & MonitorExit because
* these two lock the monitor lock, which does not exists in
@ -3474,7 +3394,7 @@ qemuProcessReconnectHelper(virDomainObjPtr obj,
qemuDomainObjRestoreJob(obj, &data->oldjob);
if (qemuDomainObjBeginJobWithDriver(src->driver, obj, QEMU_JOB_MODIFY) < 0)
if (qemuDomainObjBeginJob(src->driver, obj, QEMU_JOB_MODIFY) < 0)
goto error;
/* Since we close the connection later on, we have to make sure
@ -4111,13 +4031,13 @@ int qemuProcessStart(virConnectPtr conn,
/* qemu doesn't support setting this on the command line, so
* enter the monitor */
VIR_DEBUG("Setting network link states");
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuProcessSetLinkStates(vm) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
/* Technically, qemuProcessStart can be called from inside
* QEMU_ASYNC_JOB_MIGRATION_IN, but we are okay treating this like
@ -4131,12 +4051,12 @@ int qemuProcessStart(virConnectPtr conn,
vm->def->mem.cur_balloon);
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorSetBalloon(priv->mon, cur_balloon) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (!(flags & VIR_QEMU_PROCESS_START_PAUSED)) {
VIR_DEBUG("Starting domain CPUs");
@ -4205,8 +4125,7 @@ cleanup:
int
qemuProcessKill(virQEMUDriverPtr driver,
virDomainObjPtr vm, unsigned int flags)
qemuProcessKill(virDomainObjPtr vm, unsigned int flags)
{
int ret;
@ -4227,20 +4146,9 @@ qemuProcessKill(virQEMUDriverPtr driver,
return 0;
}
if (driver)
qemuDriverUnlock(driver);
ret = virProcessKillPainfully(vm->pid,
!!(flags & VIR_QEMU_PROCESS_KILL_FORCE));
if (driver) {
virObjectRef(vm);
virObjectUnlock(vm);
qemuDriverLock(driver);
virObjectLock(vm);
virObjectUnref(vm);
}
return ret;
}
@ -4272,8 +4180,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
}
/*
* We may unlock the driver and vm in qemuProcessKill(), and another thread
* can lock driver and vm, and then call qemuProcessStop(). So we should
* We may unlock the vm in qemuProcessKill(), and another thread
* can lock the vm, and then call qemuProcessStop(). So we should
* set vm->def->id to -1 here to avoid qemuProcessStop() to be called twice.
*/
vm->def->id = -1;
@ -4346,8 +4254,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
}
/* shut it off for sure */
ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE|
VIR_QEMU_PROCESS_KILL_NOCHECK));
ignore_value(qemuProcessKill(vm,
VIR_QEMU_PROCESS_KILL_FORCE|
VIR_QEMU_PROCESS_KILL_NOCHECK));
qemuDomainCleanupRun(driver, vm);
@ -4646,20 +4555,20 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
}
VIR_DEBUG("Getting initial memory amount");
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorGetBalloonInfo(priv->mon, &vm->def->mem.cur_balloon) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
if (qemuMonitorGetStatus(priv->mon, &running, &reason) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
if (qemuMonitorGetVirtType(priv->mon, &vm->def->virtType) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainObjExitMonitor(driver, vm);
if (!virDomainObjIsActive(vm))
goto cleanup;
@ -4731,8 +4640,8 @@ qemuProcessAutoDestroy(virQEMUDriverPtr driver,
qemuDomainObjDiscardAsyncJob(driver, dom);
}
if (qemuDomainObjBeginJobWithDriver(driver, dom,
QEMU_JOB_DESTROY) < 0)
if (qemuDomainObjBeginJob(driver, dom,
QEMU_JOB_DESTROY) < 0)
goto cleanup;
VIR_DEBUG("Killing domain");

View File

@ -84,8 +84,7 @@ typedef enum {
VIR_QEMU_PROCESS_KILL_NOCHECK = 1 << 2, /* bypass the running vm check */
} virQemuProcessKillMode;
int qemuProcessKill(virQEMUDriverPtr driver,
virDomainObjPtr vm, unsigned int flags);
int qemuProcessKill(virDomainObjPtr vm, unsigned int flags);
int qemuProcessAutoDestroyInit(virQEMUDriverPtr driver);
void qemuProcessAutoDestroyShutdown(virQEMUDriverPtr driver);