qemu: Consolidate BeginJob{,WithDriver} into a single method

This avoids code duplication and also avoids relying on good luck that
ignore_value(virDomainObjUnref(obj)) doesn't set errno.
This commit is contained in:
Jiri Denemark 2011-06-30 11:21:34 +02:00
parent 90a422f071
commit cec1d280ad

View File

@ -517,58 +517,16 @@ qemuDomainObjDiscardJob(virDomainObjPtr obj)
qemuDomainObjSetJob(obj, QEMU_JOB_NONE); qemuDomainObjSetJob(obj, QEMU_JOB_NONE);
} }
/*
* obj must be locked before calling, qemud_driver must NOT be locked
*
* 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
*/
/* Give up waiting for mutex after 30 seconds */ /* Give up waiting for mutex after 30 seconds */
#define QEMU_JOB_WAIT_TIME (1000ull * 30) #define QEMU_JOB_WAIT_TIME (1000ull * 30)
int qemuDomainObjBeginJob(virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
unsigned long long now;
unsigned long long then;
if (virTimeMs(&now) < 0)
return -1;
then = now + QEMU_JOB_WAIT_TIME;
virDomainObjRef(obj);
while (priv->job.active) {
if (virCondWaitUntil(&priv->job.cond, &obj->lock, then) < 0) {
/* Safe to ignore value since ref count was incremented above */
ignore_value(virDomainObjUnref(obj));
if (errno == ETIMEDOUT)
qemuReportError(VIR_ERR_OPERATION_TIMEOUT,
"%s", _("cannot acquire state change lock"));
else
virReportSystemError(errno,
"%s", _("cannot acquire job mutex"));
return -1;
}
}
qemuDomainObjResetJob(priv);
qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED);
priv->job.start = now;
return 0;
}
/* /*
* obj must be locked before calling, qemud_driver must be locked * obj must be locked before calling; driver_locked says if qemu_driver is
* * locked or not.
* This must be called by anything that will change the VM state
* in any way, or anything that will use the QEMU monitor.
*/ */
int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, static int
qemuDomainObjBeginJobInternal(struct qemud_driver *driver,
bool driver_locked,
virDomainObjPtr obj) virDomainObjPtr obj)
{ {
qemuDomainObjPrivatePtr priv = obj->privateData; qemuDomainObjPrivatePtr priv = obj->privateData;
@ -580,6 +538,7 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
then = now + QEMU_JOB_WAIT_TIME; then = now + QEMU_JOB_WAIT_TIME;
virDomainObjRef(obj); virDomainObjRef(obj);
if (driver_locked)
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
while (priv->job.active) { while (priv->job.active) {
@ -590,9 +549,11 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
else else
virReportSystemError(errno, virReportSystemError(errno,
"%s", _("cannot acquire job mutex")); "%s", _("cannot acquire job mutex"));
if (driver_locked) {
virDomainObjUnlock(obj); virDomainObjUnlock(obj);
qemuDriverLock(driver); qemuDriverLock(driver);
virDomainObjLock(obj); virDomainObjLock(obj);
}
/* Safe to ignore value since ref count was incremented above */ /* Safe to ignore value since ref count was incremented above */
ignore_value(virDomainObjUnref(obj)); ignore_value(virDomainObjUnref(obj));
return -1; return -1;
@ -602,13 +563,45 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED);
priv->job.start = now; priv->job.start = now;
if (driver_locked) {
virDomainObjUnlock(obj); virDomainObjUnlock(obj);
qemuDriverLock(driver); qemuDriverLock(driver);
virDomainObjLock(obj); virDomainObjLock(obj);
}
return 0; return 0;
} }
/*
* obj must be locked before calling, qemud_driver must NOT be locked
*
* 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 qemuDomainObjBeginJob(virDomainObjPtr obj)
{
return qemuDomainObjBeginJobInternal(NULL, false, obj);
}
/*
* obj must be locked before calling. If qemud_driver is passed, it MUST be
* locked; otherwise it MUST NOT be locked.
*
* 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(struct qemud_driver *driver,
virDomainObjPtr obj)
{
return qemuDomainObjBeginJobInternal(driver, true, obj);
}
/* /*
* obj must be locked before calling, qemud_driver does not matter * obj must be locked before calling, qemud_driver does not matter
* *