From: Wido den Hollander <wido@xxxxxxxx> This allows the end-user to pass down options to the storage pool backend. For example NFS could get mount options or Ceph librados options passed down. --- docs/schemas/storagepool.rng | 16 +++++++++ docs/storage.html.in | 48 +++++++++++++++++++++++++ src/conf/storage_conf.c | 82 +++++++++++++++++++++++++++++++++++++++++- src/conf/storage_conf.h | 15 ++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng index 8d7a94d..7b38dce 100644 --- a/docs/schemas/storagepool.rng +++ b/docs/schemas/storagepool.rng @@ -294,6 +294,22 @@ </element> </define> + <define name='sourceinfooptions'> + <oneOrMore> + <element name='option'> + <attribute name='name'> + <text/> + </attribute> + <optional> + <attribute name='value'> + <text/> + </attribute> + </optional> + <empty/> + </element> + </oneOrMore> + </define> + <define name='initiatorinfo'> <element name='initiator'> <element name='iqn'> diff --git a/docs/storage.html.in b/docs/storage.html.in index eb38b16..3acbd53 100644 --- a/docs/storage.html.in +++ b/docs/storage.html.in @@ -270,6 +270,30 @@ </target> </pool></pre> + <h3>Mount options</h3> + <p> + It is also possible to influence the mount options used for NFS by + adding extra options in the pool's XML definition. + </p> + <pre> + <pool type="netfs"> + <name>virtimages</name> + <source> + <host name="nfs.example.com"/> + <dir path="/var/lib/virt/images"/> + <format type='nfs'/> + <option name='noatime'/> + <option name='rsize' value='8k'/> + </source> + <target> + <path>/var/lib/virt/images</path> + </target> + </pool></pre> + <p> + Storage pool options are support since <strong>1.2.6</strong> + </p> + + <h3>Valid pool format types</h3> <p> The network filesystem pool supports the following formats: @@ -561,6 +585,30 @@ </source> </pool></pre> + <h3>RADOS cluster options</h3> + <p> + It is also possible to influence the RADOS cluster options used by librados + by adding extra options in the pool's XML definition. + </p> + <pre> + <pool type="rbd"> + <name>myrbdpool</name> + <source> + <name>rbdpool</name> + <host name='1.2.3.4' port='6789'/> + <host name='my.ceph.monitor' port='6789'/> + <host name='third.ceph.monitor' port='6789'/> + <auth username='admin' type='ceph'> + <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/> + </auth> + <option name='rados_mon_op_timeout' value='10'/> + <option name='rados_osd_op_timeout' value='10'/> + </source> + </pool></pre> + <p> + Storage pool options are support since <strong>1.2.6</strong> + </p> + <h3>Example volume output</h3> <pre> <volume> diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8b6fd79..777e12d 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -32,6 +32,7 @@ #include <stdio.h> #include <fcntl.h> #include <string.h> +#include <regex.h> #include "virerror.h" #include "datatypes.h" @@ -370,6 +371,11 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source) for (i = 0; i < source->ndevice; i++) virStoragePoolSourceDeviceClear(&source->devices[i]); VIR_FREE(source->devices); + for (i = 0; i < source->noptions; i++) { + VIR_FREE(source->options[i].name); + VIR_FREE(source->options[i].value); + } + VIR_FREE(source->options); VIR_FREE(source->dir); VIR_FREE(source->name); virStoragePoolSourceAdapterClear(source->adapter); @@ -551,6 +557,32 @@ virStoragePoolDefParseAuth(xmlXPathContextPtr ctxt, return ret; } +static int virStoragePoolDefVerifyOption(char *msg) +{ + regex_t regex; + int reti; + char msgbuf[100]; + int ret = -1; + + reti = regcomp(®ex, "^[A-Za-z0-9][A-Za-z0-9_-]*[A-Za-z0-9]$", 0); + if (reti) + goto cleanup; + + reti = regexec(®ex, msg, 0, NULL, 0); + if (!reti) { + ret = 0; + } else if (reti == REG_NOMATCH) { + ret = -1; + } else { + regerror(reti, ®ex, msgbuf, sizeof(msgbuf)); + ret = -2; + } + +cleanup: + regfree(®ex); + return ret; +} + static int virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolSourcePtr source, @@ -559,7 +591,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, { int ret = -1; xmlNodePtr relnode, *nodeset = NULL; - int nsource; + int nsource, noptions; size_t i; virStoragePoolOptionsPtr options; char *name = NULL; @@ -649,6 +681,44 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, } } + noptions = virXPathNodeSet("./option", ctxt, &nodeset); + if (noptions > 0) { + if (VIR_ALLOC_N(source->options, noptions) < 0) { + VIR_FREE(nodeset); + goto cleanup; + } + + source->noptions = noptions; + + for (i = 0; i < noptions; i++) { + char *option = virXMLPropString(nodeset[i], "name"); + if (option == NULL) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing storage pool option attribute 'name'")); + goto cleanup; + } else if (virStoragePoolDefVerifyOption(option) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s: %s", + _("invalid storage pool option"), option); + goto cleanup; + } + source->options[i].name = option; + + /* + * We allow values to be NULL. + * E.g. for a NFS mount: <option name='soft'/> or <option name='intr'/> + */ + char *value = virXMLPropString(nodeset[i], "value"); + if (value != NULL) { + if (virStoragePoolDefVerifyOption(value) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s: %s", + _("invalid storage pool option value"), value); + goto cleanup; + } + source->options[i].value = value; + } + } + } + source->dir = virXPathString("string(./dir/@path)", ctxt); /* In gluster, a missing dir defaults to "/" */ if (!source->dir && pool_type == VIR_STORAGE_POOL_GLUSTER && @@ -1166,6 +1236,16 @@ virStoragePoolSourceFormat(virBufferPtr buf, virBufferEscapeString(buf, "<vendor name='%s'/>\n", src->vendor); virBufferEscapeString(buf, "<product name='%s'/>\n", src->product); + if (src->noptions) { + for (i = 0; i < src->noptions; i++) { + virBufferAsprintf(buf, " <option name='%s'", src->options[i].name); + if (src->options[i].value != NULL) { + virBufferAsprintf(buf, " value='%s'", src->options[i].value); + } + virBufferAddLit(buf, "/>\n"); + } + } + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</source>\n"); return 0; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 04d99eb..715f129 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -147,6 +147,17 @@ struct _virStoragePoolSourceHost { int port; }; +/* + * Key-value pairs for passing down options to storage pools. + * Eg NFS mount options or Ceph RBD options + */ +typedef struct _virStoragePoolSourceOptions virStoragePoolSourceOptions; +typedef virStoragePoolSourceOptions *virStoragePoolSourceOptionsPtr; +struct _virStoragePoolSourceOptions { + char *name; + char *value; +}; + /* * For MSDOS partitions, the free area is important when @@ -259,6 +270,10 @@ struct _virStoragePoolSource { * or lvm version, etc. */ int format; + + /* Key-value pairs with options for the pool */ + int noptions; + virStoragePoolSourceOptionsPtr options; }; typedef struct _virStoragePoolTarget virStoragePoolTarget; -- 1.7.9.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list