static int
qemuBlockJobRegister(qemuBlockJobDataPtr job,
+ virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+ if (virHashAddEntry(priv->blockjobs, job->name, virObjectRef(job)) < 0) {
+ virObjectUnref(job);
+ return -1;
+ }
+
if (disk) {
job->disk = disk;
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = virObjectRef(job);
static void
-qemuBlockJobUnregister(qemuBlockJobDataPtr job)
+qemuBlockJobUnregister(qemuBlockJobDataPtr job,
+ virDomainObjPtr vm)
{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
qemuDomainDiskPrivatePtr diskPriv;
if (job->disk) {
job->disk = NULL;
}
+
+ /* this may remove the last reference of 'job' */
+ virHashRemoveEntry(priv->blockjobs, job->name);
}
* Returns 0 on success and -1 on failure.
*/
qemuBlockJobDataPtr
-qemuBlockJobDiskNew(virDomainDiskDefPtr disk,
+qemuBlockJobDiskNew(virDomainObjPtr vm,
+ virDomainDiskDefPtr disk,
qemuBlockJobType type,
const char *jobname)
{
if (!(job = qemuBlockJobDataNew(type, jobname)))
return NULL;
- if (qemuBlockJobRegister(job, disk) < 0)
+ if (qemuBlockJobRegister(job, vm, disk) < 0)
return NULL;
VIR_RETURN_PTR(job);
* to @job if it was started.
*/
void
-qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job)
+qemuBlockJobStartupFinalize(virDomainObjPtr vm,
+ qemuBlockJobDataPtr job)
{
if (!job)
return;
if (job->state == QEMU_BLOCKJOB_STATE_NEW)
- qemuBlockJobUnregister(job);
+ qemuBlockJobUnregister(job, vm);
virObjectUnref(job);
}
virStorageSourceBackingStoreClear(disk->src);
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, NULL, true));
ignore_value(qemuBlockNodeNamesDetect(driver, vm, asyncJob));
- qemuBlockJobUnregister(job);
+ qemuBlockJobUnregister(job, vm);
qemuDomainSaveConfig(vm);
}
}
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
- qemuBlockJobUnregister(job);
+ qemuBlockJobUnregister(job, vm);
break;
case VIR_DOMAIN_BLOCK_JOB_LAST:
qemuBlockJobDataPtr
-qemuBlockJobDiskNew(virDomainDiskDefPtr disk,
+qemuBlockJobDiskNew(virDomainObjPtr vm,
+ virDomainDiskDefPtr disk,
qemuBlockJobType type,
const char *jobname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
ATTRIBUTE_NONNULL(1);
void
-qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job);
+qemuBlockJobStartupFinalize(virDomainObjPtr vm,
+ qemuBlockJobDataPtr job);
int qemuBlockJobUpdate(virDomainObjPtr vm,
qemuBlockJobDataPtr job,
}
if (!(job = qemuBlockJobDiskGetJob(disk))) {
- if (!(job = qemuBlockJobDiskNew(disk, type, diskAlias)))
+ if (!(job = qemuBlockJobDiskNew(vm, disk, type, diskAlias)))
goto endjob;
qemuBlockJobStarted(job);
}
qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE);
endjob:
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
qemuDomainObjEndJob(driver, vm);
}
speed <<= 20;
}
- if (!(job = qemuBlockJobDiskNew(disk, QEMU_BLOCKJOB_TYPE_PULL, device)))
+ if (!(job = qemuBlockJobDiskNew(vm, disk, QEMU_BLOCKJOB_TYPE_PULL, device)))
goto endjob;
qemuDomainObjEnterMonitor(driver, vm);
qemuDomainObjEndJob(driver, vm);
cleanup:
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
virDomainObjEndAPI(&vm);
return ret;
}
if (qemuDomainStorageSourceChainAccessAllow(driver, vm, mirror) < 0)
goto endjob;
- if (!(job = qemuBlockJobDiskNew(disk, QEMU_BLOCKJOB_TYPE_COPY, device)))
+ if (!(job = qemuBlockJobDiskNew(vm, disk, QEMU_BLOCKJOB_TYPE_COPY, device)))
goto endjob;
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
VIR_WARN("%s", _("unable to remove just-created copy target"));
virStorageFileDeinit(mirror);
qemuDomainObjEndJob(driver, vm);
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
return ret;
}
qemuDomainStorageSourceAccessAllow(driver, vm, top_parent, false, false) < 0))
goto endjob;
- if (!(job = qemuBlockJobDiskNew(disk, jobtype, device)))
+ if (!(job = qemuBlockJobDiskNew(vm, disk, jobtype, device)))
goto endjob;
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
virFreeError(orig_err);
}
}
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
qemuDomainObjEndJob(driver, vm);
cleanup:
if (!(diskAlias = qemuAliasDiskDriveFromDisk(disk)))
goto cleanup;
- if (!(job = qemuBlockJobDiskNew(disk, QEMU_BLOCKJOB_TYPE_COPY, diskAlias)))
+ if (!(job = qemuBlockJobDiskNew(vm, disk, QEMU_BLOCKJOB_TYPE_COPY, diskAlias)))
goto cleanup;
qemuBlockJobSyncBegin(job);
ret = 0;
cleanup:
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
VIR_FREE(diskAlias);
return ret;
}
}
cleanup:
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
qemuProcessEventFree(processEvent);
virObjectUnlock(vm);
return 0;
disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)
jobtype = disk->mirrorJob;
- if (!(job = qemuBlockJobDiskNew(disk, jobtype, jobname)))
+ if (!(job = qemuBlockJobDiskNew(vm, disk, jobtype, jobname)))
return -1;
qemuBlockJobStarted(job);
}
cleanup:
- qemuBlockJobStartupFinalize(job);
+ qemuBlockJobStartupFinalize(vm, job);
return 0;
}