9119d9
From 5f5cf964e92c366ff9d423ac9bb9256ee7a79722 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <5f5cf964e92c366ff9d423ac9bb9256ee7a79722@dist-git>
9119d9
From: Peter Krempa <pkrempa@redhat.com>
9119d9
Date: Fri, 21 Nov 2014 15:04:08 +0100
9119d9
Subject: [PATCH] util: split out qemuParseRBDString into a common helper
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1164528
9119d9
9119d9
To allow reuse this non-trivial parser code in the backing store parser
9119d9
this part of the command line parser needs to be split out into a
9119d9
separate funciton.
9119d9
9119d9
(cherry picked from commit 5604c056bfa967683b8445349dd5218e531497d4)
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/libvirt_private.syms  |   1 +
9119d9
 src/qemu/qemu_command.c   | 133 +++---------------------------------------
9119d9
 src/util/virstoragefile.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++
9119d9
 src/util/virstoragefile.h |   4 ++
9119d9
 4 files changed, 158 insertions(+), 125 deletions(-)
9119d9
9119d9
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
9119d9
index de4b128..15843f8 100644
9119d9
--- a/src/libvirt_private.syms
9119d9
+++ b/src/libvirt_private.syms
9119d9
@@ -1956,6 +1956,7 @@ virStorageSourceInitChainElement;
9119d9
 virStorageSourceIsEmpty;
9119d9
 virStorageSourceIsLocalStorage;
9119d9
 virStorageSourceNewFromBacking;
9119d9
+virStorageSourceParseRBDColonString;
9119d9
 virStorageSourcePoolDefFree;
9119d9
 virStorageSourcePoolModeTypeFromString;
9119d9
 virStorageSourcePoolModeTypeToString;
9119d9
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
9119d9
index 557c985..93f02a9 100644
9119d9
--- a/src/qemu/qemu_command.c
9119d9
+++ b/src/qemu/qemu_command.c
9119d9
@@ -2538,137 +2538,20 @@ qemuGetSecretString(virConnectPtr conn,
9119d9
 }
9119d9
 
9119d9
 
9119d9
-static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
9119d9
+static int
9119d9
+qemuParseRBDString(virDomainDiskDefPtr disk)
9119d9
 {
9119d9
-    char *port;
9119d9
-    size_t skip;
9119d9
-    char **parts;
9119d9
+    char *source = disk->src->path;
9119d9
+    int ret;
9119d9
 
9119d9
-    if (VIR_EXPAND_N(disk->src->hosts, disk->src->nhosts, 1) < 0)
9119d9
-        return -1;
9119d9
+    disk->src->path = NULL;
9119d9
 
9119d9
-    if ((port = strchr(hostport, ']'))) {
9119d9
-        /* ipv6, strip brackets */
9119d9
-        hostport += 1;
9119d9
-        skip = 3;
9119d9
-    } else {
9119d9
-        port = strstr(hostport, "\\:");
9119d9
-        skip = 2;
9119d9
-    }
9119d9
+    ret = virStorageSourceParseRBDColonString(source, disk->src);
9119d9
 
9119d9
-    if (port) {
9119d9
-        *port = '\0';
9119d9
-        port += skip;
9119d9
-        if (VIR_STRDUP(disk->src->hosts[disk->src->nhosts - 1].port, port) < 0)
9119d9
-            goto error;
9119d9
-    } else {
9119d9
-        if (VIR_STRDUP(disk->src->hosts[disk->src->nhosts - 1].port, "6789") < 0)
9119d9
-            goto error;
9119d9
-    }
9119d9
-
9119d9
-    parts = virStringSplit(hostport, "\\:", 0);
9119d9
-    if (!parts)
9119d9
-        goto error;
9119d9
-    disk->src->hosts[disk->src->nhosts-1].name = virStringJoin((const char **)parts, ":");
9119d9
-    virStringFreeList(parts);
9119d9
-    if (!disk->src->hosts[disk->src->nhosts-1].name)
9119d9
-        goto error;
9119d9
-
9119d9
-    disk->src->hosts[disk->src->nhosts-1].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
9119d9
-    disk->src->hosts[disk->src->nhosts-1].socket = NULL;
9119d9
-
9119d9
-    return 0;
9119d9
-
9119d9
- error:
9119d9
-    VIR_FREE(disk->src->hosts[disk->src->nhosts-1].port);
9119d9
-    VIR_FREE(disk->src->hosts[disk->src->nhosts-1].name);
9119d9
-    return -1;
9119d9
+    VIR_FREE(source);
9119d9
+    return ret;
9119d9
 }
9119d9
 
9119d9
-/* disk->src initially has everything after the rbd: prefix */
9119d9
-static int qemuParseRBDString(virDomainDiskDefPtr disk)
9119d9
-{
9119d9
-    char *options = NULL;
9119d9
-    char *p, *e, *next;
9119d9
-    virStorageAuthDefPtr authdef = NULL;
9119d9
-
9119d9
-    p = strchr(disk->src->path, ':');
9119d9
-    if (p) {
9119d9
-        if (VIR_STRDUP(options, p + 1) < 0)
9119d9
-            goto error;
9119d9
-        *p = '\0';
9119d9
-    }
9119d9
-
9119d9
-    /* options */
9119d9
-    if (!options)
9119d9
-        return 0; /* all done */
9119d9
-
9119d9
-    p = options;
9119d9
-    while (*p) {
9119d9
-        /* find : delimiter or end of string */
9119d9
-        for (e = p; *e && *e != ':'; ++e) {
9119d9
-            if (*e == '\\') {
9119d9
-                e++;
9119d9
-                if (*e == '\0')
9119d9
-                    break;
9119d9
-            }
9119d9
-        }
9119d9
-        if (*e == '\0') {
9119d9
-            next = e;    /* last kv pair */
9119d9
-        } else {
9119d9
-            next = e + 1;
9119d9
-            *e = '\0';
9119d9
-        }
9119d9
-
9119d9
-        if (STRPREFIX(p, "id=")) {
9119d9
-            const char *secrettype;
9119d9
-            /* formulate authdef for disk->src->auth */
9119d9
-            if (VIR_ALLOC(authdef) < 0)
9119d9
-                goto error;
9119d9
-
9119d9
-            if (VIR_STRDUP(authdef->username, p + strlen("id=")) < 0)
9119d9
-                goto error;
9119d9
-            secrettype = virSecretUsageTypeToString(VIR_SECRET_USAGE_TYPE_CEPH);
9119d9
-            if (VIR_STRDUP(authdef->secrettype, secrettype) < 0)
9119d9
-                goto error;
9119d9
-            disk->src->auth = authdef;
9119d9
-            authdef = NULL;
9119d9
-
9119d9
-            /* Cannot formulate a secretType (eg, usage or uuid) given
9119d9
-             * what is provided.
9119d9
-             */
9119d9
-        }
9119d9
-        if (STRPREFIX(p, "mon_host=")) {
9119d9
-            char *h, *sep;
9119d9
-
9119d9
-            h = p + strlen("mon_host=");
9119d9
-            while (h < e) {
9119d9
-                for (sep = h; sep < e; ++sep) {
9119d9
-                    if (*sep == '\\' && (sep[1] == ',' ||
9119d9
-                                         sep[1] == ';' ||
9119d9
-                                         sep[1] == ' ')) {
9119d9
-                        *sep = '\0';
9119d9
-                        sep += 2;
9119d9
-                        break;
9119d9
-                    }
9119d9
-                }
9119d9
-                if (qemuAddRBDHost(disk, h) < 0)
9119d9
-                    goto error;
9119d9
-
9119d9
-                h = sep;
9119d9
-            }
9119d9
-        }
9119d9
-
9119d9
-        p = next;
9119d9
-    }
9119d9
-    VIR_FREE(options);
9119d9
-    return 0;
9119d9
-
9119d9
- error:
9119d9
-    VIR_FREE(options);
9119d9
-    virStorageAuthDefFree(authdef);
9119d9
-    return -1;
9119d9
-}
9119d9
 
9119d9
 static int
9119d9
 qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
9119d9
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
9119d9
index fa569d8..ecf329b 100644
9119d9
--- a/src/util/virstoragefile.c
9119d9
+++ b/src/util/virstoragefile.c
9119d9
@@ -2188,6 +2188,151 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
9119d9
 
9119d9
 
9119d9
 static int
9119d9
+virStorageSourceRBDAddHost(virStorageSourcePtr src,
9119d9
+                           char *hostport)
9119d9
+{
9119d9
+    char *port;
9119d9
+    size_t skip;
9119d9
+    char **parts;
9119d9
+
9119d9
+    if (VIR_EXPAND_N(src->hosts, src->nhosts, 1) < 0)
9119d9
+        return -1;
9119d9
+
9119d9
+    if ((port = strchr(hostport, ']'))) {
9119d9
+        /* ipv6, strip brackets */
9119d9
+        hostport += 1;
9119d9
+        skip = 3;
9119d9
+    } else {
9119d9
+        port = strstr(hostport, "\\:");
9119d9
+        skip = 2;
9119d9
+    }
9119d9
+
9119d9
+    if (port) {
9119d9
+        *port = '\0';
9119d9
+        port += skip;
9119d9
+        if (VIR_STRDUP(src->hosts[src->nhosts - 1].port, port) < 0)
9119d9
+            goto error;
9119d9
+    } else {
9119d9
+        if (VIR_STRDUP(src->hosts[src->nhosts - 1].port, "6789") < 0)
9119d9
+            goto error;
9119d9
+    }
9119d9
+
9119d9
+    parts = virStringSplit(hostport, "\\:", 0);
9119d9
+    if (!parts)
9119d9
+        goto error;
9119d9
+    src->hosts[src->nhosts-1].name = virStringJoin((const char **)parts, ":");
9119d9
+    virStringFreeList(parts);
9119d9
+    if (!src->hosts[src->nhosts-1].name)
9119d9
+        goto error;
9119d9
+
9119d9
+    src->hosts[src->nhosts-1].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
9119d9
+    src->hosts[src->nhosts-1].socket = NULL;
9119d9
+
9119d9
+    return 0;
9119d9
+
9119d9
+ error:
9119d9
+    VIR_FREE(src->hosts[src->nhosts-1].port);
9119d9
+    VIR_FREE(src->hosts[src->nhosts-1].name);
9119d9
+    return -1;
9119d9
+}
9119d9
+
9119d9
+
9119d9
+int
9119d9
+virStorageSourceParseRBDColonString(const char *rbdstr,
9119d9
+                                    virStorageSourcePtr src)
9119d9
+{
9119d9
+    char *options = NULL;
9119d9
+    char *p, *e, *next;
9119d9
+    virStorageAuthDefPtr authdef = NULL;
9119d9
+
9119d9
+    /* optionally skip the "rbd:" prefix if provided */
9119d9
+    if (STRPREFIX(rbdstr, "rbd:"))
9119d9
+        rbdstr += strlen("rbd:");
9119d9
+
9119d9
+    if (VIR_STRDUP(src->path, rbdstr) < 0)
9119d9
+        goto error;
9119d9
+
9119d9
+    p = strchr(src->path, ':');
9119d9
+    if (p) {
9119d9
+        if (VIR_STRDUP(options, p + 1) < 0)
9119d9
+            goto error;
9119d9
+        *p = '\0';
9119d9
+    }
9119d9
+
9119d9
+    /* options */
9119d9
+    if (!options)
9119d9
+        return 0; /* all done */
9119d9
+
9119d9
+    p = options;
9119d9
+    while (*p) {
9119d9
+        /* find : delimiter or end of string */
9119d9
+        for (e = p; *e && *e != ':'; ++e) {
9119d9
+            if (*e == '\\') {
9119d9
+                e++;
9119d9
+                if (*e == '\0')
9119d9
+                    break;
9119d9
+            }
9119d9
+        }
9119d9
+        if (*e == '\0') {
9119d9
+            next = e;    /* last kv pair */
9119d9
+        } else {
9119d9
+            next = e + 1;
9119d9
+            *e = '\0';
9119d9
+        }
9119d9
+
9119d9
+        if (STRPREFIX(p, "id=")) {
9119d9
+            /* formulate authdef for src->auth */
9119d9
+            if (VIR_ALLOC(authdef) < 0)
9119d9
+                goto error;
9119d9
+
9119d9
+            if (VIR_STRDUP(authdef->username, p + strlen("id=")) < 0)
9119d9
+                goto error;
9119d9
+
9119d9
+            if (VIR_STRDUP(authdef->secrettype,
9119d9
+                           virStorageAuthTypeToString(VIR_STORAGE_AUTH_TYPE_CEPHX)) < 0)
9119d9
+                goto error;
9119d9
+            src->auth = authdef;
9119d9
+            authdef = NULL;
9119d9
+
9119d9
+            /* Cannot formulate a secretType (eg, usage or uuid) given
9119d9
+             * what is provided.
9119d9
+             */
9119d9
+        }
9119d9
+        if (STRPREFIX(p, "mon_host=")) {
9119d9
+            char *h, *sep;
9119d9
+
9119d9
+            h = p + strlen("mon_host=");
9119d9
+            while (h < e) {
9119d9
+                for (sep = h; sep < e; ++sep) {
9119d9
+                    if (*sep == '\\' && (sep[1] == ',' ||
9119d9
+                                         sep[1] == ';' ||
9119d9
+                                         sep[1] == ' ')) {
9119d9
+                        *sep = '\0';
9119d9
+                        sep += 2;
9119d9
+                        break;
9119d9
+                    }
9119d9
+                }
9119d9
+
9119d9
+                if (virStorageSourceRBDAddHost(src, h) < 0)
9119d9
+                    goto error;
9119d9
+
9119d9
+                h = sep;
9119d9
+            }
9119d9
+        }
9119d9
+
9119d9
+        p = next;
9119d9
+    }
9119d9
+    VIR_FREE(options);
9119d9
+    return 0;
9119d9
+
9119d9
+ error:
9119d9
+    VIR_FREE(options);
9119d9
+    virStorageAuthDefFree(authdef);
9119d9
+    return -1;
9119d9
+}
9119d9
+
9119d9
+
9119d9
+static int
9119d9
 virStorageSourceParseBackingColon(virStorageSourcePtr src,
9119d9
                                   const char *path)
9119d9
 {
9119d9
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
9119d9
index 2583e10..3573ccd 100644
9119d9
--- a/src/util/virstoragefile.h
9119d9
+++ b/src/util/virstoragefile.h
9119d9
@@ -361,6 +361,10 @@ virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
9119d9
                                          bool backingChain)
9119d9
     ATTRIBUTE_NONNULL(1);
9119d9
 
9119d9
+int virStorageSourceParseRBDColonString(const char *rbdstr,
9119d9
+                                        virStorageSourcePtr src)
9119d9
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
9119d9
+
9119d9
 typedef int
9119d9
 (*virStorageFileSimplifyPathReadlinkCallback)(const char *path,
9119d9
                                               char **link,
9119d9
-- 
9119d9
2.1.3
9119d9