So far, my work has been merely preserving the status quo of
backing file analysis. But this patch starts to tread in the
territory of making the backing chain code more powerful - we
will eventually support network storage containing non-raw
formats. Here, we expose metadata information about a network
backing store, even if that information is still hardcoded to
a raw format for now.
* src/util/virstoragefile.c (virStorageFileGetMetadataRecurse):
Also populate struct for non-file backing.
(virStorageFileGetMetadata, virStorageFileGetMetadatainternal):
Recognize non-file top image.
(virFindBackingFile): Add comment.
* tests/virstoragetest.c (mymain): Update test to reflect it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/util/virstoragefile.c | 62 +++++++++++++++++++++++++++++++++++------------
tests/virstoragetest.c | 17 +++++++++----
2 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index f5fe8ad..7a91a01 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -569,6 +569,14 @@ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
ATTRIBUTE_NONNULL(4)
virFindBackingFile(const char *start, const char *path,
char **directory, char **canonical)
{
+ /* FIXME - when we eventually allow non-raw network devices, we
+ * must ensure that we handle backing files the same way as qemu.
+ * For a qcow2 top file of gluster://server/vol/img, qemu treats
+ * the relative backing file 'rel' as meaning
+ * 'gluster://server/vol/rel', while the backing file '/abs' is
+ * used as a local file. But we cannot canonicalize network
+ * devices via canonicalize_file_name(), because they are not part
+ * of the local file system. */
char *combined = NULL;
int ret = -1;
@@ -874,6 +882,12 @@ virStorageFileGetMetadataInternal(const char *path,
meta->backingStoreRaw, path);
}
+ } else {
+ if (VIR_STRDUP(meta->backingStoreRaw, backing) < 0) {
+ VIR_FREE(backing);
+ goto cleanup;
+ }
+ backingFormat = VIR_STORAGE_FILE_RAW;
}
VIR_FREE(backing);
meta->backingStoreFormat = backingFormat;
@@ -1132,18 +1146,32 @@ virStorageFileGetMetadataRecurse(const char *path, const char
*canonPath,
if (virHashAddEntry(cycle, canonPath, (void *)1) < 0)
return -1;
- if ((fd = virFileOpenAs(canonPath, O_RDONLY, 0, uid, gid, 0)) < 0) {
- virReportSystemError(-fd, _("Failed to open file '%s'"),
path);
- return -1;
- }
+ if (virBackingStoreIsFile(path)) {
+ if ((fd = virFileOpenAs(canonPath, O_RDONLY, 0, uid, gid, 0)) < 0) {
+ virReportSystemError(-fd, _("Failed to open file '%s'"),
path);
+ return -1;
+ }
- ret = virStorageFileGetMetadataFromFDInternal(path, canonPath, directory,
- fd, format, meta);
+ ret = virStorageFileGetMetadataFromFDInternal(path, canonPath,
+ directory,
+ fd, format, meta);
- if (VIR_CLOSE(fd) < 0)
- VIR_WARN("could not close file %s", path);
+ if (VIR_CLOSE(fd) < 0)
+ VIR_WARN("could not close file %s", path);
+ } else {
+ /* FIXME: when the proper storage drivers are compiled in, it
+ * would be nice to read metadata from the network storage to
+ * allow for non-raw images. */
+ if (VIR_STRDUP(meta->path, path) < 0)
+ return -1;
+ if (VIR_STRDUP(meta->canonPath, path) < 0)
+ return -1;
+ meta->type = VIR_STORAGE_TYPE_NETWORK;
+ meta->format = VIR_STORAGE_FILE_RAW;
+ ret = 0;
+ }
- if (ret == 0 && meta->backingStoreIsFile) {
+ if (ret == 0 && meta->backingStore) {
virStorageFileMetadataPtr backing;
if (meta->backingStoreFormat == VIR_STORAGE_FILE_AUTO &&
!allow_probe)
@@ -1207,12 +1235,16 @@ virStorageFileGetMetadata(const char *path, int format,
if (!cycle)
return NULL;
- if (!(canonPath = canonicalize_file_name(path))) {
- virReportSystemError(errno, _("unable to resolve '%s'"),
path);
- goto cleanup;
- }
- if (!(directory = mdir_name(path))) {
- virReportOOMError();
+ if (virBackingStoreIsFile(path)) {
+ if (!(canonPath = canonicalize_file_name(path))) {
+ virReportSystemError(errno, _("unable to resolve '%s'"),
path);
+ goto cleanup;
+ }
+ if (!(directory = mdir_name(path))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else if (VIR_STRDUP(canonPath, path) < 0) {
goto cleanup;
}
if (VIR_ALLOC(meta) < 0)
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index 9a9b0d8..e8409f6 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -621,17 +621,24 @@ mymain(void)
if (virCommandRun(cmd, NULL) < 0)
ret = -1;
qcow2.expBackingStore = "nbd:example.org:6000";
- qcow2.expBackingStoreRaw = NULL;
+ qcow2.expBackingStoreRaw = "nbd:example.org:6000";
qcow2.expBackingDirRel = NULL;
qcow2.expBackingDirAbs = NULL;
qcow2.expBackingFormat = VIR_STORAGE_FILE_RAW;
/* Qcow2 file with backing protocol instead of file */
+ testFileData nbd = {
+ .pathRel = "nbd:example.org:6000",
+ .pathAbs = "nbd:example.org:6000",
+ .canonPath = "nbd:example.org:6000",
+ .type = VIR_STORAGE_TYPE_NETWORK,
+ .format = VIR_STORAGE_FILE_RAW,
+ };
TEST_CHAIN(11, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2,
- (&qcow2), EXP_PASS,
- (&qcow2), ALLOW_PROBE | EXP_PASS,
- (&qcow2), EXP_PASS,
- (&qcow2), ALLOW_PROBE | EXP_PASS);
+ (&qcow2, &nbd), EXP_PASS,
+ (&qcow2, &nbd), ALLOW_PROBE | EXP_PASS,
+ (&qcow2, &nbd), EXP_PASS,
+ (&qcow2, &nbd), ALLOW_PROBE | EXP_PASS);
/* qed file */
testFileData qed = {
--
1.9.0