[PATCH v8 2/3] conf: Support to parse rbd namespace from source name
Peter Krempa
pkrempa at redhat.com
Mon Jun 7 14:58:13 UTC 2021
On Mon, Jun 07, 2021 at 16:34:39 +0200, Peter Krempa wrote:
> On Wed, May 26, 2021 at 21:35:11 +0800, Han Han wrote:
> > Signed-off-by: Han Han <hhan at redhat.com>
> > ---
> > docs/formatdomain.rst | 16 ++++++++++++
> > src/conf/domain_conf.c | 47 +++++++++++++++++++++++++++++++---
> > src/conf/storage_source_conf.c | 2 ++
> > src/conf/storage_source_conf.h | 1 +
> > 4 files changed, 62 insertions(+), 4 deletions(-)
>
> [...]
>
> > @@ -2570,6 +2580,12 @@ paravirtualized driver is specified via the ``disk`` element.
> > the host by the ``nbd_tls`` and ``nbd_tls_x509_cert_dir`` in
> > /etc/libvirt/qemu.conf. ('tls' :since:`Since 4.5.0` )
> >
> > + For "rbd", the ``name`` attribute could be two formats: the format of
> > + ``pool_name/image_name`` includes the rbd pool name and image name with
> > + default rbd pool namespace; for the customized namespace, the format is
> > + ``pool_name/namespace/image_name`` ( :since:`Since 6.9.0 and QEMU 5.0` ).
> > + The pool name, namespace and image are separated by slash.
>
> 7.5.0 at this point.
>
> > +
> > For protocols ``http`` and ``https`` an optional attribute ``query``
> > specifies the query string. ( :since:`Since 6.2.0` )
> >
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index 6d90041bf8..eac59dd00e 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -8197,6 +8197,7 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
> > {
> > virStorageNetProtocol protocol;
> > xmlNodePtr tmpnode;
> > + char **tmp_split_paths;
> >
> > if (virXMLPropEnum(node, "protocol", virStorageNetProtocolTypeFromString,
> > VIR_XML_PROP_REQUIRED, &protocol) < 0)
> > @@ -8226,8 +8227,7 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
> > /* for historical reasons we store the volume and image name in one XML
> > * element although it complicates thing when attempting to access them. */
> > if (src->path &&
> > - (src->protocol == VIR_STORAGE_NET_PROTOCOL_GLUSTER ||
> > - src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD)) {
> > + src->protocol == VIR_STORAGE_NET_PROTOCOL_GLUSTER) {
> > char *tmp;
> > if (!(tmp = strchr(src->path, '/')) ||
> > tmp == src->path) {
> > @@ -8244,6 +8244,41 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
> > tmp[0] = '\0';
> > }
> >
> > + /* the name of rbd could be <pool>/<image> or <pool>/<namespace>/<image> */
> > + if (src->path &&
> > + src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD &&
>
> This algorithm is still needlessly obscure and very hard to follow.
>
>
> > + (tmp_split_paths = g_strsplit(src->path, "/", 3))) {
> > + if (virStringIsEmpty(tmp_split_paths[0]) ||
> > + !tmp_split_paths[1] ||
> > + STREQ_NULLABLE(tmp_split_paths[2], "") ||
>
> Firstly on 3 lines you have 3 distinct empty sting checks.
>
> > + (virStringIsEmpty(tmp_split_paths[1]) &&
> > + !tmp_split_paths[2])) {
> > + virStringListFreeCount(tmp_split_paths, 3);
>
> Then there's no need for explicit freeing just declare the helper
> variable as g_auto(GStrv).
>
> Additionally put it into the scope here by making the top level
> condition just:
> if (src->path && src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
> ...
>
> > + virReportError(VIR_ERR_XML_ERROR,
> > + _("can't split path '%s' into pool name, pool "
> > + "namespace, image name OR pool name, image name"),
>
> error string should be a signle line. Also the error format is not using
> the expected format that you require. (it should contain the slashes).
>
> > + src->path);
> > + return -1;
> > + }
> > +
> > + VIR_FREE(src->path);
> > + src->volume = g_strdup(tmp_split_paths[0]);
> > + /* the format of <pool>/<image> */
> > + if (!tmp_split_paths[2])
> > + src->path = g_strdup(tmp_split_paths[1]);
> > +
> > + if (tmp_split_paths[2]) {
>
> this is the 'else' section of the above condition.
>
> > + /* the format of <pool>/<ns>/<image> */
> > + if (STRNEQ_NULLABLE(tmp_split_paths[1], ""))
>
> This check is duplicated.
>
> > + src->ns = g_strdup(tmp_split_paths[1]);
> > +
> > + /* the format of <pool>//<image> */
> > + src->path = g_strdup(tmp_split_paths[2]);
>
> Well, so the qemu parser for the stringified name actually supports
> escape sequences.
>
> > + }
> > +
> > + virStringListFreeCount(tmp_split_paths, 3);
>
>
> I suggest the following implementation which should have the same logic
> as what you've proposed:
>
> /* the name of rbd could be <pool>/<image> or <pool>/<namespace>/<image> */
> if (src->path && src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
> g_auto(GStrv) path_components = g_strsplit(src->path, "/", 3);
> size_t npath_components = g_strv_length(path_components);
>
> if (npath_components < 2 ||
> virStringIsEmpty(path_components[0]) ||
> virStringIsEmpty(path_components[npath_components - 1])) {
> virReportError(VIR_ERR_XML_ERROR,
> _("path '%s' doesn't consist of 'pool_name/image_name', or 'pool_name/namespace_name/image_name'"),
> src->path);
> return -1;
> }
>
> VIR_FREE(src->path);
> src->volume = g_strdup(path_components[0]);
>
> if (npath_components == 2 ||
> virStringIsEmpty(path_components[1])) {
> src->path = g_strdup(path_components[1]);
> } else {
> src->ns = g_strdup(path_components[1]);
> src->path = g_strdup(path_components[2]);
> }
Actually the above hunk should be:
if (npath_components == 2) {
src->path = g_strdup(path_components[1]);
} else if (virStringIsEmpty(path_components[1])) {
src->path = g_strdup(path_components[2]);
} else {
src->ns = g_strdup(path_components[1]);
src->path = g_strdup(path_components[2]);
}
> }
>
>
> > + }
> > +
> > /* snapshot currently works only for remote disks */
> > src->snapshot = virXPathString("string(./snapshot/@name)", ctxt);
> >
> > @@ -22948,8 +22983,12 @@ virDomainDiskSourceFormatNetwork(virBuffer *attrBuf,
> > virBufferAsprintf(attrBuf, " protocol='%s'",
> > virStorageNetProtocolTypeToString(src->protocol));
> >
> > - if (src->volume)
> > - path = g_strdup_printf("%s/%s", src->volume, src->path);
> > + if (src->volume) {
> > + if (src->ns)
> > + path = g_strdup_printf("%s/%s/%s", src->volume, src->ns, src->path);
> > + else
> > + path = g_strdup_printf("%s/%s", src->volume, src->path);
> > + }
> >
> > virBufferEscapeString(attrBuf, " name='%s'", path ? path : src->path);
> > virBufferEscapeString(attrBuf, " query='%s'", src->query);
>
> The series is also missing the parsers for the backing store strings
> which we parse from the image metadata in cases when the backing chain
> is not fully defined in the XML.
>
> There's also a possibility that a similar treatment will be needed in
> the URI parser for the RBD case, but I'm not sure whether qemu accepts
> URIs as RBD source.
>
> Namely:
>
> virStorageSourceParseRBDColonString and TEST_BACKING_PARSE test cases
> in tests/virstoragetest.c
>
> and
>
> virStorageSourceParseBackingJSONRBD and also a test case in the above
> mentioned test file.
>
>
>
More information about the libvir-list
mailing list