[libvirt] [RFC PATCH 4/5] util: storagefile: Add deep copy for struct virStorageSource

Peter Krempa pkrempa at redhat.com
Thu Jun 12 15:02:18 UTC 2014


Now that we have pointers to store disk source information and thus can
easily exchange the structs behind we need a function to copy all the
data.
---
 src/libvirt_private.syms  |   1 +
 src/util/virstoragefile.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virstoragefile.h |   2 +
 3 files changed, 153 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 122c572..08e67b2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1889,6 +1889,7 @@ virStorageNetProtocolTypeToString;
 virStorageSourceAuthClear;
 virStorageSourceClear;
 virStorageSourceClearBackingStore;
+virStorageSourceCopy;
 virStorageSourceFree;
 virStorageSourceGetActualType;
 virStorageSourceNewFromBacking;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 67c1471..8998807 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1489,6 +1489,156 @@ virStorageNetHostDefCopy(size_t nhosts,
 }


+static virStorageTimestampsPtr
+virStorageTimestampsCopy(const virStorageTimestamps *src)
+{
+    virStorageTimestampsPtr ret;
+
+    if (VIR_ALLOC(ret) < 0)
+        return NULL;
+
+    memcpy(ret, src, sizeof(*src));
+
+    return ret;
+}
+
+
+static virStoragePermsPtr
+virStoragePermsCopy(const virStoragePerms *src)
+{
+    virStoragePermsPtr ret;
+
+    if (VIR_ALLOC(ret) < 0)
+        return NULL;
+
+    ret->mode = src->mode;
+    ret->uid = src->uid;
+    ret->gid = src->gid;
+
+    if (VIR_STRDUP(ret->label, src->label))
+        goto error;
+
+    return ret;
+
+ error:
+    virStoragePermsFree(ret);
+    return NULL;
+}
+
+
+static virStorageSourcePoolDefPtr
+virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src)
+{
+    virStorageSourcePoolDefPtr ret;
+
+    if (VIR_ALLOC(ret) < 0)
+        return NULL;
+
+    ret->voltype = src->voltype;
+    ret->pooltype = src->pooltype;
+    ret->actualtype = src->actualtype;
+    ret->mode = src->mode;
+
+    if (VIR_STRDUP(ret->pool, src->pool) < 0 ||
+        VIR_STRDUP(ret->volume, src->volume) < 0)
+        goto error;
+
+    return ret;
+
+ error:
+    virStorageSourcePoolDefFree(ret);
+    return NULL;
+}
+
+
+virStorageSourcePtr
+virStorageSourceCopy(const virStorageSource *src,
+                     bool backingChain)
+{
+    size_t i;
+    virStorageSourcePtr ret = NULL;
+
+    if (VIR_ALLOC(ret) < 0)
+        return NULL;
+
+    ret->type = src->type;
+    ret->protocol = src->protocol;
+    ret->format = src->format;
+    ret->allocation = src->allocation;
+    ret->capacity = src->capacity;
+    ret->backingRelative = src->backingRelative;
+
+    /* storage driver metadata are not copied */
+    ret->drv = NULL;
+
+    if (VIR_STRDUP(ret->path, src->path) < 0 ||
+        VIR_STRDUP(ret->volume, src->volume) < 0 ||
+        VIR_STRDUP(ret->driverName, src->driverName) < 0 ||
+        VIR_STRDUP(ret->relPath, src->relPath) < 0 ||
+        VIR_STRDUP(ret->relDir, src->relDir) < 0 ||
+        VIR_STRDUP(ret->backingStoreRaw, src->backingStoreRaw) < 0 ||
+        VIR_STRDUP(ret->compat, src->compat) < 0 ||
+        VIR_STRDUP(ret->auth.username, src->auth.username) < 0)
+        goto error;
+
+    if (!(ret->hosts = virStorageNetHostDefCopy(src->nhosts, src->hosts)))
+        goto error;
+    ret->nhosts = src->nhosts;
+
+    if (!(ret->srcpool = virStorageSourcePoolDefCopy(src->srcpool)))
+        goto error;
+
+    if (!(ret->features = virBitmapNewCopy(src->features)))
+        goto error;
+
+    if (!(ret->encryption = virStorageEncryptionCopy(src->encryption)))
+        goto error;
+
+    if (!(ret->perms = virStoragePermsCopy(src->perms)))
+        goto error;
+
+    if (!(ret->timestamps = virStorageTimestampsCopy(src->timestamps)))
+        goto error;
+
+    ret->auth.secretType = src->auth.secretType;
+    switch ((virStorageSecretType) src->auth.secretType) {
+        case VIR_STORAGE_SECRET_TYPE_NONE:
+        case VIR_STORAGE_SECRET_TYPE_LAST:
+            break;
+
+        case VIR_STORAGE_SECRET_TYPE_UUID:
+            memcpy(ret->auth.secret.uuid, src->auth.secret.uuid, VIR_UUID_BUFLEN);
+            break;
+
+        case VIR_STORAGE_SECRET_TYPE_USAGE:
+            if (VIR_STRDUP(ret->auth.secret.usage, src->auth.secret.usage) < 0)
+                goto error;
+            break;
+    }
+
+    if (backingChain && src->backingStore) {
+        if (!(ret->backingStore = virStorageSourceCopy(src->backingStore,
+                                                       true)))
+            goto error;
+    }
+
+    ret->nseclabels = src->nseclabels;
+    if (VIR_ALLOC_N(ret->seclabels, ret->nseclabels) < 0)
+        goto error;
+
+    for (i = 0; i < ret->nseclabels; i++) {
+        if (!(ret->seclabels[i] = virSecurityDeviceLabelDefCopy(src->seclabels[i])))
+            goto error;
+    }
+
+    return ret;
+
+ error:
+    virStorageSourceFree(ret);
+    return NULL;
+}
+
+
 void
 virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def)
 {
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 34b3625..cda9e76 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -324,6 +324,8 @@ int virStorageSourceGetActualType(virStorageSourcePtr def);
 void virStorageSourceFree(virStorageSourcePtr def);
 void virStorageSourceClearBackingStore(virStorageSourcePtr def);
 virStorageSourcePtr virStorageSourceNewFromBacking(virStorageSourcePtr parent);
+virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
+                                         bool backingChain);


 #endif /* __VIR_STORAGE_FILE_H__ */
-- 
1.9.3




More information about the libvir-list mailing list