[PATCH 07/15] storage file: fill in src->dataFileStore during file probe

Nikolai Barybin via Devel posted 15 patches 1 week, 6 days ago
[PATCH 07/15] storage file: fill in src->dataFileStore during file probe
Posted by Nikolai Barybin via Devel 1 week, 6 days ago
Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com>
---
 src/storage_file/storage_source.c | 39 +++++++++++++++++++++++++++++++
 src/storage_file/storage_source.h |  4 ++++
 2 files changed, 43 insertions(+)

diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_source.c
index 2cfe3bc325..b9d2d71aea 100644
--- a/src/storage_file/storage_source.c
+++ b/src/storage_file/storage_source.c
@@ -543,6 +543,33 @@ virStorageSourceNewFromBacking(virStorageSource *parent,
 }
 
 
+/**
+ * virStorageSourceNewFromDataFile:
+ * @parent: storage source parent
+ * @dataFileSrc: returned data file source definition
+ *
+ * Creates a storage source which describes the data file image of @parent.
+ * Returned storage source format is VIR_STORAGE_FILE_RAW, and, unlike
+ * backing storage creation, readonly flag is copied from @parent.
+ *
+ * Return codes are the same as in virStorageSourceNewFromChild.
+ */
+int
+virStorageSourceNewFromDataFile(virStorageSource *parent,
+                                virStorageSource **dataFileSrc)
+{
+    if (virStorageSourceNewFromChild(parent,
+                                     parent->dataFileRaw,
+                                     dataFileSrc) < 0)
+        return -1;
+
+    (*dataFileSrc)->format = VIR_STORAGE_FILE_RAW;
+    (*dataFileSrc)->readonly = parent->readonly;
+
+    return 0;
+}
+
+
 /**
  * @src: disk source definition structure
  * @fd: file descriptor
@@ -1391,6 +1418,18 @@ virStorageSourceGetMetadataRecurse(virStorageSource *src,
         }
     }
 
+    if (src->dataFileRaw) {
+        g_autoptr(virStorageSource) dataFileStore = NULL;
+        if ((rv = virStorageSourceNewFromDataFile(src, &dataFileStore)) < 0)
+            return -1;
+
+        /* the data file would not be usable for VM usage */
+        if (rv == 1)
+            return 0;
+
+        src->dataFileStore = g_steal_pointer(&dataFileStore);
+    }
+
     if (src->backingStoreRaw) {
         if ((rv = virStorageSourceNewFromBacking(src, &backingStore)) < 0)
             return -1;
diff --git a/src/storage_file/storage_source.h b/src/storage_file/storage_source.h
index 63fefb6919..78b31e405a 100644
--- a/src/storage_file/storage_source.h
+++ b/src/storage_file/storage_source.h
@@ -72,6 +72,10 @@ int
 virStorageSourceNewFromBacking(virStorageSource *parent,
                                virStorageSource **backing);
 
+int
+virStorageSourceNewFromDataFile(virStorageSource *parent,
+                                virStorageSource **dataFileSrc);
+
 int
 virStorageSourceGetRelativeBackingPath(virStorageSource *top,
                                        virStorageSource *base,
-- 
2.43.5
Re: [PATCH 07/15] storage file: fill in src->dataFileStore during file probe
Posted by Peter Krempa 1 week, 5 days ago
On Wed, Nov 20, 2024 at 18:48:42 +0300, Nikolai Barybin via Devel wrote:
> Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com>
> ---
>  src/storage_file/storage_source.c | 39 +++++++++++++++++++++++++++++++
>  src/storage_file/storage_source.h |  4 ++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_source.c
> index 2cfe3bc325..b9d2d71aea 100644
> --- a/src/storage_file/storage_source.c
> +++ b/src/storage_file/storage_source.c
> @@ -543,6 +543,33 @@ virStorageSourceNewFromBacking(virStorageSource *parent,
>  }
>  
>  
> +/**
> + * virStorageSourceNewFromDataFile:
> + * @parent: storage source parent
> + * @dataFileSrc: returned data file source definition
> + *
> + * Creates a storage source which describes the data file image of @parent.
> + * Returned storage source format is VIR_STORAGE_FILE_RAW, and, unlike
> + * backing storage creation, readonly flag is copied from @parent.
> + *
> + * Return codes are the same as in virStorageSourceNewFromChild.
> + */
> +int

This function is never used outside of this module thus should not be
exported.

> +virStorageSourceNewFromDataFile(virStorageSource *parent,
> +                                virStorageSource **dataFileSrc)
> +{
> +    if (virStorageSourceNewFromChild(parent,
> +                                     parent->dataFileRaw,
> +                                     dataFileSrc) < 0)
> +        return -1;

This strips the possibility to return '1' which you've explicitly
documented above.

Thinking about it a bit; the logic which is for backing store regarding
the skipping of detection if libvirt can't parse it is a stop-gap
measure for pre-existing configs when the blockdev code was being
introduced. It meant to simply skip the backing store definition via
-blockdev in case libvirt can't do that and offloaded it to qemu.

For data files I don't think we need this kind of logic, and can fail
instead.

> +
> +    (*dataFileSrc)->format = VIR_STORAGE_FILE_RAW;
> +    (*dataFileSrc)->readonly = parent->readonly;
> +
> +    return 0;
> +}
> +
> +
>  /**
>   * @src: disk source definition structure
>   * @fd: file descriptor
> @@ -1391,6 +1418,18 @@ virStorageSourceGetMetadataRecurse(virStorageSource *src,
>          }
>      }
>  
> +    if (src->dataFileRaw) {
> +        g_autoptr(virStorageSource) dataFileStore = NULL;
> +        if ((rv = virStorageSourceNewFromDataFile(src, &dataFileStore)) < 0)
> +            return -1;
> +
> +        /* the data file would not be usable for VM usage */
> +        if (rv == 1)
> +            return 0;

Apart from what I wrote above, this would be wrong here as this would
also skip the backing store parsing below. Now with the change to report
error if 'data-store' can't be fully processed by libvirt the location
and logich here will be correct, but the above return statement will be
removed.

> +

I'll be changing this to:

diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_source.c
index 2cfe3bc325..df73f44699 100644
--- a/src/storage_file/storage_source.c
+++ b/src/storage_file/storage_source.c
@@ -543,6 +543,39 @@ virStorageSourceNewFromBacking(virStorageSource *parent,
 }


+/**
+ * virStorageSourceNewFromDataFile:
+ * @parent: storage source parent
+ *
+ * Creates a storage source which describes the data file image of @parent.
+ * Returned storage source format is VIR_STORAGE_FILE_RAW, and, unlike
+ * backing storage creation, readonly flag is copied from @parent.
+ */
+static virStorageSource *
+virStorageSourceNewFromDataFile(virStorageSource *parent)
+{
+    g_autoptr(virStorageSource) dataFile = NULL;
+    int rc;
+
+    if ((rc = virStorageSourceNewFromChild(parent,
+                                           parent->dataFileRaw,
+                                           &dataFile)) < 0)
+        return NULL;
+
+    if (rc == 1) {
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       _("can't use data file definition '%1$s'"),
+                       parent->dataFileRaw);
+        return NULL;
+    }
+
+    dataFile->format = VIR_STORAGE_FILE_RAW;
+    dataFile->readonly = parent->readonly;
+
+    return g_steal_pointer(&dataFile);
+}
+
+
 /**
  * @src: disk source definition structure
  * @fd: file descriptor
@@ -1391,6 +1424,11 @@ virStorageSourceGetMetadataRecurse(virStorageSource *src,
         }
     }

+    if (src->dataFileRaw) {
+        if (!(src->dataFileStore = virStorageSourceNewFromDataFile(src)))
+            return -1;
+    }
+
     if (src->backingStoreRaw) {
         if ((rv = virStorageSourceNewFromBacking(src, &backingStore)) < 0)
             return -1;
Re: [PATCH 07/15] storage file: fill in src->dataFileStore during file probe
Posted by Peter Krempa 1 week ago
On Thu, Nov 21, 2024 at 15:11:46 +0100, Peter Krempa wrote:
> On Wed, Nov 20, 2024 at 18:48:42 +0300, Nikolai Barybin via Devel wrote:
> > Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com>
> > ---
> >  src/storage_file/storage_source.c | 39 +++++++++++++++++++++++++++++++
> >  src/storage_file/storage_source.h |  4 ++++
> >  2 files changed, 43 insertions(+)



> @@ -1391,6 +1424,11 @@ virStorageSourceGetMetadataRecurse(virStorageSource *src,
>          }
>      }
> 
> +    if (src->dataFileRaw) {

In addition to this change we must also not fill this if the current
'src' already has the 'dataFileStore' member populated. It can happen
that you have the last image in chain with a <dataStore> but without
<backingStore> that situation invokes probing of the image and here we'd
overwrite the user-configured <dataStore>.