qemu: report drive mirror errors on migration
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
bc444666f7
commit
5b0451ab57
@ -47,6 +47,7 @@ VIR_LOG_INIT("qemu.qemu_blockjob");
|
|||||||
* @driver: qemu driver
|
* @driver: qemu driver
|
||||||
* @vm: domain
|
* @vm: domain
|
||||||
* @disk: domain disk
|
* @disk: domain disk
|
||||||
|
* @error: error (output parameter)
|
||||||
*
|
*
|
||||||
* Update disk's mirror state in response to a block job event stored in
|
* Update disk's mirror state in response to a block job event stored in
|
||||||
* blockJobStatus by qemuProcessHandleBlockJob event handler.
|
* blockJobStatus by qemuProcessHandleBlockJob event handler.
|
||||||
@ -57,17 +58,24 @@ int
|
|||||||
qemuBlockJobUpdate(virQEMUDriverPtr driver,
|
qemuBlockJobUpdate(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
qemuDomainAsyncJob asyncJob,
|
qemuDomainAsyncJob asyncJob,
|
||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk,
|
||||||
|
char **error)
|
||||||
{
|
{
|
||||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||||
int status = diskPriv->blockJobStatus;
|
int status = diskPriv->blockJobStatus;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
|
||||||
if (status != -1) {
|
if (status != -1) {
|
||||||
qemuBlockJobEventProcess(driver, vm, disk, asyncJob,
|
qemuBlockJobEventProcess(driver, vm, disk, asyncJob,
|
||||||
diskPriv->blockJobType,
|
diskPriv->blockJobType,
|
||||||
diskPriv->blockJobStatus);
|
diskPriv->blockJobStatus);
|
||||||
diskPriv->blockJobStatus = -1;
|
diskPriv->blockJobStatus = -1;
|
||||||
VIR_FREE(diskPriv->blockJobError);
|
if (error)
|
||||||
|
VIR_STEAL_PTR(*error, diskPriv->blockJobError);
|
||||||
|
else
|
||||||
|
VIR_FREE(diskPriv->blockJobError);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -249,6 +257,6 @@ qemuBlockJobSyncEnd(virQEMUDriverPtr driver,
|
|||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
VIR_DEBUG("disk=%s", disk->dst);
|
VIR_DEBUG("disk=%s", disk->dst);
|
||||||
qemuBlockJobUpdate(driver, vm, asyncJob, disk);
|
qemuBlockJobUpdate(driver, vm, asyncJob, disk, NULL);
|
||||||
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync = false;
|
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync = false;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
int qemuBlockJobUpdate(virQEMUDriverPtr driver,
|
int qemuBlockJobUpdate(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
qemuDomainAsyncJob asyncJob,
|
qemuDomainAsyncJob asyncJob,
|
||||||
virDomainDiskDefPtr disk);
|
virDomainDiskDefPtr disk,
|
||||||
|
char **error);
|
||||||
void qemuBlockJobEventProcess(virQEMUDriverPtr driver,
|
void qemuBlockJobEventProcess(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
|
@ -16782,13 +16782,13 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
* block jobs from confusing us. */
|
* block jobs from confusing us. */
|
||||||
if (!async) {
|
if (!async) {
|
||||||
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
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) {
|
while (diskPriv->blockjob) {
|
||||||
if (virDomainObjWait(vm) < 0) {
|
if (virDomainObjWait(vm) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
qemuBlockJobUpdate(driver, vm, QEMU_ASYNC_JOB_NONE, disk);
|
qemuBlockJobUpdate(driver, vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,17 +611,25 @@ qemuMigrationDriveMirrorReady(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);
|
||||||
|
char *error = NULL;
|
||||||
|
|
||||||
if (!diskPriv->migrating)
|
if (!diskPriv->migrating)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk);
|
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
|
||||||
if (status == VIR_DOMAIN_BLOCK_JOB_FAILED) {
|
if (status == VIR_DOMAIN_BLOCK_JOB_FAILED) {
|
||||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
if (error) {
|
||||||
_("migration of disk %s failed"),
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
disk->dst);
|
_("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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
VIR_FREE(error);
|
||||||
|
|
||||||
if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY)
|
if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY)
|
||||||
notReady++;
|
notReady++;
|
||||||
@ -663,17 +671,23 @@ qemuMigrationDriveMirrorCancelled(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);
|
||||||
|
char *error = NULL;
|
||||||
|
|
||||||
if (!diskPriv->migrating)
|
if (!diskPriv->migrating)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk);
|
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case VIR_DOMAIN_BLOCK_JOB_FAILED:
|
case VIR_DOMAIN_BLOCK_JOB_FAILED:
|
||||||
if (check) {
|
if (check) {
|
||||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
if (error) {
|
||||||
_("migration of disk %s failed"),
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
disk->dst);
|
_("migration of disk %s failed: %s"),
|
||||||
|
disk->dst, error);
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("migration of disk %s failed"), disk->dst);
|
||||||
|
}
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
ATTRIBUTE_FALLTHROUGH;
|
ATTRIBUTE_FALLTHROUGH;
|
||||||
@ -689,6 +703,8 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
|
if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
|
||||||
completed++;
|
completed++;
|
||||||
|
|
||||||
|
VIR_FREE(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Updating completed block job drops the lock thus we have to recheck
|
/* Updating completed block job drops the lock thus we have to recheck
|
||||||
@ -736,24 +752,30 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
|
|||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
char *diskAlias = NULL;
|
char *diskAlias = NULL;
|
||||||
|
char *error = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int status;
|
int status;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk);
|
status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case VIR_DOMAIN_BLOCK_JOB_FAILED:
|
case VIR_DOMAIN_BLOCK_JOB_FAILED:
|
||||||
case VIR_DOMAIN_BLOCK_JOB_CANCELED:
|
case VIR_DOMAIN_BLOCK_JOB_CANCELED:
|
||||||
if (failNoJob) {
|
if (failNoJob) {
|
||||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
if (error) {
|
||||||
_("migration of disk %s failed"),
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
disk->dst);
|
_("migration of disk %s failed: %s"),
|
||||||
return -1;
|
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:
|
case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
|
||||||
return 1;
|
ret = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(diskAlias = qemuAliasFromDisk(disk)))
|
if (!(diskAlias = qemuAliasFromDisk(disk)))
|
||||||
@ -771,6 +793,7 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(diskAlias);
|
VIR_FREE(diskAlias);
|
||||||
|
VIR_FREE(error);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user