mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 07:17:44 +00:00
qemu: blockjob: Track current state of blockjob
Add a field tracking the current state of job so that it can be queried later. Until now the job state e.g. that the job is _READY for finalizing was tracked only for mirror jobs. Add tracking of state for all jobs. Similarly to 'qemuBlockJobType' this maps the existing states of the blockjob from virConnectDomainEventBlockJobStatus to 'qemuBlockJobState' so that we can track some internal states as well. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
728830be9b
commit
d1a44634ac
@ -79,7 +79,6 @@ qemuBlockJobDataNew(void)
|
|||||||
static void
|
static void
|
||||||
qemuBlockJobDataReset(qemuBlockJobDataPtr job)
|
qemuBlockJobDataReset(qemuBlockJobDataPtr job)
|
||||||
{
|
{
|
||||||
job->started = false;
|
|
||||||
job->type = -1;
|
job->type = -1;
|
||||||
job->newstate = -1;
|
job->newstate = -1;
|
||||||
VIR_FREE(job->errmsg);
|
VIR_FREE(job->errmsg);
|
||||||
@ -104,6 +103,7 @@ qemuBlockJobDiskNew(virDomainDiskDefPtr disk,
|
|||||||
|
|
||||||
qemuBlockJobDataReset(job);
|
qemuBlockJobDataReset(job);
|
||||||
|
|
||||||
|
job->state = QEMU_BLOCKJOB_STATE_NEW;
|
||||||
job->type = type;
|
job->type = type;
|
||||||
|
|
||||||
return virObjectRef(job);
|
return virObjectRef(job);
|
||||||
@ -137,7 +137,7 @@ qemuBlockJobDiskGetJob(virDomainDiskDefPtr disk)
|
|||||||
void
|
void
|
||||||
qemuBlockJobStarted(qemuBlockJobDataPtr job)
|
qemuBlockJobStarted(qemuBlockJobDataPtr job)
|
||||||
{
|
{
|
||||||
job->started = true;
|
job->state = QEMU_BLOCKJOB_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -155,13 +155,21 @@ qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job)
|
|||||||
if (!job)
|
if (!job)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!job->started)
|
if (job->state == QEMU_BLOCKJOB_STATE_NEW)
|
||||||
qemuBlockJobDataReset(job);
|
qemuBlockJobDataReset(job);
|
||||||
|
|
||||||
virObjectUnref(job);
|
virObjectUnref(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
qemuBlockJobIsRunning(qemuBlockJobDataPtr job)
|
||||||
|
{
|
||||||
|
return job->state == QEMU_BLOCKJOB_STATE_RUNNING ||
|
||||||
|
job->state == QEMU_BLOCKJOB_STATE_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemuBlockJobEmitEvents:
|
* qemuBlockJobEmitEvents:
|
||||||
*
|
*
|
||||||
@ -196,7 +204,6 @@ qemuBlockJobEventProcessLegacyCompleted(virQEMUDriverPtr driver,
|
|||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
int asyncJob)
|
int asyncJob)
|
||||||
{
|
{
|
||||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
|
||||||
virDomainDiskDefPtr persistDisk = NULL;
|
virDomainDiskDefPtr persistDisk = NULL;
|
||||||
|
|
||||||
if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
|
if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
|
||||||
@ -250,7 +257,6 @@ qemuBlockJobEventProcessLegacyCompleted(virQEMUDriverPtr driver,
|
|||||||
virStorageSourceBackingStoreClear(disk->src);
|
virStorageSourceBackingStoreClear(disk->src);
|
||||||
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, true));
|
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, true));
|
||||||
ignore_value(qemuBlockNodeNamesDetect(driver, vm, asyncJob));
|
ignore_value(qemuBlockNodeNamesDetect(driver, vm, asyncJob));
|
||||||
diskPriv->blockjob->started = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -272,12 +278,12 @@ qemuBlockJobEventProcessLegacy(virQEMUDriverPtr driver,
|
|||||||
{
|
{
|
||||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
virDomainDiskDefPtr disk = job->disk;
|
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,
|
disk->dst,
|
||||||
NULLSTR(virDomainDiskMirrorStateTypeToString(disk->mirrorState)),
|
NULLSTR(virDomainDiskMirrorStateTypeToString(disk->mirrorState)),
|
||||||
job->type,
|
job->type,
|
||||||
|
job->state,
|
||||||
job->newstate);
|
job->newstate);
|
||||||
|
|
||||||
qemuBlockJobEmitEvents(driver, vm, disk, job->type, job->newstate);
|
qemuBlockJobEmitEvents(driver, vm, disk, job->type, job->newstate);
|
||||||
@ -302,13 +308,14 @@ qemuBlockJobEventProcessLegacy(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||||
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
|
||||||
diskPriv->blockjob->started = false;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_BLOCK_JOB_LAST:
|
case VIR_DOMAIN_BLOCK_JOB_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
job->state = job->newstate;
|
||||||
|
|
||||||
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
|
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);
|
VIR_WARN("Unable to save status on vm %s after block job", vm->def->name);
|
||||||
|
|
||||||
|
@ -25,6 +25,22 @@
|
|||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
# include "qemu_conf.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
|
* 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
|
* to the same values. All internal blockjobs can be mapped after and don't
|
||||||
@ -51,6 +67,7 @@ struct _qemuBlockJobData {
|
|||||||
|
|
||||||
bool started;
|
bool started;
|
||||||
int type; /* qemuBlockJobType */
|
int type; /* qemuBlockJobType */
|
||||||
|
int state; /* qemuBlockjobState */
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
bool synchronous; /* API call is waiting for this job */
|
bool synchronous; /* API call is waiting for this job */
|
||||||
|
|
||||||
@ -72,6 +89,10 @@ void
|
|||||||
qemuBlockJobStarted(qemuBlockJobDataPtr job)
|
qemuBlockJobStarted(qemuBlockJobDataPtr job)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
bool
|
||||||
|
qemuBlockJobIsRunning(qemuBlockJobDataPtr job)
|
||||||
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
void
|
void
|
||||||
qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job);
|
qemuBlockJobStartupFinalize(qemuBlockJobDataPtr job);
|
||||||
|
|
||||||
|
@ -9254,7 +9254,7 @@ qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (diskPriv->blockjob &&
|
if (diskPriv->blockjob &&
|
||||||
diskPriv->blockjob->started) {
|
qemuBlockJobIsRunning(diskPriv->blockjob)) {
|
||||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
||||||
_("disk '%s' already in active block job"),
|
_("disk '%s' already in active block job"),
|
||||||
disk->dst);
|
disk->dst);
|
||||||
@ -9283,7 +9283,8 @@ qemuDomainHasBlockjob(virDomainObjPtr vm,
|
|||||||
virDomainDiskDefPtr disk = vm->def->disks[i];
|
virDomainDiskDefPtr disk = vm->def->disks[i];
|
||||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
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;
|
return true;
|
||||||
|
|
||||||
if (disk->mirror && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
|
if (disk->mirror && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
|
||||||
|
@ -17445,9 +17445,8 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
* do the waiting while still holding the VM job, to prevent newly
|
* do the waiting while still holding the VM job, to prevent newly
|
||||||
* scheduled block jobs from confusing us. */
|
* scheduled block jobs from confusing us. */
|
||||||
if (!async) {
|
if (!async) {
|
||||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
|
||||||
qemuBlockJobUpdateDisk(vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
|
qemuBlockJobUpdateDisk(vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
|
||||||
while (diskPriv->blockjob->started) {
|
while (qemuBlockJobIsRunning(job)) {
|
||||||
if (virDomainObjWait(vm) < 0) {
|
if (virDomainObjWait(vm) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
@ -702,12 +702,16 @@ qemuMigrationSrcNBDCopyCancel(virQEMUDriverPtr driver,
|
|||||||
for (i = 0; i < vm->def->ndisks; i++) {
|
for (i = 0; i < vm->def->ndisks; i++) {
|
||||||
virDomainDiskDefPtr disk = vm->def->disks[i];
|
virDomainDiskDefPtr disk = vm->def->disks[i];
|
||||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||||
|
qemuBlockJobDataPtr job;
|
||||||
|
|
||||||
if (!diskPriv->blockjob->started)
|
if (!(job = qemuBlockJobDiskGetJob(disk)) ||
|
||||||
|
!qemuBlockJobIsRunning(job))
|
||||||
diskPriv->migrating = false;
|
diskPriv->migrating = false;
|
||||||
|
|
||||||
if (!diskPriv->migrating)
|
if (!diskPriv->migrating) {
|
||||||
|
virObjectUnref(job);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
rv = qemuMigrationSrcNBDCopyCancelOne(driver, vm, disk,
|
rv = qemuMigrationSrcNBDCopyCancelOne(driver, vm, disk,
|
||||||
check, asyncJob);
|
check, asyncJob);
|
||||||
@ -720,6 +724,8 @@ qemuMigrationSrcNBDCopyCancel(virQEMUDriverPtr driver,
|
|||||||
qemuBlockJobSyncEndDisk(vm, asyncJob, disk);
|
qemuBlockJobSyncEndDisk(vm, asyncJob, disk);
|
||||||
diskPriv->migrating = false;
|
diskPriv->migrating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virObjectUnref(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((rv = qemuMigrationSrcNBDCopyCancelled(vm, asyncJob, check)) != 1) {
|
while ((rv = qemuMigrationSrcNBDCopyCancelled(vm, asyncJob, check)) != 1) {
|
||||||
@ -5395,7 +5401,7 @@ qemuMigrationSrcCancel(virQEMUDriverPtr driver,
|
|||||||
qemuBlockJobDataPtr job;
|
qemuBlockJobDataPtr job;
|
||||||
|
|
||||||
if (!(job = qemuBlockJobDiskGetJob(disk)) ||
|
if (!(job = qemuBlockJobDiskGetJob(disk)) ||
|
||||||
!job->started)
|
!qemuBlockJobIsRunning(job))
|
||||||
diskPriv->migrating = false;
|
diskPriv->migrating = false;
|
||||||
|
|
||||||
if (diskPriv->migrating) {
|
if (diskPriv->migrating) {
|
||||||
|
@ -7846,8 +7846,10 @@ qemuProcessRefreshLegacyBlockjob(void *payload,
|
|||||||
|
|
||||||
if (disk->mirror) {
|
if (disk->mirror) {
|
||||||
if (info->ready == 1 ||
|
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;
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
|
||||||
|
job->state = VIR_DOMAIN_BLOCK_JOB_READY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuBlockJobStartupFinalize(job);
|
qemuBlockJobStartupFinalize(job);
|
||||||
|
Loading…
Reference in New Issue
Block a user