[PATCH] feature: Ceph rbd create with data pool attributes set support.

Guozhonghua posted 1 patch 1 year, 2 months ago
Failed in applying to current master (apply log)
src/conf/storage_conf.c           | 205 ++++++++++++++++++++++++++++++
src/conf/storage_conf.h           |  33 +++++
src/storage/storage_backend_rbd.c | 123 +++++++++++++++++-
3 files changed, 358 insertions(+), 3 deletions(-)
[PATCH] feature: Ceph rbd create with data pool attributes set support.
Posted by Guozhonghua 1 year, 2 months ago

In some cases, we may use another pool to store the data and one pool to
store the meta data of the rbd vol, so it is to use another interface to
create the rbd vol, rbd_create4, required.

This patch add the feature with xml configure is like as below:
<source>
    <host name='xxx.xxx.xxx.xxx' port='6789'/>
    <host name='xxx.xxx.xxx.xxx' port='6789'/>
    <name>rbd_pool</name>
    <auth type='ceph' username='user_name'>
       <secret uuid='972327af-360b-4a68-9b0f-99dec10a05dc'/>
    </auth>
    <rbdimageoption format='x' feature='x' order='x' stripeunit='x' stripecount='x' journalorder='x' journalpool='x' featureset='x' featureclear='x' datapool='x' flatten='x' cloneformat=' mirrorimagemode=''/>
</source>

Here we add one item rbdimageoption to set the attributions used when
create rbd vol.

If the option is not set, then the origin interface rbd_create is
called as before.

Signed-off-by: Guozhonghua <guozh88@chinatelecom.cn>
---
 src/conf/storage_conf.c           | 205 ++++++++++++++++++++++++++++++
 src/conf/storage_conf.h           |  33 +++++
 src/storage/storage_backend_rbd.c | 123 +++++++++++++++++-
 3 files changed, 358 insertions(+), 3 deletions(-)

diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index f5a9636ce2..ac6c700ac1 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -461,6 +461,14 @@ virStoragePoolSourceDeviceClear(virStoragePoolSourceDevice *dev)
 }
 
 
+void
+virRbdImageOptionClear(virRbdImageOptionsPtr rbd_image_option)
+{
+    VIR_FREE(rbd_image_option->journal_pool);
+    VIR_FREE(rbd_image_option->data_pool);
+}
+
+
 void
 virStoragePoolSourceClear(virStoragePoolSource *source)
 {
@@ -484,6 +492,7 @@ virStoragePoolSourceClear(virStoragePoolSource *source)
     VIR_FREE(source->vendor);
     VIR_FREE(source->product);
     VIR_FREE(source->protocolVer);
+    virRbdImageOptionClear(&source->rbdImageOptions);
 }
 
 
@@ -514,6 +523,131 @@ virStoragePoolDefFree(virStoragePoolDef *def)
 }
 
 
+int
+virRbdImageOptionParseXML(virRbdImageOptionsPtr rbd_image_option,
+                             xmlNodePtr node,
+                             xmlXPathContextPtr ctxt)
+{
+    VIR_XPATH_NODE_AUTORESTORE(ctxt)
+    char *val = NULL;
+
+    ctxt->node = node;
+
+    rbd_image_option->format = -1;
+    if ((val = virXMLPropString(node, "format"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->format) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->feature = -1;
+    if ((val = virXMLPropString(node, "feature"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->feature) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->order = -1;
+    if ((val = virXMLPropString(node, "order"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->order) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->stripe_unit = -1;
+    if ((val = virXMLPropString(node, "stripeunit"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->stripe_unit) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->stripe_count = -1;
+    if ((val = virXMLPropString(node, "stripecount"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->stripe_count) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->journal_order = -1;
+    if ((val = virXMLPropString(node, "journalorder"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->journal_order) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->journal_splay_width = -1;
+    if ((val = virXMLPropString(node, "journalsplaywidth"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->journal_splay_width) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->journal_pool = virXMLPropString(node, "journalpool");
+
+    rbd_image_option->feature_set = -1;
+    if ((val = virXMLPropString(node, "featureset"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->feature_set) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->feature_clear = -1;
+    if ((val = virXMLPropString(node, "featureclear"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->feature_clear) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->data_pool = virXMLPropString(node, "datapool");
+
+    rbd_image_option->flatten = -1;
+    if ((val = virXMLPropString(node, "flatten"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->flatten) < 0)
+            goto cleanup;
+	VIR_FREE(val);
+    }
+
+    rbd_image_option->clone_format = -1;
+    if ((val = virXMLPropString(node, "cloneformat"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->clone_format) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    rbd_image_option->mirror_image_mode = -1;
+    if ((val = virXMLPropString(node, "mirrorimagemode"))) {
+        if (virStrToLong_l(val, NULL, 10, &rbd_image_option->mirror_image_mode) < 0)
+            goto cleanup;
+        VIR_FREE(val);
+    }
+
+    return 0;
+cleanup:
+    VIR_FREE(val);
+    return -1;
+}
+
+
+ void
+ virRbdImageOptionDefaultSet(virRbdImageOptionsPtr rbd_image_option)
+ {
+     rbd_image_option->format = -1;
+     rbd_image_option->feature = -1;
+     rbd_image_option->order = -1;
+     rbd_image_option->stripe_unit = -1;
+     rbd_image_option->stripe_count = -1;
+     rbd_image_option->journal_order = -1;
+     rbd_image_option->journal_splay_width = -1;
+     rbd_image_option->journal_pool = NULL;
+     rbd_image_option->feature_set = -1;
+     rbd_image_option->feature_clear = -1;
+     rbd_image_option->data_pool = NULL;
+     rbd_image_option->flatten = -1;
+     rbd_image_option->clone_format = -1;
+     rbd_image_option->mirror_image_mode = -1;
+ }
+
+
 static int
 virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
                              virStoragePoolSource *source,
@@ -522,6 +656,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
 {
     xmlNodePtr authnode;
     xmlNodePtr adapternode;
+    xmlNodePtr rbdimageoption;
     int nsource;
     size_t i;
     virStoragePoolOptions *options;
@@ -633,6 +768,13 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
         source->auth = g_steal_pointer(&authdef);
     }
 
+    if ((rbdimageoption = virXPathNode("./rbdimageoption", ctxt))) {
+        if (virRbdImageOptionParseXML(&source->rbdImageOptions, rbdimageoption, ctxt) < 0)
+            goto cleanup;
+    } else {
+        virRbdImageOptionDefaultSet(&source->rbdImageOptions);
+    }
+
     /* Option protocol version string (NFSvN) */
     if ((source->protocolVer = virXPathString("string(./protocol/@ver)", ctxt))) {
         if ((source->format != VIR_STORAGE_POOL_NETFS_NFS) &&
@@ -988,6 +1130,67 @@ virStoragePoolDefParse(const char *xmlStr,
 }
 
 
+static void
+virRbdImageOptionFormat(virBufferPtr buf,
+                       virRbdImageOptionsPtr rbdImageOptions)
+{
+   // not set the rbd image options.
+   if (rbdImageOptions->format < 0 && rbdImageOptions->feature < 0 && rbdImageOptions->order < 0
+       && rbdImageOptions->stripe_unit < 0 && rbdImageOptions->stripe_count < 0 && rbdImageOptions->journal_order < 0
+       && rbdImageOptions->journal_splay_width < 0 && (rbdImageOptions->journal_pool != NULL) && rbdImageOptions->feature_set < 0
+       && rbdImageOptions->feature_clear < 0 && (rbdImageOptions->data_pool != NULL) && rbdImageOptions->flatten < 0
+       && rbdImageOptions->clone_format < 0 && rbdImageOptions->mirror_image_mode < 0)
+   return;
+
+   virBufferAsprintf(buf, "<rbdimageoption");
+
+   if (rbdImageOptions->format >= 0)
+       virBufferAsprintf(buf, " format='%ld'", rbdImageOptions->format);
+
+   if (rbdImageOptions->feature >= 0)
+       virBufferAsprintf(buf, " feature='%ld'", rbdImageOptions->feature);
+
+   if (rbdImageOptions->order >= 0)
+       virBufferAsprintf(buf, " order='%ld'", rbdImageOptions->order);
+
+   if (rbdImageOptions->stripe_unit >= 0)
+       virBufferAsprintf(buf, " stripeunit='%ld'", rbdImageOptions->stripe_unit);
+
+   if (rbdImageOptions->stripe_count >= 0)
+       virBufferAsprintf(buf, " stripecount='%ld'", rbdImageOptions->stripe_count);
+
+   if (rbdImageOptions->journal_order >= 0)
+       virBufferAsprintf(buf, " journalorder='%ld'", rbdImageOptions->journal_order);
+
+   if (rbdImageOptions->journal_splay_width >= 0)
+       virBufferAsprintf(buf, " journalsplaywidth='%ld'", rbdImageOptions->journal_splay_width);
+
+   if (rbdImageOptions->journal_pool)
+       virBufferAsprintf(buf, " journalpool='%s'", rbdImageOptions->journal_pool);
+
+   if (rbdImageOptions->feature_set >= 0)
+       virBufferAsprintf(buf, " featureset='%ld'", rbdImageOptions->feature_set);
+
+   if (rbdImageOptions->feature_clear >= 0)
+       virBufferAsprintf(buf, " featureclear='%ld'", rbdImageOptions->feature_clear);
+
+   if (rbdImageOptions->data_pool)
+       virBufferAsprintf(buf, " datapool='%s'", rbdImageOptions->data_pool);
+
+   if (rbdImageOptions->flatten >= 0)
+       virBufferAsprintf(buf, " flatten='%ld'", rbdImageOptions->flatten);
+
+   if (rbdImageOptions->clone_format >= 0)
+       virBufferAsprintf(buf, " cloneformat='%ld'", rbdImageOptions->clone_format);
+
+   if (rbdImageOptions->mirror_image_mode >= 0)
+       virBufferAsprintf(buf, " mirrorimagemode='%ld'", rbdImageOptions->mirror_image_mode);
+
+   virBufferAsprintf(buf, "/>\n");
+}
+
+
+
 static int
 virStoragePoolSourceFormat(virBuffer *buf,
                            virStoragePoolOptions *options,
@@ -1066,6 +1269,8 @@ virStoragePoolSourceFormat(virBuffer *buf,
     virBufferEscapeString(buf, "<vendor name='%s'/>\n", src->vendor);
     virBufferEscapeString(buf, "<product name='%s'/>\n", src->product);
 
+    virRbdImageOptionFormat(buf, &src->rbdImageOptions);
+
     virBufferAdjustIndent(buf, -2);
     virBufferAddLit(buf, "</source>\n");
     return 0;
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index fc67957cfe..377ea1cfe2 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -175,6 +175,25 @@ struct _virStoragePoolFeatures {
     virTristateBool cow;
 };
 
+typedef struct _virRbdImageOptions virRbdImageOptions;
+typedef virRbdImageOptions *virRbdImageOptionsPtr;
+struct _virRbdImageOptions {
+    int64_t format;
+    int64_t feature;
+    int64_t order;
+    int64_t stripe_unit;
+    int64_t stripe_count;
+    int64_t journal_order;
+    int64_t journal_splay_width;
+    char *journal_pool;
+    int64_t feature_set;
+    int64_t feature_clear;
+    char *data_pool;
+    int64_t flatten;
+    int64_t clone_format;
+    int64_t mirror_image_mode;
+};
+
 
 typedef struct _virStoragePoolSource virStoragePoolSource;
 struct _virStoragePoolSource {
@@ -214,6 +233,9 @@ struct _virStoragePoolSource {
 
     /* Protocol version value for netfs */
     char *protocolVer;
+
+    /* RBD Image Options definition. */
+    virRbdImageOptions rbdImageOptions;
 };
 
 typedef struct _virStoragePoolTarget virStoragePoolTarget;
@@ -314,6 +336,9 @@ virStoragePoolSaveConfig(const char *configFile,
 void
 virStorageVolDefFree(virStorageVolDef *def);
 
+void
+virRbdImageOptionClear(virRbdImageOptionsPtr rbd_image_option);
+
 void
 virStoragePoolSourceClear(virStoragePoolSource *source);
 
@@ -326,6 +351,14 @@ virStoragePoolSourceFree(virStoragePoolSource *source);
 void
 virStoragePoolDefFree(virStoragePoolDef *def);
 
+int
+virRbdImageOptionParseXML(virRbdImageOptionsPtr rbd_image_option,
+                             xmlNodePtr node,
+                             xmlXPathContextPtr ctxt);
+
+void
+virRbdImageOptionDefaultSet(virRbdImageOptionsPtr rbd_image_option);
+
 virStoragePoolSource *
 virStoragePoolDefParseSourceString(const char *srcSpec,
                                    int pool_type);
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 05b2c43f79..29c651cbcd 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -878,10 +878,127 @@ virStorageBackendRBDCreateVol(virStoragePoolObj *pool,
 }
 
 static int virStorageBackendRBDCreateImage(rados_ioctx_t io,
-                                           char *name, long capacity)
+                                           char *name, long capacity, virStoragePoolDefPtr def)
 {
     int order = 0;
-    return rbd_create(io, name, capacity, &order);
+    int ret = -1;
+    rbd_image_options_t image_options;
+
+    if (def->source.rbdImageOptions.format < 0 && def->source.rbdImageOptions.feature < 0
+        && def->source.rbdImageOptions.order < 0 && def->source.rbdImageOptions.stripe_unit < 0
+        && def->source.rbdImageOptions.stripe_count < 0 && def->source.rbdImageOptions.journal_order < 0
+        && def->source.rbdImageOptions.journal_splay_width < 0 && (def->source.rbdImageOptions.journal_pool != NULL)
+        && def->source.rbdImageOptions.feature_set < 0	&& def->source.rbdImageOptions.feature_clear < 0
+        && (def->source.rbdImageOptions.data_pool != NULL) && def->source.rbdImageOptions.flatten < 0
+        && def->source.rbdImageOptions.clone_format < 0 && def->source.rbdImageOptions.mirror_image_mode < 0) {
+        VIR_DEBUG("Creating RBD image %s, without data pool, with size %lu", name, capacity);
+        return rbd_create(io, name, capacity, &order);
+    }
+
+    rbd_image_options_create(&image_options);
+
+    if (def->source.rbdImageOptions.format >= 0) {
+        VIR_DEBUG("Set rbd image option format:%d, %lu", RBD_IMAGE_OPTION_FORMAT, def->source.rbdImageOptions.format);
+        rbd_image_options_set_uint64(image_options,
+              RBD_IMAGE_OPTION_FORMAT,
+              (uint64_t)def->source.rbdImageOptions.format);
+    }
+
+    if (def->source.rbdImageOptions.feature >= 0) {
+        VIR_DEBUG("Set rbd image option features:%d, %lu", RBD_IMAGE_OPTION_FEATURES, def->source.rbdImageOptions.feature);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_FEATURES,
+            (uint64_t)def->source.rbdImageOptions.feature);
+    }
+
+    if (def->source.rbdImageOptions.order >= 0) {
+        VIR_DEBUG("Set rbd image option order:%d, %lu", RBD_IMAGE_OPTION_ORDER, def->source.rbdImageOptions.order);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_ORDER,
+            (uint64_t)def->source.rbdImageOptions.order);
+    }
+
+    if (def->source.rbdImageOptions.stripe_unit >= 0) {
+        VIR_DEBUG("Set rbd image option stripe_unit:%d, %lu", RBD_IMAGE_OPTION_STRIPE_UNIT, def->source.rbdImageOptions.stripe_unit);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_STRIPE_UNIT,
+            (uint64_t)def->source.rbdImageOptions.stripe_unit);
+    }
+
+    if (def->source.rbdImageOptions.stripe_count >= 0) {
+        VIR_DEBUG("Set rbd image option stipe_count:%d, %lu", RBD_IMAGE_OPTION_STRIPE_COUNT, def->source.rbdImageOptions.stripe_count);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_STRIPE_COUNT,
+            (uint64_t)def->source.rbdImageOptions.stripe_count);
+    }
+
+    if (def->source.rbdImageOptions.journal_order >= 0) {
+        VIR_DEBUG("Set rbd image option journal_order:%d, %lu", RBD_IMAGE_OPTION_JOURNAL_ORDER, def->source.rbdImageOptions.journal_order);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_JOURNAL_ORDER,
+            (uint64_t)def->source.rbdImageOptions.journal_order);
+    }
+
+    if (def->source.rbdImageOptions.journal_splay_width >= 0) {
+        VIR_DEBUG("Set rbd image option journal_splay_width:%d, %lu", RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH, def->source.rbdImageOptions.journal_splay_width);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH,
+            (uint64_t)def->source.rbdImageOptions.journal_splay_width);
+    }
+
+    if (def->source.rbdImageOptions.journal_pool != NULL) {
+        VIR_DEBUG("Set rbd image option journal_pool:%d, %s", RBD_IMAGE_OPTION_JOURNAL_POOL, def->source.rbdImageOptions.journal_pool);
+        rbd_image_options_set_string(image_options,
+            RBD_IMAGE_OPTION_JOURNAL_POOL,
+            def->source.rbdImageOptions.journal_pool);
+    }
+
+    if (def->source.rbdImageOptions.feature_set >= 0) {
+        VIR_DEBUG("Set rbd image option feature_set:%d, %lu", RBD_IMAGE_OPTION_FEATURES_SET, def->source.rbdImageOptions.feature_set);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_FEATURES_SET,
+            (uint64_t)def->source.rbdImageOptions.feature_set);
+    }
+
+    if (def->source.rbdImageOptions.feature_clear >= 0) {
+        VIR_DEBUG("Set rbd image option feature_clear:%d, %lu", RBD_IMAGE_OPTION_FEATURES_CLEAR, def->source.rbdImageOptions.feature_clear);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_FEATURES_CLEAR,
+            (uint64_t)def->source.rbdImageOptions.feature_clear);
+    }
+
+    if (def->source.rbdImageOptions.data_pool != NULL) {
+        VIR_DEBUG("Set rbd image option data_pool:%d, %s", RBD_IMAGE_OPTION_DATA_POOL, def->source.rbdImageOptions.data_pool);
+        rbd_image_options_set_string(image_options,
+            RBD_IMAGE_OPTION_DATA_POOL,
+            def->source.rbdImageOptions.data_pool);
+    }
+
+    if (def->source.rbdImageOptions.flatten >= 0) {
+        VIR_DEBUG("Set rbd image option flatten:%d, %lu", RBD_IMAGE_OPTION_FLATTEN, def->source.rbdImageOptions.flatten);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_FLATTEN,
+            (uint64_t)def->source.rbdImageOptions.flatten);
+    }
+
+    if (def->source.rbdImageOptions.clone_format >= 0) {
+        VIR_DEBUG("Set rbd image option clone_format:%d, %lu", RBD_IMAGE_OPTION_CLONE_FORMAT, def->source.rbdImageOptions.clone_format);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_CLONE_FORMAT,
+            (uint64_t)def->source.rbdImageOptions.clone_format);
+    }
+
+    if (def->source.rbdImageOptions.mirror_image_mode >= 0) {
+        VIR_DEBUG("Set rbd image option mirror_image_mode:%d, %lu", RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE, def->source.rbdImageOptions.mirror_image_mode);
+        rbd_image_options_set_uint64(image_options,
+            RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE,
+            (uint64_t)def->source.rbdImageOptions.mirror_image_mode);
+    }
+
+    ret = rbd_create4(io, name, capacity, image_options);
+    VIR_DEBUG("Creating RBD image %s, with size:%lu, ret:%d", name, capacity, ret);
+    rbd_image_options_destroy(image_options);
+    return ret;
 }
 
 static int
@@ -920,7 +1037,7 @@ virStorageBackendRBDBuildVol(virStoragePoolObj *pool,
         goto cleanup;
 
     if (virStorageBackendRBDCreateImage(ptr->ioctx, vol->name,
-                                       vol->target.capacity) < 0) {
+                                       vol->target.capacity, def) < 0) {
         virReportSystemError(errno, _("failed to create volume '%s/%s'"),
                              def->source.name, vol->name);
         goto cleanup;
-- 
2.29.1.windows.1