From 639a00984a1b6b328093c2e89f2b329ed4f341e4 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 11 Sep 2014 18:59:32 +0200 Subject: [PATCH] qemu: Report better errors from broken backing chains Request erroring out from the backing chain traveller and drop qemu's internal backing chain integrity tester. The backing chain traveller reports errors by itself with possibly more detail than qemuDiskChainCheckBroken ever could. We also need to make sure that we reconnect to existing qemu instances even at the cost of losing the backing chain info (this really should be stored in the XML rather than reloaded from disk, but that needs some work). --- src/qemu/qemu_domain.c | 29 ++++------------------------- src/qemu/qemu_domain.h | 3 ++- src/qemu/qemu_driver.c | 11 ++++++----- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 12 ++++++++---- 5 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a969d278a0..11145d1999 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2513,27 +2513,6 @@ qemuDomainCheckDiskStartupPolicy(virQEMUDriverPtr driver, return -1; } -static int -qemuDiskChainCheckBroken(virDomainDiskDefPtr disk) -{ - char *brokenFile = NULL; - - if (!virDomainDiskGetSource(disk)) - return 0; - - if (virStorageFileChainGetBroken(disk->src, &brokenFile) < 0) - return -1; - - if (brokenFile) { - virReportError(VIR_ERR_INVALID_ARG, - _("Backing file '%s' of image '%s' is missing."), - brokenFile, virDomainDiskGetSource(disk)); - VIR_FREE(brokenFile); - return -1; - } - - return 0; -} int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver, @@ -2561,8 +2540,7 @@ qemuDomainCheckDiskPresence(virQEMUDriverPtr driver, virFileExists(virDomainDiskGetSource(disk))) continue; - if (qemuDomainDetermineDiskChain(driver, vm, disk, false) >= 0 && - qemuDiskChainCheckBroken(disk) >= 0) + if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) >= 0) continue; if (disk->startupPolicy && @@ -2707,7 +2685,8 @@ int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, - bool force_probe) + bool force_probe, + bool report_broken) { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); int ret = 0; @@ -2729,7 +2708,7 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, if (virStorageFileGetMetadata(disk->src, uid, gid, cfg->allowDiskFormatProbing, - false) < 0) + report_broken) < 0) ret = -1; cleanup: diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index c1d1edf9f1..845d3c7c3a 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -370,7 +370,8 @@ int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver, int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, - bool force_probe); + bool force_probe, + bool report_broken); int qemuDomainStorageFileInit(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d1a0657a6e..543de79e0f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6833,7 +6833,7 @@ qemuDomainChangeDiskMediaLive(virConnectPtr conn, if (virStorageTranslateDiskSourcePool(conn, disk) < 0) goto end; - if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0) + if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) < 0) goto end; switch (disk->device) { @@ -13254,7 +13254,8 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, for (i = 0; i < snap->def->ndisks; i++) { if (snap->def->disks[i].snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) continue; - qemuDomainDetermineDiskChain(driver, vm, vm->def->disks[i], true); + ignore_value(qemuDomainDetermineDiskChain(driver, vm, vm->def->disks[i], + true, true)); } if (orig_err) { virSetError(orig_err); @@ -15062,7 +15063,7 @@ qemuDomainBlockPivot(virConnectPtr conn, oldsrc = disk->src; disk->src = disk->mirror; - if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0) + if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) < 0) goto cleanup; if (disk->mirror->format && @@ -15575,7 +15576,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, goto endjob; } - if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0) + if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) < 0) goto endjob; if ((flags & VIR_DOMAIN_BLOCK_COPY_SHALLOW) && @@ -15944,7 +15945,7 @@ qemuDomainBlockCommit(virDomainPtr dom, disk->dst); goto endjob; } - if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0) + if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) < 0) goto endjob; if (!top) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 7bc19cd9b9..d63188749c 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -779,7 +779,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn, if (qemuSetUnprivSGIO(dev) < 0) goto end; - if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0) + if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) < 0) goto end; switch (disk->device) { diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 13614e9307..dddca35837 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1090,7 +1090,8 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, save = disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE; disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE; disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN; - qemuDomainDetermineDiskChain(driver, vm, disk, true); + ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, + true, true)); } else if (disk->mirror && (type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY || type == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)) { @@ -3430,9 +3431,12 @@ qemuProcessReconnect(void *opaque) if (virStorageTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0) goto error; - /* XXX we should be able to restore all data from XML in the future */ - if (qemuDomainDetermineDiskChain(driver, obj, - obj->def->disks[i], true) < 0) + /* XXX we should be able to restore all data from XML in the future. + * This should be the only place that calls qemuDomainDetermineDiskChain + * with @report_broken == false to guarantee best-effort domain + * reconnect */ + if (qemuDomainDetermineDiskChain(driver, obj, obj->def->disks[i], + true, false) < 0) goto error; dev.type = VIR_DOMAIN_DEVICE_DISK; -- GitLab