To allow reuse this non-trivial parser code in the backing store parser
this part of the command line parser needs to be split out into a
separate funciton.
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 133 +++---------------------------------------
src/util/virstoragefile.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/virstoragefile.h | 3 +
4 files changed, 156 insertions(+), 125 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b8f35e8..b33722e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1991,6 +1991,7 @@ virStorageSourceInitChainElement;
virStorageSourceIsEmpty;
virStorageSourceIsLocalStorage;
virStorageSourceNewFromBacking;
+virStorageSourceParseRBDColonString;
virStorageSourcePoolDefFree;
virStorageSourcePoolModeTypeFromString;
virStorageSourcePoolModeTypeToString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 19e8f9d..021ec07 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2540,137 +2540,20 @@ qemuGetSecretString(virConnectPtr conn,
}
-static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
+static int
+qemuParseRBDString(virDomainDiskDefPtr disk)
{
- char *port;
- size_t skip;
- char **parts;
-
- if (VIR_EXPAND_N(disk->src->hosts, disk->src->nhosts, 1) < 0)
- return -1;
-
- if ((port = strchr(hostport, ']'))) {
- /* ipv6, strip brackets */
- hostport += 1;
- skip = 3;
- } else {
- port = strstr(hostport, "\\:");
- skip = 2;
- }
-
- if (port) {
- *port = '\0';
- port += skip;
- if (VIR_STRDUP(disk->src->hosts[disk->src->nhosts - 1].port, port)
< 0)
- goto error;
- } else {
- if (VIR_STRDUP(disk->src->hosts[disk->src->nhosts - 1].port,
"6789") < 0)
- goto error;
- }
-
- parts = virStringSplit(hostport, "\\:", 0);
- if (!parts)
- goto error;
- disk->src->hosts[disk->src->nhosts-1].name = virStringJoin((const char
**)parts, ":");
- virStringFreeList(parts);
- if (!disk->src->hosts[disk->src->nhosts-1].name)
- goto error;
+ char *source = disk->src->path;
+ int ret;
- disk->src->hosts[disk->src->nhosts-1].transport =
VIR_STORAGE_NET_HOST_TRANS_TCP;
- disk->src->hosts[disk->src->nhosts-1].socket = NULL;
+ disk->src->path = NULL;
- return 0;
+ ret = virStorageSourceParseRBDColonString(source, disk->src);
- error:
- VIR_FREE(disk->src->hosts[disk->src->nhosts-1].port);
- VIR_FREE(disk->src->hosts[disk->src->nhosts-1].name);
- return -1;
+ VIR_FREE(source);
+ return ret;
}
-/* disk->src initially has everything after the rbd: prefix */
-static int qemuParseRBDString(virDomainDiskDefPtr disk)
-{
- char *options = NULL;
- char *p, *e, *next;
- virStorageAuthDefPtr authdef = NULL;
-
- p = strchr(disk->src->path, ':');
- if (p) {
- if (VIR_STRDUP(options, p + 1) < 0)
- goto error;
- *p = '\0';
- }
-
- /* options */
- if (!options)
- return 0; /* all done */
-
- p = options;
- while (*p) {
- /* find : delimiter or end of string */
- for (e = p; *e && *e != ':'; ++e) {
- if (*e == '\\') {
- e++;
- if (*e == '\0')
- break;
- }
- }
- if (*e == '\0') {
- next = e; /* last kv pair */
- } else {
- next = e + 1;
- *e = '\0';
- }
-
- if (STRPREFIX(p, "id=")) {
- const char *secrettype;
- /* formulate authdef for disk->src->auth */
- if (VIR_ALLOC(authdef) < 0)
- goto error;
-
- if (VIR_STRDUP(authdef->username, p + strlen("id=")) < 0)
- goto error;
- secrettype = virSecretUsageTypeToString(VIR_SECRET_USAGE_TYPE_CEPH);
- if (VIR_STRDUP(authdef->secrettype, secrettype) < 0)
- goto error;
- disk->src->auth = authdef;
- authdef = NULL;
-
- /* Cannot formulate a secretType (eg, usage or uuid) given
- * what is provided.
- */
- }
- if (STRPREFIX(p, "mon_host=")) {
- char *h, *sep;
-
- h = p + strlen("mon_host=");
- while (h < e) {
- for (sep = h; sep < e; ++sep) {
- if (*sep == '\\' && (sep[1] == ',' ||
- sep[1] == ';' ||
- sep[1] == ' ')) {
- *sep = '\0';
- sep += 2;
- break;
- }
- }
- if (qemuAddRBDHost(disk, h) < 0)
- goto error;
-
- h = sep;
- }
- }
-
- p = next;
- }
- VIR_FREE(options);
- return 0;
-
- error:
- VIR_FREE(options);
- virStorageAuthDefFree(authdef);
- return -1;
-}
static int
qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index c2d5b46..f267d1a 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2209,6 +2209,150 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
static int
+virStorageSourceRBDAddHost(virStorageSourcePtr src,
+ char *hostport)
+{
+ char *port;
+ size_t skip;
+ char **parts;
+
+ if (VIR_EXPAND_N(src->hosts, src->nhosts, 1) < 0)
+ return -1;
+
+ if ((port = strchr(hostport, ']'))) {
+ /* ipv6, strip brackets */
+ hostport += 1;
+ skip = 3;
+ } else {
+ port = strstr(hostport, "\\:");
+ skip = 2;
+ }
+
+ if (port) {
+ *port = '\0';
+ port += skip;
+ if (VIR_STRDUP(src->hosts[src->nhosts - 1].port, port) < 0)
+ goto error;
+ } else {
+ if (VIR_STRDUP(src->hosts[src->nhosts - 1].port, "6789") < 0)
+ goto error;
+ }
+
+ parts = virStringSplit(hostport, "\\:", 0);
+ if (!parts)
+ goto error;
+ src->hosts[src->nhosts-1].name = virStringJoin((const char **)parts,
":");
+ virStringFreeList(parts);
+ if (!src->hosts[src->nhosts-1].name)
+ goto error;
+
+ src->hosts[src->nhosts-1].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+ src->hosts[src->nhosts-1].socket = NULL;
+
+ return 0;
+
+ error:
+ VIR_FREE(src->hosts[src->nhosts-1].port);
+ VIR_FREE(src->hosts[src->nhosts-1].name);
+ return -1;
+}
+
+
+int
+virStorageSourceParseRBDColonString(const char *rbdstr,
+ virStorageSourcePtr src)
+{
+ char *options = NULL;
+ char *p, *e, *next;
+ virStorageAuthDefPtr authdef = NULL;
+
+ /* optionally skip the "rbd:" prefix if provided */
+ if (STRPREFIX(rbdstr, "rbd:"))
+ rbdstr += strlen("rbd:");
+
+ if (VIR_STRDUP(src->path, rbdstr) < 0)
+ goto error;
+
+ p = strchr(src->path, ':');
+ if (p) {
+ if (VIR_STRDUP(options, p + 1) < 0)
+ goto error;
+ *p = '\0';
+ }
+
+ /* options */
+ if (!options)
+ return 0; /* all done */
+
+ p = options;
+ while (*p) {
+ /* find : delimiter or end of string */
+ for (e = p; *e && *e != ':'; ++e) {
+ if (*e == '\\') {
+ e++;
+ if (*e == '\0')
+ break;
+ }
+ }
+ if (*e == '\0') {
+ next = e; /* last kv pair */
+ } else {
+ next = e + 1;
+ *e = '\0';
+ }
+
+ if (STRPREFIX(p, "id=")) {
+ /* formulate authdef for src->auth */
+ if (VIR_ALLOC(authdef) < 0)
+ goto error;
+
+ if (VIR_STRDUP(authdef->username, p + strlen("id=")) < 0)
+ goto error;
+
+ if (VIR_STRDUP(authdef->secrettype, "ceph") < 0)
+ goto error;
+ src->auth = authdef;
+ authdef = NULL;
+
+ /* Cannot formulate a secretType (eg, usage or uuid) given
+ * what is provided.
+ */
+ }
+ if (STRPREFIX(p, "mon_host=")) {
+ char *h, *sep;
+
+ h = p + strlen("mon_host=");
+ while (h < e) {
+ for (sep = h; sep < e; ++sep) {
+ if (*sep == '\\' && (sep[1] == ',' ||
+ sep[1] == ';' ||
+ sep[1] == ' ')) {
+ *sep = '\0';
+ sep += 2;
+ break;
+ }
+ }
+
+ if (virStorageSourceRBDAddHost(src, h) < 0)
+ goto error;
+
+ h = sep;
+ }
+ }
+
+ p = next;
+ }
+ VIR_FREE(options);
+ return 0;
+
+ error:
+ VIR_FREE(options);
+ virStorageAuthDefFree(authdef);
+ return -1;
+}
+
+
+static int
virStorageSourceParseBackingColon(virStorageSourcePtr src,
const char *path)
{
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 7f3f353..b1ba73a 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -363,6 +363,9 @@ virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
bool backingChain)
ATTRIBUTE_NONNULL(1);
+int virStorageSourceParseRBDColonString(const char *rbdstr,
+ virStorageSourcePtr src);
+
typedef int
(*virStorageFileSimplifyPathReadlinkCallback)(const char *path,
char **link,
--
2.1.0