From 0ed445e79cf7311f9c9f37ea4dbece195254468f Mon Sep 17 00:00:00 2001 From: Philipp Hahn Date: Tue, 1 Mar 2011 16:48:20 +0100 Subject: [PATCH] Ignore backing file errors in FS storage pool Currently a single storage volume with a broken backing file will disable the whole storage pool. This can happen when the backing file is on some unavailable network storage or if the backing volume is deleted, while the storage volumes using it remain. Since the storage pool can not be re-activated, re-creating the missing or deleting the now useless volumes using libvirt only is not possible. Fixing this is a little bit tricky: 1. virStorageBackendProbeTarget() only detects the missing backing file, if the backing file format is not explicitly specified. If the backing file is created using kvm-img create -f qcow2 -o backing_fmt=qcow2,backing_file=... ... no error is detected at this stage. The new return code -3 signals that the backing file could not be opened. 2. The backingStore.format must be >= 0, since values < 0 would break virStorageVolTargetDefFormat() when dumping the XML data such as Because of this the format is faked as VIR_STORAGE_FILE_RAW. 3. virStorageBackendUpdateVolTargetInfo() always opens the backing file and thus always detects a missing backing file. Since it "only" updates the capacity, allocation, owner, group, mode and SELinux label, just ignore errors at this stage, print an error message and continue. 4. Using vol-dump on a broken volume still doesn't work, but at least vol-destroy and pool-refresh do work now. To reproduce: dir=$(mktemp -d) virsh pool-create-as tmp dir '' '' '' '' "$dir" virsh vol-create-as --format qcow2 tmp back 1G virsh vol-create-as --format qcow2 --backing-vol-format qcow2 --backing-vol back tmp cow 1G virsh vol-delete --pool tmp back virsh pool-refresh tmp After the last step, the pool will be gone (because it was not persistent). As long as the now broken image stays in the directory, you will not be able to re-create or re-start the pool. Signed-off-by: Philipp Hahn --- src/storage/storage_backend_fs.c | 46 +++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index c33fb05086..0a6b074fb2 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -1,7 +1,7 @@ /* * storage_backend_fs.c: storage backend for FS and directory handling * - * Copyright (C) 2007-2010 Red Hat, Inc. + * Copyright (C) 2007-2011 Red Hat, Inc. * Copyright (C) 2007-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -96,16 +96,25 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target, *backingStore = meta.backingStore; meta.backingStore = NULL; if (meta.backingStoreFormat == VIR_STORAGE_FILE_AUTO) { - if ((*backingStoreFormat - = virStorageFileProbeFormat(*backingStore)) < 0) { - VIR_FORCE_CLOSE(fd); - goto cleanup; + if ((ret = virStorageFileProbeFormat(*backingStore)) < 0) { + /* If the backing file is currently unavailable, only log an error, + * but continue. Returning -1 here would disable the whole storage + * pool, making it unavailable for even maintenance. */ + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot probe backing volume format: %s"), + *backingStore); + ret = -3; + } else { + *backingStoreFormat = ret; + ret = 0; } } else { *backingStoreFormat = meta.backingStoreFormat; + ret = 0; } } else { VIR_FREE(meta.backingStore); + ret = 0; } if (capacity && meta.capacity) @@ -133,7 +142,7 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target, */ } - return 0; + return ret; cleanup: VIR_FREE(*backingStore); @@ -646,15 +655,21 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED, &vol->allocation, &vol->capacity, &vol->target.encryption)) < 0) { - if (ret == -1) - goto cleanup; - else { + if (ret == -2) { /* Silently ignore non-regular files, * eg '.' '..', 'lost+found', dangling symbolic link */ virStorageVolDefFree(vol); vol = NULL; continue; - } + } else if (ret == -3) { + /* The backing file is currently unavailable, its format is not + * explicitly specified, the probe to auto detect the format + * failed: continue with faked RAW format, since AUTO will + * break virStorageVolTargetDefFormat() generating the line + * . */ + backingStoreFormat = VIR_STORAGE_FILE_RAW; + } else + goto cleanup; } if (backingStore != NULL) { @@ -664,8 +679,15 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED, if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore, NULL, NULL) < 0) { - VIR_FREE(vol->backingStore.path); - goto cleanup; + /* The backing file is currently unavailable, the capacity, + * allocation, owner, group and mode are unknown. Just log the + * error an continue. + * Unfortunately virStorageBackendProbeTarget() might already + * have logged a similar message for the same problem, but only + * if AUTO format detection was used. */ + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot probe backing volume info: %s"), + vol->backingStore.path); } } -- GitLab