Allow for adjustment of RBD configuration options via Storage
Pool XML Namespace adjustments.
Based off original patch/concept:
https://www.redhat.com/archives/libvir-list/2014-May/msg00940.html
Signed-off-by: John Ferlan <jferlan@redhat.com>
---
docs/formatstorage.html.in | 45 +++++
docs/schemas/storagepool.rng | 23 +++
src/storage/storage_backend_rbd.c | 159 +++++++++++++++++-
.../pool-rbd-configopts.xml | 17 ++
.../pool-rbd-configopts.xml | 20 +++
tests/storagepoolxml2xmltest.c | 1 +
6 files changed, 264 insertions(+), 1 deletion(-)
create mode 100644 tests/storagepoolxml2xmlin/pool-rbd-configopts.xml
create mode 100644 tests/storagepoolxml2xmlout/pool-rbd-configopts.xml
diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in
index 308b94f5e5..4e0fe0a981 100644
--- a/docs/formatstorage.html.in
+++ b/docs/formatstorage.html.in
@@ -437,6 +437,51 @@
<span class="since">Since 5.0.0.</span></dd>
+ <dt><code>rbd:config_opts</code></dt>
+ <dd>Provides an XML namespace mechanism to optionally utilize
+ specifically named options for the RBD configuration options
+ via the rados_conf_set API for the <code>rbd</code> type
+ storage pools. In order to designate that the Storage Pool
+ will be using the mechanism, the <code>pool</code> element
+ must be modified to provide the XML namespace attribute
+ syntax as follows:
+
+ <p>
+ xmlns:rbd='http://libvirt.org/schemas/storagepool/source/rbd/1.0'
+ </p>
+
+ <p>
+ The <code>rbd:config_opts</code> defines the configuration options
+ by specifying multiple <code>rbd:option</code> subelements with
+ the attribute <code>name</code> specifying the configuration option
+ to be added and <code>value</code> specifying the configuration
+ option value. The name and value for each option is only checked
+ to be not empty. The name and value provided are not checked since
+ it's possible options don't exist on all distributions. It is
+ expected that proper and valid options will be supplied for the
+ target host.
+ </p>
+
+ The following XML snippet shows the syntax required in order to
+ utilize
+ <pre>
+<pool type="rbd" xmlns:rbd='http://libvirt.org/schemas/storagepool/source/rbd/1.0'>
+ <name>myrbdpool</name>
+...
+ <source>
+ <name>rbdpool</name>
+ <host name='1.2.3.4'/>
+ <host name='my.ceph.monitor'/>
+ <host name='third.ceph.monitor' port='6789'/>
+ <rbd:config_opts>
+ <rbd:option name='client_mount_timeout' value='45'/>
+ <rbd:option name='rados_mon_op_timeout' value='20'/>
+ <rbd:option name='rados_osd_op_timeout' value='10'/>
+ </rbd:config_opts>
+ </source>
+...</pre>
+
+ <span class="since">Since 5.0.0.</span></dd>
</dl>
<h3><a id="StoragePoolTarget">Target elements</a></h3>
diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng
index 20c7ae5744..54fa584828 100644
--- a/docs/schemas/storagepool.rng
+++ b/docs/schemas/storagepool.rng
@@ -647,6 +647,9 @@
<optional>
<ref name='sourceinfoauth'/>
</optional>
+ <optional>
+ <ref name='rbd_config_opts'/>
+ </optional>
</interleave>
</element>
</define>
@@ -695,4 +698,24 @@
</element>
</define>
+ <!--
+ Optional storage pool extensions in their own namespace:
+ RBD
+ -->
+
+ <define name="rbd_config_opts">
+ <element name="config_opts" ns="http://libvirt.org/schemas/storagepool/source/rbd/1.0">
+ <zeroOrMore>
+ <element name="option">
+ <attribute name='name'>
+ <text/>
+ </attribute>
+ <attribute name='value'>
+ <text/>
+ </attribute>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
</grammar>
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 24dd1349ae..c419b12e2d 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -36,6 +36,7 @@
#include "rbd/librbd.h"
#include "secret_util.h"
#include "storage_util.h"
+#include <libxml/xpathInternals.h>
#define VIR_FROM_THIS VIR_FROM_STORAGE
@@ -50,6 +51,138 @@ struct _virStorageBackendRBDState {
typedef struct _virStorageBackendRBDState virStorageBackendRBDState;
typedef virStorageBackendRBDState *virStorageBackendRBDStatePtr;
+/* NetFS Storage Pool Namespace options to share w/ storage_backend_fs.c and
+ * the virStorageBackendFileSystemMountCmd method */
+typedef struct _virStoragePoolRBDMountOptionsDef virStoragePoolRBDMountOptionsDef;
+typedef virStoragePoolRBDMountOptionsDef *virStoragePoolRBDMountOptionsDefPtr;
+struct _virStoragePoolRBDMountOptionsDef {
+ size_t noptions;
+ char **names;
+ char **values;
+};
+
+#define STORAGE_POOL_RBD_NAMESPACE_HREF "http://libvirt.org/schemas/storagepool/source/rbd/1.0"
+
+static void
+virStoragePoolDefRBDNamespaceFree(void *nsdata)
+{
+ virStoragePoolRBDMountOptionsDefPtr cmdopts = nsdata;
+ size_t i;
+
+ if (!cmdopts)
+ return;
+
+ for (i = 0; i < cmdopts->noptions; i++) {
+ VIR_FREE(cmdopts->names[i]);
+ VIR_FREE(cmdopts->values[i]);
+ }
+
+ VIR_FREE(cmdopts);
+}
+
+
+static int
+virStoragePoolDefRBDNamespaceParse(xmlXPathContextPtr ctxt,
+ void **data)
+{
+ virStoragePoolRBDMountOptionsDefPtr cmdopts = NULL;
+ xmlNodePtr *nodes = NULL;
+ int nnodes;
+ size_t i;
+ int ret = -1;
+
+ if (xmlXPathRegisterNs(ctxt, BAD_CAST "rbd",
+ BAD_CAST STORAGE_POOL_RBD_NAMESPACE_HREF) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to register xml namespace '%s'"),
+ STORAGE_POOL_RBD_NAMESPACE_HREF);
+ return -1;
+ }
+
+ nnodes = virXPathNodeSet("./rbd:config_opts/rbd:option", ctxt, &nodes);
+ if (nnodes < 0)
+ return -1;
+
+ if (nnodes == 0)
+ return 0;
+
+ if (VIR_ALLOC(cmdopts) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC_N(cmdopts->names, nnodes) < 0 ||
+ VIR_ALLOC_N(cmdopts->values, nnodes) < 0)
+ goto cleanup;
+
+ for (i = 0; i < nnodes; i++) {
+ if (!(cmdopts->names[cmdopts->noptions] =
+ virXMLPropString(nodes[i], "name"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("no rbd option name specified"));
+ goto cleanup;
+ }
+ if (*cmdopts->names[cmdopts->noptions] == '\0') {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("empty rbd option name specified"));
+ goto cleanup;
+ }
+ if (!(cmdopts->values[cmdopts->noptions] =
+ virXMLPropString(nodes[i], "value"))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("no rbd option value specified for name '%s'"),
+ cmdopts->names[cmdopts->noptions]);
+ goto cleanup;
+ }
+ if (*cmdopts->values[cmdopts->noptions] == '\0') {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("empty rbd option value specified for name '%s'"),
+ cmdopts->names[cmdopts->noptions]);
+ goto cleanup;
+ }
+ cmdopts->noptions++;
+ }
+
+ VIR_STEAL_PTR(*data, cmdopts);
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(nodes);
+ virStoragePoolDefRBDNamespaceFree(cmdopts);
+ return ret;
+}
+
+
+static int
+virStoragePoolDefRBDNamespaceFormatXML(virBufferPtr buf,
+ void *nsdata)
+{
+ size_t i;
+ virStoragePoolRBDMountOptionsDefPtr def = nsdata;
+
+ if (!def)
+ return 0;
+
+ virBufferAddLit(buf, "<rbd:config_opts>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ for (i = 0; i < def->noptions; i++) {
+ virBufferEscapeString(buf, "<rbd:option name='%s' ", def->names[i]);
+ virBufferEscapeString(buf, "value='%s'/>\n", def->values[i]);
+ }
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</rbd:config_opts>\n");
+
+ return 0;
+}
+
+
+static const char *
+virStoragePoolDefRBDNamespaceHref(void)
+{
+ return "xmlns:rbd='" STORAGE_POOL_RBD_NAMESPACE_HREF "'";
+}
+
+
static int
virStorageBackendRBDRADOSConfSet(rados_t cluster,
const char *option,
@@ -183,6 +316,17 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr,
rbd_default_format) < 0)
goto cleanup;
+ if (source->namespaceData) {
+ virStoragePoolRBDMountOptionsDefPtr cmdopts = source->namespaceData;
+
+ for (i = 0; i < cmdopts->noptions; i++) {
+ if (virStorageBackendRBDRADOSConfSet(ptr->cluster,
+ cmdopts->names[i],
+ cmdopts->values[i]) < 0)
+ goto cleanup;
+ }
+ }
+
ptr->starttime = time(0);
if ((r = rados_connect(ptr->cluster)) < 0) {
virReportSystemError(-r, _("failed to connect to the RADOS monitor on: %s"),
@@ -1277,6 +1421,7 @@ virStorageBackendRBDVolWipe(virStoragePoolObjPtr pool,
return ret;
}
+
virStorageBackend virStorageBackendRBD = {
.type = VIR_STORAGE_POOL_RBD,
@@ -1291,8 +1436,20 @@ virStorageBackend virStorageBackendRBD = {
};
+static virStoragePoolXMLNamespace virStoragePoolRBDXMLNamespace = {
+ .parse = virStoragePoolDefRBDNamespaceParse,
+ .free = virStoragePoolDefRBDNamespaceFree,
+ .format = virStoragePoolDefRBDNamespaceFormatXML,
+ .href = virStoragePoolDefRBDNamespaceHref,
+};
+
+
int
virStorageBackendRBDRegister(void)
{
- return virStorageBackendRegister(&virStorageBackendRBD);
+ if (virStorageBackendRegister(&virStorageBackendRBD) < 0)
+ return -1;
+
+ return virStorageBackendNamespaceInit(VIR_STORAGE_POOL_RBD,
+ &virStoragePoolRBDXMLNamespace);
}
diff --git a/tests/storagepoolxml2xmlin/pool-rbd-configopts.xml b/tests/storagepoolxml2xmlin/pool-rbd-configopts.xml
new file mode 100644
index 0000000000..a23f559afb
--- /dev/null
+++ b/tests/storagepoolxml2xmlin/pool-rbd-configopts.xml
@@ -0,0 +1,17 @@
+<pool type='rbd' xmlns:rbd='http://libvirt.org/schemas/storagepool/source/rbd/1.0'>
+ <name>ceph</name>
+ <uuid>47c1faee-0207-e741-f5ae-d9b019b98fe2</uuid>
+ <source>
+ <name>rbd</name>
+ <host name='localhost' port='6789'/>
+ <host name='localhost' port='6790'/>
+ <auth username='admin' type='ceph'>
+ <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
+ </auth>
+ <rbd:config_opts>
+ <rbd:option name='client_mount_timeout' value='45'/>
+ <rbd:option name='rados_mon_op_timeout' value='10'/>
+ <rbd:option name='rados_osd_op_timeout' value='20'/>
+ </rbd:config_opts>
+ </source>
+</pool>
diff --git a/tests/storagepoolxml2xmlout/pool-rbd-configopts.xml b/tests/storagepoolxml2xmlout/pool-rbd-configopts.xml
new file mode 100644
index 0000000000..121a69c0d7
--- /dev/null
+++ b/tests/storagepoolxml2xmlout/pool-rbd-configopts.xml
@@ -0,0 +1,20 @@
+<pool type='rbd' xmlns:rbd='http://libvirt.org/schemas/storagepool/source/rbd/1.0'>
+ <name>ceph</name>
+ <uuid>47c1faee-0207-e741-f5ae-d9b019b98fe2</uuid>
+ <capacity unit='bytes'>0</capacity>
+ <allocation unit='bytes'>0</allocation>
+ <available unit='bytes'>0</available>
+ <source>
+ <host name='localhost' port='6789'/>
+ <host name='localhost' port='6790'/>
+ <name>rbd</name>
+ <auth type='ceph' username='admin'>
+ <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
+ </auth>
+ <rbd:config_opts>
+ <rbd:option name='client_mount_timeout' value='45'/>
+ <rbd:option name='rados_mon_op_timeout' value='10'/>
+ <rbd:option name='rados_osd_op_timeout' value='20'/>
+ </rbd:config_opts>
+ </source>
+</pool>
diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c
index c08313d236..25f134fc23 100644
--- a/tests/storagepoolxml2xmltest.c
+++ b/tests/storagepoolxml2xmltest.c
@@ -105,6 +105,7 @@ mymain(void)
DO_TEST("pool-zfs");
DO_TEST("pool-zfs-sourcedev");
DO_TEST("pool-rbd");
+ DO_TEST("pool-rbd-configopts");
DO_TEST("pool-vstorage");
DO_TEST("pool-iscsi-direct-auth");
DO_TEST("pool-iscsi-direct");
--
2.20.1
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 1/8/19 6:52 PM, John Ferlan wrote: > Allow for adjustment of RBD configuration options via Storage > Pool XML Namespace adjustments. > > Based off original patch/concept: > > https://www.redhat.com/archives/libvir-list/2014-May/msg00940.html > > Signed-off-by: John Ferlan <jferlan@redhat.com> > --- > docs/formatstorage.html.in | 45 +++++ > docs/schemas/storagepool.rng | 23 +++ > src/storage/storage_backend_rbd.c | 159 +++++++++++++++++- > .../pool-rbd-configopts.xml | 17 ++ > .../pool-rbd-configopts.xml | 20 +++ > tests/storagepoolxml2xmltest.c | 1 + > 6 files changed, 264 insertions(+), 1 deletion(-) > create mode 100644 tests/storagepoolxml2xmlin/pool-rbd-configopts.xml > create mode 100644 tests/storagepoolxml2xmlout/pool-rbd-configopts.xml > > diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in > index 308b94f5e5..4e0fe0a981 100644 > --- a/docs/formatstorage.html.in > +++ b/docs/formatstorage.html.in > @@ -437,6 +437,51 @@ > > <span class="since">Since 5.0.0.</span></dd> > > + <dt><code>rbd:config_opts</code></dt> > + <dd>Provides an XML namespace mechanism to optionally utilize > + specifically named options for the RBD configuration options > + via the rados_conf_set API for the <code>rbd</code> type > + storage pools. In order to designate that the Storage Pool > + will be using the mechanism, the <code>pool</code> element > + must be modified to provide the XML namespace attribute > + syntax as follows: > + > + <p> > + xmlns:rbd='http://libvirt.org/schemas/storagepool/source/rbd/1.0' > + </p> > + > + <p> > + The <code>rbd:config_opts</code> defines the configuration options > + by specifying multiple <code>rbd:option</code> subelements with > + the attribute <code>name</code> specifying the configuration option > + to be added and <code>value</code> specifying the configuration > + option value. The name and value for each option is only checked > + to be not empty. The name and value provided are not checked since > + it's possible options don't exist on all distributions. It is > + expected that proper and valid options will be supplied for the > + target host. > + </p> > + > + The following XML snippet shows the syntax required in order to > + utilize > + <pre> > +<pool type="rbd" xmlns:rbd='http://libvirt.org/schemas/storagepool/source/rbd/1.0'> > + <name>myrbdpool</name> > +... > + <source> > + <name>rbdpool</name> > + <host name='1.2.3.4'/> > + <host name='my.ceph.monitor'/> > + <host name='third.ceph.monitor' port='6789'/> > + <rbd:config_opts> > + <rbd:option name='client_mount_timeout' value='45'/> > + <rbd:option name='rados_mon_op_timeout' value='20'/> > + <rbd:option name='rados_osd_op_timeout' value='10'/> > + </rbd:config_opts> > + </source> > +...</pre> > + > + <span class="since">Since 5.0.0.</span></dd> > </dl> > > <h3><a id="StoragePoolTarget">Target elements</a></h3> > diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng > index 20c7ae5744..54fa584828 100644 > --- a/docs/schemas/storagepool.rng > +++ b/docs/schemas/storagepool.rng > @@ -647,6 +647,9 @@ > <optional> > <ref name='sourceinfoauth'/> > </optional> > + <optional> > + <ref name='rbd_config_opts'/> > + </optional> > </interleave> > </element> > </define> > @@ -695,4 +698,24 @@ > </element> > </define> > > + <!-- > + Optional storage pool extensions in their own namespace: > + RBD > + --> > + > + <define name="rbd_config_opts"> > + <element name="config_opts" ns="http://libvirt.org/schemas/storagepool/source/rbd/1.0"> > + <zeroOrMore> > + <element name="option"> > + <attribute name='name'> > + <text/> > + </attribute> > + <attribute name='value'> > + <text/> > + </attribute> > + </element> > + </zeroOrMore> > + </element> > + </define> > + > </grammar> > diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c > index 24dd1349ae..c419b12e2d 100644 > --- a/src/storage/storage_backend_rbd.c > +++ b/src/storage/storage_backend_rbd.c > @@ -36,6 +36,7 @@ > #include "rbd/librbd.h" > #include "secret_util.h" > #include "storage_util.h" > +#include <libxml/xpathInternals.h> > > #define VIR_FROM_THIS VIR_FROM_STORAGE > > @@ -50,6 +51,138 @@ struct _virStorageBackendRBDState { > typedef struct _virStorageBackendRBDState virStorageBackendRBDState; > typedef virStorageBackendRBDState *virStorageBackendRBDStatePtr; > > +/* NetFS Storage Pool Namespace options to share w/ storage_backend_fs.c and > + * the virStorageBackendFileSystemMountCmd method */ > +typedef struct _virStoragePoolRBDMountOptionsDef virStoragePoolRBDMountOptionsDef; > +typedef virStoragePoolRBDMountOptionsDef *virStoragePoolRBDMountOptionsDefPtr; > +struct _virStoragePoolRBDMountOptionsDef { > + size_t noptions; > + char **names; > + char **values; > +}; > + > +#define STORAGE_POOL_RBD_NAMESPACE_HREF "http://libvirt.org/schemas/storagepool/source/rbd/1.0" > + > +static void > +virStoragePoolDefRBDNamespaceFree(void *nsdata) > +{ > + virStoragePoolRBDMountOptionsDefPtr cmdopts = nsdata; > + size_t i; > + > + if (!cmdopts) > + return; > + > + for (i = 0; i < cmdopts->noptions; i++) { > + VIR_FREE(cmdopts->names[i]); > + VIR_FREE(cmdopts->values[i]); > + } > + Again, VIR_FREE(cmdopts->names) and VIR_FREE(cmdopts->values); > + VIR_FREE(cmdopts); > +} Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2024 Red Hat, Inc.