--- src/qemu/qemu_blockjob.c | 14 +++++++++--- src/qemu/qemu_blockjob.h | 3 ++- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_migration.c | 55 +++++++++++++++++++++++++++++++++-------------- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index cb00736..5e4fe6d 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -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; @@ -255,6 +263,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; } diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index 47aa4c1..e71d691 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -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, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6255d89..f6fd6ad 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16596,13 +16596,13 @@ qemuDomainBlockJobAbort(virDomainPtr dom, VIR_DOMAIN_BLOCK_JOB_CANCELED); } else { 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); } } } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 272d525..b7ba4c3 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -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; - + /* 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; } -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list