static void
qemuBlockJobDataReset(qemuBlockJobDataPtr job)
{
- job->started = false;
job->type = -1;
job->newstate = -1;
VIR_FREE(job->errmsg);
qemuBlockJobDataReset(job);
+ job->state = QEMU_BLOCKJOB_STATE_NEW;
job->type = type;
return virObjectRef(job);
void
qemuBlockJobStarted(qemuBlockJobDataPtr job)
{
- job->started = true;
+ job->state = QEMU_BLOCKJOB_STATE_RUNNING;
}
if (!job)
return;
- if (!job->started)
+ if (job->state == QEMU_BLOCKJOB_STATE_NEW)
qemuBlockJobDataReset(job);
virObjectUnref(job);
}
+bool
+qemuBlockJobIsRunning(qemuBlockJobDataPtr job)
+{
+ return job->state == QEMU_BLOCKJOB_STATE_RUNNING ||
+ job->state == QEMU_BLOCKJOB_STATE_READY;
+}
+
+
/**
* qemuBlockJobEmitEvents:
*
virDomainDiskDefPtr disk,
int asyncJob)
{
- qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
virDomainDiskDefPtr persistDisk = NULL;
if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
virStorageSourceBackingStoreClear(disk->src);
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, true));
ignore_value(qemuBlockNodeNamesDetect(driver, vm, asyncJob));
- diskPriv->blockjob->started = false;
}
{
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virDomainDiskDefPtr disk = job->disk;
- qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
- VIR_DEBUG("disk=%s, mirrorState=%s, type=%d, newstate=%d",
+ VIR_DEBUG("disk=%s, mirrorState=%s, type=%d, state=%d, newstate=%d",
disk->dst,
NULLSTR(virDomainDiskMirrorStateTypeToString(disk->mirrorState)),
job->type,
+ job->state,
job->newstate);
qemuBlockJobEmitEvents(driver, vm, disk, job->type, job->newstate);
}
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
- diskPriv->blockjob->started = false;
break;
case VIR_DOMAIN_BLOCK_JOB_LAST:
break;
}
+ job->state = job->newstate;
+
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
VIR_WARN("Unable to save status on vm %s after block job", vm->def->name);
# include "internal.h"
# include "qemu_conf.h"
+/**
+ * This enum has to map all known block job states from enum virDomainBlockJobType
+ * to the same values. All internal blockjobs can be mapped after and don't
+ * need to have stable values.
+ */
+typedef enum {
+ QEMU_BLOCKJOB_STATE_COMPLETED = VIR_DOMAIN_BLOCK_JOB_COMPLETED,
+ QEMU_BLOCKJOB_STATE_FAILED = VIR_DOMAIN_BLOCK_JOB_FAILED,
+ QEMU_BLOCKJOB_STATE_CANCELLED = VIR_DOMAIN_BLOCK_JOB_CANCELED,
+ QEMU_BLOCKJOB_STATE_READY = VIR_DOMAIN_BLOCK_JOB_READY,
+ QEMU_BLOCKJOB_STATE_NEW = VIR_DOMAIN_BLOCK_JOB_LAST,
+ QEMU_BLOCKJOB_STATE_RUNNING,
+ QEMU_BLOCKJOB_STATE_LAST
+} qemuBlockjobState;
+verify((int)QEMU_BLOCKJOB_STATE_NEW == VIR_DOMAIN_BLOCK_JOB_LAST);
+
/**
* This enum has to map all known block job types from enum virDomainBlockJobType
* to the same values. All internal blockjobs can be mapped after and don't
bool started;
int type; /* qemuBlockJobType */
+ int state; /* qemuBlockjobState */
char *errmsg;
bool synchronous; /* API call is waiting for this job */
qemuBlockJobStarted(qemuBlockJobDataPtr job)
ATTRIBUTE_NONNULL(1);
+bool
+qemuBlockJobIsRunning(qemuBlockJobDataPtr job)
+ ATTRIBUTE_NONNULL(1);
+
void
qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job);
}
if (diskPriv->blockjob &&
- diskPriv->blockjob->started) {
+ qemuBlockJobIsRunning(diskPriv->blockjob)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("disk '%s' already in active block job"),
disk->dst);
virDomainDiskDefPtr disk = vm->def->disks[i];
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
- if (!copy_only && diskPriv->blockjob && diskPriv->blockjob->started)
+ if (!copy_only && diskPriv->blockjob &&
+ qemuBlockJobIsRunning(diskPriv->blockjob))
return true;
if (disk->mirror && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
* do the waiting while still holding the VM job, to prevent newly
* scheduled block jobs from confusing us. */
if (!async) {
- qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
qemuBlockJobUpdateDisk(vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
- while (diskPriv->blockjob->started) {
+ while (qemuBlockJobIsRunning(job)) {
if (virDomainObjWait(vm) < 0) {
ret = -1;
goto endjob;
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+ qemuBlockJobDataPtr job;
- if (!diskPriv->blockjob->started)
+ if (!(job = qemuBlockJobDiskGetJob(disk)) ||
+ !qemuBlockJobIsRunning(job))
diskPriv->migrating = false;
- if (!diskPriv->migrating)
+ if (!diskPriv->migrating) {
+ virObjectUnref(job);
continue;
+ }
rv = qemuMigrationSrcNBDCopyCancelOne(driver, vm, disk,
check, asyncJob);
qemuBlockJobSyncEndDisk(vm, asyncJob, disk);
diskPriv->migrating = false;
}
+
+ virObjectUnref(job);
}
while ((rv = qemuMigrationSrcNBDCopyCancelled(vm, asyncJob, check)) != 1) {
qemuBlockJobDataPtr job;
if (!(job = qemuBlockJobDiskGetJob(disk)) ||
- !job->started)
+ !qemuBlockJobIsRunning(job))
diskPriv->migrating = false;
if (diskPriv->migrating) {
if (disk->mirror) {
if (info->ready == 1 ||
- (info->ready == -1 && info->end == info->cur))
+ (info->ready == -1 && info->end == info->cur)) {
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
+ job->state = VIR_DOMAIN_BLOCK_JOB_READY;
+ }
}
qemuBlockJobStartupFinalize(job);