diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 4ee1168f0da78d983723f264151e69391f3347b8..2e0b61fc89e677fd14d20bb82d1e2c34cf1e6fc6 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -202,6 +202,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 0x44415441 #define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE) #define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE+8) @@ -429,7 +430,8 @@ cowGetBackingStore(char **res, static int qcow2GetExtensions(const char *buf, size_t buf_size, - int *backingFormat) + int *backingFormat, + char **externalDataStoreRaw) { size_t offset; size_t extension_start; @@ -505,6 +507,9 @@ qcow2GetExtensions(const char *buf, switch (magic) { case QCOW2_HDR_EXTENSION_BACKING_FORMAT: { VIR_AUTOFREE(char *) tmp = NULL; + if (!backingFormat) + break; + if (VIR_ALLOC_N(tmp, len + 1) < 0) return -1; memcpy(tmp, buf + offset, len); @@ -516,6 +521,19 @@ qcow2GetExtensions(const char *buf, break; } + case QCOW2_HDR_EXTENSION_DATA_FILE: { + if (!externalDataStoreRaw) + break; + + if (VIR_ALLOC_N(*externalDataStoreRaw, len + 1) < 0) + return -1; + memcpy(*externalDataStoreRaw, buf + offset, len); + (*externalDataStoreRaw)[len] = '\0'; + VIR_DEBUG("parsed externalDataStoreRaw='%s'", + *externalDataStoreRaw); + break; + } + case QCOW2_HDR_EXTENSION_END: goto done; } @@ -567,7 +585,7 @@ qcowXGetBackingStore(char **res, memcpy(*res, buf + offset, size); (*res)[size] = '\0'; - if (qcow2GetExtensions(buf, buf_size, format) < 0) + if (qcow2GetExtensions(buf, buf_size, format, NULL) < 0) return BACKING_STORE_INVALID; return BACKING_STORE_OK; @@ -2259,6 +2277,7 @@ virStorageSourceCopy(const virStorageSource *src, VIR_STRDUP(def->volume, src->volume) < 0 || VIR_STRDUP(def->relPath, src->relPath) < 0 || VIR_STRDUP(def->backingStoreRaw, src->backingStoreRaw) < 0 || + VIR_STRDUP(def->externalDataStoreRaw, src->externalDataStoreRaw) < 0 || VIR_STRDUP(def->snapshot, src->snapshot) < 0 || VIR_STRDUP(def->configFile, src->configFile) < 0 || VIR_STRDUP(def->nodeformat, src->nodeformat) < 0 || @@ -2534,6 +2553,7 @@ virStorageSourceClear(virStorageSourcePtr def) virStorageSourceSeclabelsClear(def); virStoragePermsFree(def->perms); VIR_FREE(def->timestamps); + VIR_FREE(def->externalDataStoreRaw); virStorageNetHostDefFree(def->nhosts, def->hosts); virStorageAuthDefFree(def->auth); diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 2472d89c8588fc42f53298c4f9c3f9a4df2ba4bf..bbff511657d7d1f4efe7d10491573b52f93bcb0b 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -302,6 +302,8 @@ struct _virStorageSource { /* Name of the child backing store recorded in metadata of the * current file. */ char *backingStoreRaw; + /* Name of the child data file recorded in metadata of the current file. */ + char *externalDataStoreRaw; /* metadata that allows identifying given storage source */ char *nodeformat; /* name of the format handler object */