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 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_conf.h file has inline comments describing the locking
the QEMU driver is blocked while this is held, though some internal needs for each field. Any field marked immutable, self-locking
callbacks may still run asynchronously. This lock must never be held can be accessed without the driver lock. For other fields there
for anything which sleeps/waits (i.e. monitor commands) 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 * virDomainObjPtr
any lock be held on a virDomainObjPtr. This *WILL* result in
deadlock.
* virDomainObjPtr: Mutex
Will be locked after calling any of the virDomainFindBy{ID,Name,UUID} Will be locked after calling any of the virDomainFindBy{ID,Name,UUID}
methods. methods.
Lock must be held when changing/reading any variable in the virDomainObjPtr 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 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(). 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 This lock must not be held for anything which sleeps/waits (i.e. monitor
commands). commands).
@ -103,26 +92,10 @@ There are a number of locks on various objects
The virDomainObjPtr lock *MUST* then be released when invoking the The virDomainObjPtr lock *MUST* then be released when invoking the
monitor command. 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 Helper methods
-------------- --------------
To lock the driver
qemuDriverLock()
- Acquires the driver lock
qemuDriverUnlock()
- Releases the driver lock
To lock the virDomainObjPtr To lock the virDomainObjPtr
virObjectLock() virObjectLock()
@ -135,7 +108,7 @@ To lock the virDomainObjPtr
To acquire the normal job condition To acquire the normal job condition
qemuDomainObjBeginJob() (if driver is unlocked) qemuDomainObjBeginJob()
- Increments ref count on virDomainObjPtr - Increments ref count on virDomainObjPtr
- Waits until the job is compatible with current async job or no - Waits until the job is compatible with current async job or no
async job is running async job is running
@ -145,23 +118,6 @@ To acquire the normal job condition
isn't isn't
- Sets job.active to the job type - 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() qemuDomainObjEndJob()
- Sets job.active to 0 - Sets job.active to 0
@ -172,7 +128,7 @@ To acquire the normal job condition
To acquire the asynchronous job condition To acquire the asynchronous job condition
qemuDomainObjBeginAsyncJob() (if driver is unlocked) qemuDomainObjBeginAsyncJob()
- Increments ref count on virDomainObjPtr - Increments ref count on virDomainObjPtr
- Waits until no async job is running - Waits until no async job is running
- Waits for job.cond condition 'job.active != 0' using virDomainObjPtr - 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 and repeats waiting in that case
- Sets job.asyncJob to the asynchronous job type - 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() qemuDomainObjEndAsyncJob()
- Sets job.asyncJob to 0 - Sets job.asyncJob to 0
@ -215,61 +155,34 @@ To acquire the QEMU monitor lock
- Releases the qemuMonitorObjPtr lock - Releases the qemuMonitorObjPtr lock
- Acquires the virDomainObjPtr 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. These functions must not be used by an asynchronous job.
To acquire the QEMU monitor lock with the driver lock held To acquire the QEMU monitor lock as part of an asynchronous job
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
qemuDomainObjEnterMonitorAsync() qemuDomainObjEnterMonitorAsync()
- Validates that the right async job is still running - Validates that the right async job is still running
- Acquires the qemuMonitorObjPtr lock - Acquires the qemuMonitorObjPtr lock
- Releases the virDomainObjPtr lock - Releases the virDomainObjPtr lock
- Releases the driver lock
- Validates that the VM is still active - Validates that the VM is still active
qemuDomainObjExitMonitorWithDriver() qemuDomainObjExitMonitor()
- Releases the qemuMonitorObjPtr lock - Releases the qemuMonitorObjPtr lock
- Acquires the driver lock
- Acquires the virDomainObjPtr 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 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). 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 Helper functions may also call this with QEMU_ASYNC_JOB_NONE when
used from a sync job (such as when first starting a domain). used from a sync job (such as when first starting a domain).
To keep a domain alive while waiting on a remote command, starting To keep a domain alive while waiting on a remote command
with the driver lock held
qemuDomainObjEnterRemoterWithDriver() qemuDomainObjEnterRemote()
- Increments ref count on virDomainObjPtr - Increments ref count on virDomainObjPtr
- Releases the virDomainObjPtr lock - Releases the virDomainObjPtr lock
- Releases the driver lock
qemuDomainObjExitRemoteWithDriver() qemuDomainObjExitRemote()
- Acquires the driver lock
- Acquires the virDomainObjPtr lock - Acquires the virDomainObjPtr lock
- Decrements ref count on virDomainObjPtr - 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 * Accessing something directly to do with a virDomainObjPtr
virDomainObjPtr obj; 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); obj = virDomainFindByUUID(driver->domains, dom->uuid);
...do work... ...do work...
virDomainObjUnlock(obj); virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
* Updating something directly to do with a virDomainObjPtr * Updating something directly to do with a virDomainObjPtr
virDomainObjPtr obj; virDomainObjPtr obj;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid); obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDriverUnlock(driver);
qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE); qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE);
@ -341,9 +225,7 @@ Design patterns
virDomainObjPtr obj; virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid); obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDriverUnlock(driver);
qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE); qemuDomainObjBeginJob(obj, QEMU_JOB_TYPE);
@ -362,42 +244,14 @@ Design patterns
* Running asynchronous job
* Invoking a monitor command on a virDomainObjPtr with driver locked too
virDomainObjPtr obj; virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid); obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDomainObjBeginJobWithDriver(obj, QEMU_JOB_TYPE); qemuDomainObjBeginAsyncJob(obj, QEMU_ASYNC_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);
qemuDomainObjSetAsyncJobMask(obj, allowedJobs); qemuDomainObjSetAsyncJobMask(obj, allowedJobs);
...do prep work... ...do prep work...
@ -408,7 +262,7 @@ Design patterns
goto error; goto error;
} }
...start qemu job... ...start qemu job...
qemuDomainObjExitMonitorWithDriver(driver, obj); qemuDomainObjExitMonitor(driver, obj);
while (!finished) { while (!finished) {
if (qemuDomainObjEnterMonitorAsync(driver, obj, if (qemuDomainObjEnterMonitorAsync(driver, obj,
@ -417,7 +271,7 @@ Design patterns
goto error; goto error;
} }
...monitor job progress... ...monitor job progress...
qemuDomainObjExitMonitorWithDriver(driver, obj); qemuDomainObjExitMonitor(driver, obj);
virObjectUnlock(obj); virObjectUnlock(obj);
sleep(aWhile); sleep(aWhile);
@ -428,7 +282,6 @@ Design patterns
qemuDomainObjEndAsyncJob(obj); qemuDomainObjEndAsyncJob(obj);
virDomainObjUnlock(obj); virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
* Coordinating with a remote server for migration * Coordinating with a remote server for migration
@ -436,17 +289,16 @@ Design patterns
virDomainObjPtr obj; virDomainObjPtr obj;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver);
obj = virDomainFindByUUID(driver->domains, dom->uuid); obj = virDomainFindByUUID(driver->domains, dom->uuid);
qemuDomainObjBeginAsyncJobWithDriver(obj, QEMU_ASYNC_JOB_TYPE); qemuDomainObjBeginAsyncJob(obj, QEMU_ASYNC_JOB_TYPE);
...do prep work... ...do prep work...
if (virDomainObjIsActive(vm)) { if (virDomainObjIsActive(vm)) {
qemuDomainObjEnterRemoteWithDriver(driver, obj); qemuDomainObjEnterRemote(obj);
...communicate with remote... ...communicate with remote...
qemuDomainObjExitRemoteWithDriver(driver, obj); qemuDomainObjExitRemote(obj);
/* domain may have been stopped while we were talking to remote */ /* domain may have been stopped while we were talking to remote */
if (!virDomainObjIsActive(vm)) { if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -458,14 +310,3 @@ Design patterns
qemuDomainObjEndAsyncJob(obj); qemuDomainObjEndAsyncJob(obj);
virDomainObjUnlock(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 * 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 * Copyright (C) 2006 Daniel P. Berrange
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -79,11 +79,13 @@ struct _qemuDriverCloseDef {
qemuDriverCloseCallback cb; qemuDriverCloseCallback cb;
}; };
void qemuDriverLock(virQEMUDriverPtr driver) static void
qemuDriverLock(virQEMUDriverPtr driver)
{ {
virMutexLock(&driver->lock); virMutexLock(&driver->lock);
} }
void qemuDriverUnlock(virQEMUDriverPtr driver) static void
qemuDriverUnlock(virQEMUDriverPtr driver)
{ {
virMutexUnlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
@ -523,7 +525,11 @@ no_memory:
virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver) 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, virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
bool refresh) bool refresh)
{ {
virCapsPtr ret = NULL;
if (refresh) { if (refresh) {
virCapsPtr caps = NULL; virCapsPtr caps = NULL;
if ((caps = virQEMUDriverCreateCapabilities(driver)) == NULL) if ((caps = virQEMUDriverCreateCapabilities(driver)) == NULL)
return NULL; return NULL;
qemuDriverLock(driver);
virObjectUnref(driver->caps); virObjectUnref(driver->caps);
driver->caps = 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]; char uuidstr[VIR_UUID_STRING_BUFLEN];
qemuDriverCloseDefPtr closeDef; qemuDriverCloseDefPtr closeDef;
int ret = -1;
qemuDriverLock(driver);
virUUIDFormat(vm->def->uuid, uuidstr); virUUIDFormat(vm->def->uuid, uuidstr);
VIR_DEBUG("vm=%s, uuid=%s, conn=%p, cb=%p", VIR_DEBUG("vm=%s, uuid=%s, conn=%p, cb=%p",
vm->def->name, uuidstr, conn, cb); vm->def->name, uuidstr, conn, cb);
@ -669,30 +683,34 @@ qemuDriverCloseCallbackSet(virQEMUDriverPtr driver,
_("Close callback for domain %s already registered" _("Close callback for domain %s already registered"
" with another connection %p"), " with another connection %p"),
vm->def->name, closeDef->conn); vm->def->name, closeDef->conn);
return -1; goto cleanup;
} }
if (closeDef->cb && closeDef->cb != cb) { if (closeDef->cb && closeDef->cb != cb) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Another close callback is already defined for" _("Another close callback is already defined for"
" domain %s"), vm->def->name); " domain %s"), vm->def->name);
return -1; goto cleanup;
} }
closeDef->cb = cb; closeDef->cb = cb;
} else { } else {
if (VIR_ALLOC(closeDef) < 0) { if (VIR_ALLOC(closeDef) < 0) {
virReportOOMError(); virReportOOMError();
return -1; goto cleanup;
} }
closeDef->conn = conn; closeDef->conn = conn;
closeDef->cb = cb; closeDef->cb = cb;
if (virHashAddEntry(driver->closeCallbacks, uuidstr, closeDef) < 0) { if (virHashAddEntry(driver->closeCallbacks, uuidstr, closeDef) < 0) {
VIR_FREE(closeDef); VIR_FREE(closeDef);
return -1; goto cleanup;
} }
} }
return 0;
ret = 0;
cleanup:
qemuDriverUnlock(driver);
return ret;
} }
int int
@ -702,23 +720,28 @@ qemuDriverCloseCallbackUnset(virQEMUDriverPtr driver,
{ {
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
qemuDriverCloseDefPtr closeDef; qemuDriverCloseDefPtr closeDef;
int ret = -1;
qemuDriverLock(driver);
virUUIDFormat(vm->def->uuid, uuidstr); virUUIDFormat(vm->def->uuid, uuidstr);
VIR_DEBUG("vm=%s, uuid=%s, cb=%p", VIR_DEBUG("vm=%s, uuid=%s, cb=%p",
vm->def->name, uuidstr, cb); vm->def->name, uuidstr, cb);
closeDef = virHashLookup(driver->closeCallbacks, uuidstr); closeDef = virHashLookup(driver->closeCallbacks, uuidstr);
if (!closeDef) if (!closeDef)
return -1; goto cleanup;
if (closeDef->cb && closeDef->cb != cb) { if (closeDef->cb && closeDef->cb != cb) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Trying to remove mismatching close callback for" _("Trying to remove mismatching close callback for"
" domain %s"), vm->def->name); " 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 qemuDriverCloseCallback
@ -730,6 +753,7 @@ qemuDriverCloseCallbackGet(virQEMUDriverPtr driver,
qemuDriverCloseDefPtr closeDef; qemuDriverCloseDefPtr closeDef;
qemuDriverCloseCallback cb = NULL; qemuDriverCloseCallback cb = NULL;
qemuDriverLock(driver);
virUUIDFormat(vm->def->uuid, uuidstr); virUUIDFormat(vm->def->uuid, uuidstr);
VIR_DEBUG("vm=%s, uuid=%s, conn=%p", VIR_DEBUG("vm=%s, uuid=%s, conn=%p",
vm->def->name, uuidstr, conn); vm->def->name, uuidstr, conn);
@ -739,6 +763,7 @@ qemuDriverCloseCallbackGet(virQEMUDriverPtr driver,
cb = closeDef->cb; cb = closeDef->cb;
VIR_DEBUG("cb=%p", cb); VIR_DEBUG("cb=%p", cb);
qemuDriverUnlock(driver);
return cb; return cb;
} }
@ -794,8 +819,9 @@ qemuDriverCloseCallbackRunAll(virQEMUDriverPtr driver,
driver, conn driver, conn
}; };
VIR_DEBUG("conn=%p", conn); VIR_DEBUG("conn=%p", conn);
qemuDriverLock(driver);
virHashForEach(driver->closeCallbacks, qemuDriverCloseCallbackRun, &data); virHashForEach(driver->closeCallbacks, qemuDriverCloseCallbackRun, &data);
qemuDriverUnlock(driver);
} }
/* Construct the hash key for sharedDisks as "major:minor" */ /* Construct the hash key for sharedDisks as "major:minor" */
@ -832,6 +858,7 @@ qemuAddSharedDisk(virQEMUDriverPtr driver,
char *key = NULL; char *key = NULL;
int ret = -1; int ret = -1;
qemuDriverLock(driver);
if (!(key = qemuGetSharedDiskKey(disk_path))) if (!(key = qemuGetSharedDiskKey(disk_path)))
goto cleanup; goto cleanup;
@ -845,6 +872,7 @@ qemuAddSharedDisk(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
qemuDriverUnlock(driver);
VIR_FREE(key); VIR_FREE(key);
return ret; return ret;
} }
@ -860,6 +888,7 @@ qemuRemoveSharedDisk(virQEMUDriverPtr driver,
char *key = NULL; char *key = NULL;
int ret = -1; int ret = -1;
qemuDriverLock(driver);
if (!(key = qemuGetSharedDiskKey(disk_path))) if (!(key = qemuGetSharedDiskKey(disk_path)))
goto cleanup; goto cleanup;
@ -876,6 +905,7 @@ qemuRemoveSharedDisk(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
qemuDriverUnlock(driver);
VIR_FREE(key); VIR_FREE(key);
return ret; return ret;
} }

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/* /*
* qemu_domain.h: QEMU domain private state * 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 * Copyright (C) 2006 Daniel P. Berrange
* *
* This library is free software; you can redistribute it and/or * 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); void qemuDomainEventFlush(int timer, void *opaque);
/* driver must be locked before calling */
void qemuDomainEventQueue(virQEMUDriverPtr driver, void qemuDomainEventQueue(virQEMUDriverPtr driver,
virDomainEventPtr event); virDomainEventPtr event);
@ -190,14 +189,6 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
virDomainObjPtr obj, virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob) enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_RETURN_CHECK; 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, bool qemuDomainObjEndJob(virQEMUDriverPtr driver,
virDomainObjPtr obj) virDomainObjPtr obj)
@ -224,38 +215,22 @@ void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
void qemuDomainObjExitMonitor(virQEMUDriverPtr driver, void qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
virDomainObjPtr obj) virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void qemuDomainObjEnterMonitorWithDriver(virQEMUDriverPtr driver,
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver, int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
virDomainObjPtr obj, virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob) enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; 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, void qemuDomainObjEnterAgent(virDomainObjPtr obj)
virDomainObjPtr obj) ATTRIBUTE_NONNULL(1);
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); void qemuDomainObjExitAgent(virDomainObjPtr obj)
void qemuDomainObjExitAgent(virQEMUDriverPtr driver, ATTRIBUTE_NONNULL(1);
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 qemuDomainObjEnterRemoteWithDriver(virQEMUDriverPtr driver, void qemuDomainObjEnterRemote(virDomainObjPtr obj)
virDomainObjPtr obj) ATTRIBUTE_NONNULL(1);
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); void qemuDomainObjExitRemote(virDomainObjPtr obj)
void qemuDomainObjExitRemoteWithDriver(virQEMUDriverPtr driver, ATTRIBUTE_NONNULL(1);
virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuDomainDefFormatBuf(virQEMUDriverPtr driver, int qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
virDomainDefPtr vm, 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))) if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps)))
goto error; goto error;
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force); ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
/* we don't want to report errors from media tray_open polling */ /* we don't want to report errors from media tray_open polling */
@ -144,7 +144,7 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
disk->src, format); disk->src, format);
} }
exit_monitor: exit_monitor:
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, origdisk->src, disk->src, "update", ret >= 0); virDomainAuditDisk(vm, origdisk->src, disk->src, "update", ret >= 0);
@ -194,7 +194,7 @@ qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
table = qemuMonitorGetBlockInfo(priv->mon); table = qemuMonitorGetBlockInfo(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
} }
if (!table) if (!table)
@ -276,7 +276,7 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
goto error; goto error;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr); ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) { if (ret == 0) {
@ -305,7 +305,7 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr)); memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
} }
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0); virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
@ -381,7 +381,7 @@ int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDevice(priv->mon, devstr); ret = qemuMonitorAddDevice(priv->mon, devstr);
} else { } else {
@ -389,7 +389,7 @@ int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver,
type, type,
&controller->info.addr.pci); &controller->info.addr.pci);
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
if (ret == 0) { if (ret == 0) {
controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
@ -529,7 +529,7 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn,
goto error; goto error;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr); ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) { if (ret == 0) {
@ -555,7 +555,7 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn,
disk->info.addr.drive.unit = driveAddr.unit; disk->info.addr.drive.unit = driveAddr.unit;
} }
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0); virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
@ -633,7 +633,7 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
goto error; goto error;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr); ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) { if (ret == 0) {
@ -648,7 +648,7 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
} else { } else {
ret = qemuMonitorAddUSBDisk(priv->mon, disk->src); ret = qemuMonitorAddUSBDisk(priv->mon, disk->src);
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0); virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
@ -807,24 +807,24 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name, if (qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name,
vhostfd, vhostfd_name) < 0) { vhostfd, vhostfd_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false); virDomainAuditNet(vm, NULL, net, "attach", false);
goto cleanup; goto cleanup;
} }
} else { } else {
if (qemuMonitorAddHostNetwork(priv->mon, netstr, tapfd, tapfd_name, if (qemuMonitorAddHostNetwork(priv->mon, netstr, tapfd, tapfd_name,
vhostfd, vhostfd_name) < 0) { vhostfd, vhostfd_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false); virDomainAuditNet(vm, NULL, net, "attach", false);
goto cleanup; goto cleanup;
} }
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
VIR_FORCE_CLOSE(tapfd); VIR_FORCE_CLOSE(tapfd);
VIR_FORCE_CLOSE(vhostfd); VIR_FORCE_CLOSE(vhostfd);
@ -843,10 +843,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
goto try_remove; goto try_remove;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) { if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false); virDomainAuditNet(vm, NULL, net, "attach", false);
goto try_remove; goto try_remove;
} }
@ -854,14 +854,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
guestAddr = net->info.addr.pci; guestAddr = net->info.addr.pci;
if (qemuMonitorAddPCINetwork(priv->mon, nicstr, if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
&guestAddr) < 0) { &guestAddr) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, NULL, net, "attach", false); virDomainAuditNet(vm, NULL, net, "attach", false);
goto try_remove; goto try_remove;
} }
net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr)); memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
/* set link state */ /* set link state */
if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) { if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
@ -869,11 +869,11 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
virReportError(VIR_ERR_OPERATION_FAILED, "%s", virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("device alias not found: cannot set link state to down")); _("device alias not found: cannot set link state to down"));
} else { } else {
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) { 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); virDomainAuditNet(vm, NULL, net, "attach", false);
goto try_remove; goto try_remove;
} }
@ -882,7 +882,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
_("setting of link state not supported: Link is up")); _("setting of link state not supported: Link is up"));
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
} }
/* link set to down */ /* link set to down */
} }
@ -934,11 +934,11 @@ try_remove:
char *netdev_name; char *netdev_name;
if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0) if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0)
goto no_memory; goto no_memory;
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0) if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
VIR_WARN("Failed to remove network backend for netdev %s", VIR_WARN("Failed to remove network backend for netdev %s",
netdev_name); netdev_name);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
VIR_FREE(netdev_name); VIR_FREE(netdev_name);
} else { } else {
VIR_WARN("Unable to remove network backend"); VIR_WARN("Unable to remove network backend");
@ -947,11 +947,11 @@ try_remove:
char *hostnet_name; char *hostnet_name;
if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0) if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
goto no_memory; goto no_memory;
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
VIR_WARN("Failed to remove network backend for vlan %d, net %s", VIR_WARN("Failed to remove network backend for vlan %d, net %s",
vlan, hostnet_name); vlan, hostnet_name);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
VIR_FREE(hostnet_name); VIR_FREE(hostnet_name);
} }
goto cleanup; goto cleanup;
@ -1009,18 +1009,18 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
priv->qemuCaps))) priv->qemuCaps)))
goto error; goto error;
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
configfd, configfd_name); configfd, configfd_name);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
} else { } else {
virDevicePCIAddress guestAddr = hostdev->info->addr.pci; virDevicePCIAddress guestAddr = hostdev->info->addr.pci;
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorAddPCIHostDevice(priv->mon, ret = qemuMonitorAddPCIHostDevice(priv->mon,
&hostdev->source.subsys.u.pci, &hostdev->source.subsys.u.pci,
&guestAddr); &guestAddr);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
memcpy(&hostdev->info->addr.pci, &guestAddr, sizeof(guestAddr)); memcpy(&hostdev->info->addr.pci, &guestAddr, sizeof(guestAddr));
@ -1076,13 +1076,13 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
goto error; goto error;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
ret = qemuMonitorAddDevice(priv->mon, devstr); ret = qemuMonitorAddDevice(priv->mon, devstr);
else else
goto error; goto error;
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0); virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
if (ret < 0) if (ret < 0)
goto error; goto error;
@ -1146,14 +1146,14 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
virUSBDeviceFree(usb); virUSBDeviceFree(usb);
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
ret = qemuMonitorAddDevice(priv->mon, devstr); ret = qemuMonitorAddDevice(priv->mon, devstr);
else else
ret = qemuMonitorAddUSBDeviceExact(priv->mon, ret = qemuMonitorAddUSBDeviceExact(priv->mon,
hostdev->source.subsys.u.usb.bus, hostdev->source.subsys.u.usb.bus,
hostdev->source.subsys.u.usb.device); hostdev->source.subsys.u.usb.device);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditHostdev(vm, hostdev, "attach", ret == 0); virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
if (ret < 0) if (ret < 0)
goto error; goto error;
@ -1421,7 +1421,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate); ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
if (ret < 0) if (ret < 0)
@ -1431,7 +1431,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
dev->linkstate = linkstate; dev->linkstate = linkstate;
cleanup: cleanup:
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
return ret; return ret;
} }
@ -2059,17 +2059,17 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", false); virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
} else { } else {
if (qemuMonitorRemovePCIDevice(priv->mon, if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) { &detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", false); virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
@ -2078,7 +2078,7 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
/* disconnect guest from host device */ /* disconnect guest from host device */
qemuMonitorDriveDel(priv->mon, drivestr); qemuMonitorDriveDel(priv->mon, drivestr);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", true); virDomainAuditDisk(vm, detach->src, NULL, "detach", true);
@ -2165,9 +2165,9 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", false); virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
@ -2175,7 +2175,7 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
/* disconnect guest from host device */ /* disconnect guest from host device */
qemuMonitorDriveDel(priv->mon, drivestr); qemuMonitorDriveDel(priv->mon, drivestr);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditDisk(vm, detach->src, NULL, "detach", true); virDomainAuditDisk(vm, detach->src, NULL, "detach", true);
@ -2301,20 +2301,20 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
goto cleanup; goto cleanup;
} }
} else { } else {
if (qemuMonitorRemovePCIDevice(priv->mon, if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) { &detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
goto cleanup; goto cleanup;
} }
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainControllerRemove(vm->def, idx); virDomainControllerRemove(vm->def, idx);
virDomainControllerDefFree(detach); virDomainControllerDefFree(detach);
@ -2357,13 +2357,13 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
rv = qemuMonitorDelDevice(priv->mon, detach->info->alias); rv = qemuMonitorDelDevice(priv->mon, detach->info->alias);
} else { } else {
rv = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci); rv = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditHostdev(vm, detach, "detach", rv == 0); virDomainAuditHostdev(vm, detach, "detach", rv == 0);
if (rv < 0) if (rv < 0)
goto cleanup; goto cleanup;
@ -2427,9 +2427,9 @@ qemuDomainDetachHostUsbDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditHostdev(vm, detach, "detach", ret == 0); virDomainAuditHostdev(vm, detach, "detach", ret == 0);
if (ret < 0) if (ret < 0)
return -1; return -1;
@ -2613,17 +2613,17 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false); virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
} else { } else {
if (qemuMonitorRemovePCIDevice(priv->mon, if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) { &detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false); virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
@ -2632,18 +2632,18 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) { if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false); virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
} else { } else {
if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) { if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", false); virDomainAuditNet(vm, detach, NULL, "detach", false);
goto cleanup; goto cleanup;
} }
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
virDomainAuditNet(vm, detach, NULL, "detach", true); virDomainAuditNet(vm, detach, NULL, "detach", true);
@ -2713,7 +2713,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
if (auth->connected) if (auth->connected)
connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected); connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetPassword(priv->mon, ret = qemuMonitorSetPassword(priv->mon,
type, type,
auth->passwd ? auth->passwd : defaultPasswd, auth->passwd ? auth->passwd : defaultPasswd,
@ -2756,7 +2756,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
} }
end_job: end_job:
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitor(driver, vm);
cleanup: cleanup:
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;

View File

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

View File

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

View File

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