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

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

 



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);
 };
 
 
@@ -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;
+            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';
             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);
+    }
+
+    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