Re: [PATCH 2/3] storage: add qcow2 filename parsing from header

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Aug 11, 2024 at 17:34:47 +0300, Nikolai Barybin via Devel wrote:
> Signed-off-by: Nikolai Barybin <nikolai.barybin@xxxxxxxxxxxxx>
> ---
>  src/storage_file/storage_file_probe.c | 66 +++++++++++++++++++++++----
>  1 file changed, 57 insertions(+), 9 deletions(-)
> 
> diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c
> index 243927d50a..c7ff743c87 100644
> --- a/src/storage_file/storage_file_probe.c
> +++ b/src/storage_file/storage_file_probe.c
> @@ -93,8 +93,9 @@ struct FileTypeInfo {
>                                           size_t buf_size);
>      int (*getBackingStore)(char **res, int *format,
>                             const char *buf, size_t buf_size);
> +    int (*getDataFile)(char **res, const char *buf, int format, size_t buf_size);
>      int (*getFeatures)(virBitmap **features, int format,
> -                       char *buf, ssize_t len);
> +                       const char *buf, ssize_t len);

This looks like a separate refactor. Please don't mix those. Especially
if you don't document what's happening.

>  };
>  
>  
> @@ -105,8 +106,9 @@ qcow2GetClusterSize(const char *buf,
>                      size_t buf_size);
>  static int qcowXGetBackingStore(char **, int *,
>                                  const char *, size_t);
> +static int qcowXGetDataFile(char **, const char *, int, size_t);
>  static int qcow2GetFeatures(virBitmap **features, int format,
> -                            char *buf, ssize_t len);
> +                            const char *buf, ssize_t len);
>  static int vmdk4GetBackingStore(char **, int *,
>                                  const char *, size_t);
>  static int
> @@ -126,6 +128,7 @@ qedGetBackingStore(char **, int *, const char *, size_t);
>  
>  #define QCOW2_HDR_EXTENSION_END 0
>  #define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
> +#define QCOW2_HDR_EXTENSION_DATA_FILE_NAME 0x44415441
>  
>  #define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE)
>  #define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE+8)
> @@ -313,6 +316,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
>          qcow2EncryptionInfo,
>          qcow2GetClusterSize,
>          qcowXGetBackingStore,
> +        qcowXGetDataFile,
>          qcow2GetFeatures
>      },
>      [VIR_STORAGE_FILE_QED] = {
> @@ -359,7 +363,7 @@ enum qcow2IncompatibleFeature {
>  static const virStorageFileFeature qcow2IncompatibleFeatureArray[] = {
>      VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DIRTY */
>      VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_CORRUPT */
> -    VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DATA_FILE */
> +    VIR_STORAGE_FILE_FEATURE_DATA_FILE, /* QCOW2_INCOMPATIBLE_FEATURE_DATA_FILE */
>      VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_COMPRESSION */
>      VIR_STORAGE_FILE_FEATURE_EXTENDED_L2, /* QCOW2_INCOMPATIBLE_FEATURE_EXTL2 */
>  };
> @@ -391,7 +395,7 @@ cowGetBackingStore(char **res,
>  static int
>  qcow2GetExtensions(const char *buf,
>                     size_t buf_size,
> -                   int *backingFormat)
> +                   void *data)
>  {
>      size_t offset;
>      size_t extension_start;
> @@ -467,7 +471,7 @@ qcow2GetExtensions(const char *buf,
>          switch (magic) {
>          case QCOW2_HDR_EXTENSION_BACKING_FORMAT: {
>              g_autofree char *tmp = NULL;
> -            if (!backingFormat)
> +            if (!data)
>                  break;
>  
>              tmp = g_new0(char, len + 1);
> @@ -480,9 +484,20 @@ qcow2GetExtensions(const char *buf,
>               * doesn't look like a format driver name to be a protocol driver
>               * directly and thus the image is in fact still considered raw
>               */
> -            *backingFormat = virStorageFileFormatTypeFromString(tmp);
> -            if (*backingFormat <= VIR_STORAGE_FILE_NONE)
> -                *backingFormat = VIR_STORAGE_FILE_RAW;
> +            *(int *)data = virStorageFileFormatTypeFromString(tmp);
> +            if (*(int *)data <= VIR_STORAGE_FILE_NONE)
> +                *(int *)data = VIR_STORAGE_FILE_RAW;

Please add new fields rather than doing this overwrite.

> +            break;
> +        }
> +
> +        case QCOW2_HDR_EXTENSION_DATA_FILE_NAME: {
> +            g_autofree char *tmp = NULL;
> +            if (!data)
> +                break;
> +
> +            *(char **)data = g_new0(char, len + 1);
> +            memcpy(*(char **)data, buf + offset, len);
> +            (*((char **)data))[len] = '\0';

How is this even supposed to work? The function loops over all
extensions in the header so it would overwrite the previous value.

>              break;
>          }
>  
> @@ -559,6 +574,33 @@ qcowXGetBackingStore(char **res,
>  }
>  
>  
> +static int
> +qcowXGetDataFile(char **res,
> +                 const char *buf,
> +                 int format,
> +                 size_t buf_size)
> +{
> +    virBitmap *features = NULL;
> +    char *filename = NULL;
> +    size_t namelen = 0;
> +    *res = NULL;
> +
> +    if (buf_size < QCOW2v3_HDR_FEATURES_INCOMPATIBLE + 8)
> +        return 0;
> +
> +    ignore_value(qcow2GetFeatures(&features, format, buf, buf_size));
> +    if (features && virBitmapIsBitSet(features, VIR_STORAGE_FILE_FEATURE_DATA_FILE)) {
> +        if (qcow2GetExtensions(buf, buf_size, &filename) < 0)
> +            return 0;
> +
> +        namelen = strlen(filename) + 1;
> +        *res = g_new0(char, namelen);
> +        memcpy(*res, filename, namelen);

Ummm, so you 'strlen()' the buffer, but then use memcpy? You can use
'g_strdup' directly.

> +    }
> +
> +    return 0;
> +}
> +
>  static int
>  vmdk4GetBackingStore(char **res,
>                       int *format,
> @@ -789,7 +831,7 @@ qcow2GetFeaturesProcessGroup(uint64_t bits,
>  static int
>  qcow2GetFeatures(virBitmap **features,
>                   int format,
> -                 char *buf,
> +                 const char *buf,
>                   ssize_t len)
>  {
>      int version = -1;
> @@ -961,6 +1003,12 @@ virStorageFileProbeGetMetadata(virStorageSource *meta,
>          meta->backingStoreRawFormat = format;
>      }
>  
> +    VIR_FREE(meta->dataFileRaw);
> +    if (fileTypeInfo[meta->format].getDataFile != NULL) {
> +        fileTypeInfo[meta->format].getDataFile(&meta->dataFileRaw,
> +                                               buf, meta->format, len);
> +    }
> +
>      g_clear_pointer(&meta->features, virBitmapFree);
>      if (fileTypeInfo[meta->format].getFeatures != NULL &&
>          fileTypeInfo[meta->format].getFeatures(&meta->features, meta->format, buf, len) < 0)
> -- 
> 2.43.5
> 



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux