qemu: report drive mirror errors on migration

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Nikolay Shirokovskiy 2017-10-27 15:37:23 +03:00 committed by Jiri Denemark
parent bc444666f7
commit 5b0451ab57
4 changed files with 54 additions and 22 deletions

View File

@ -47,6 +47,7 @@ VIR_LOG_INIT("qemu.qemu_blockjob");
* @driver: qemu driver
* @vm: domain
* @disk: domain disk
* @error: error (output parameter)
*
* Update disk's mirror state in response to a block job event stored in
* blockJobStatus by qemuProcessHandleBlockJob event handler.
@ -57,17 +58,24 @@ int
qemuBlockJobUpdate(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob,
virDomainDiskDefPtr disk)
virDomainDiskDefPtr disk,
char **error)
{
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
int status = diskPriv->blockJobStatus;
if (error)
*error = NULL;
if (status != -1) {
qemuBlockJobEventProcess(driver, vm, disk, asyncJob,
diskPriv->blockJobType,
diskPriv->blockJobStatus);
diskPriv->blockJobStatus = -1;
VIR_FREE(diskPriv->blockJobError);
if (error)
VIR_STEAL_PTR(*error, diskPriv->blockJobError);
else
VIR_FREE(diskPriv->blockJobError);
}
return status;
@ -249,6 +257,6 @@ qemuBlockJobSyncEnd(virQEMUDriverPtr driver,
virDomainDiskDefPtr disk)
{
VIR_DEBUG("disk=%s", disk->dst);
qemuBlockJobUpdate(driver, vm, asyncJob, disk);
qemuBlockJobUpdate(driver, vm, asyncJob, disk, NULL);
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync = false;
}

View File

@ -29,7 +29,8 @@
int qemuBlockJobUpdate(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob,
virDomainDiskDefPtr disk);
virDomainDiskDefPtr disk,
char **error);
void qemuBlockJobEventProcess(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,

View File

@ -16782,13 +16782,13 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
* block jobs from confusing us. */
if (!async) {
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
qemuBlockJobUpdate(driver, vm, QEMU_ASYNC_JOB_NONE, disk);
qemuBlockJobUpdate(driver, vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
while (diskPriv->blockjob) {
if (virDomainObjWait(vm) < 0) {
ret = -1;
goto endjob;
}
qemuBlockJobUpdate(driver, vm, QEMU_ASYNC_JOB_NONE, disk);
qemuBlockJobUpdate(driver, vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
}
}

View File

@ -611,17 +611,25 @@ qemuMigrationDriveMirrorReady(virQEMUDriverPtr driver,
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
char *error = NULL;
if (!diskPriv->migrating)
continue;
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk);
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
if (status == VIR_DOMAIN_BLOCK_JOB_FAILED) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed"),
disk->dst);
if (error) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed: %s"),
disk->dst, error);
VIR_FREE(error);
} else {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed"), disk->dst);
}
return -1;
}
VIR_FREE(error);
if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY)
notReady++;
@ -663,17 +671,23 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
char *error = NULL;
if (!diskPriv->migrating)
continue;
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk);
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
switch (status) {
case VIR_DOMAIN_BLOCK_JOB_FAILED:
if (check) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed"),
disk->dst);
if (error) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed: %s"),
disk->dst, error);
} else {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed"), disk->dst);
}
failed = true;
}
ATTRIBUTE_FALLTHROUGH;
@ -689,6 +703,8 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
completed++;
VIR_FREE(error);
}
/* Updating completed block job drops the lock thus we have to recheck
@ -736,24 +752,30 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
{
qemuDomainObjPrivatePtr priv = vm->privateData;
char *diskAlias = NULL;
char *error = NULL;
int ret = -1;
int status;
int rv;
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk);
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
switch (status) {
case VIR_DOMAIN_BLOCK_JOB_FAILED:
case VIR_DOMAIN_BLOCK_JOB_CANCELED:
if (failNoJob) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed"),
disk->dst);
return -1;
if (error) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed: %s"),
disk->dst, error);
} else {
virReportError(VIR_ERR_OPERATION_FAILED,
_("migration of disk %s failed"), disk->dst);
}
goto cleanup;
}
return 1;
ATTRIBUTE_FALLTHROUGH;
case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
return 1;
ret = 1;
goto cleanup;
}
if (!(diskAlias = qemuAliasFromDisk(disk)))
@ -771,6 +793,7 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
cleanup:
VIR_FREE(diskAlias);
VIR_FREE(error);
return ret;
}