mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
util: split out qemuParseRBDString into a common helper
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.
This commit is contained in:
parent
162e1ac6fa
commit
5604c056bf
@ -1993,6 +1993,7 @@ virStorageSourceInitChainElement;
|
||||
virStorageSourceIsEmpty;
|
||||
virStorageSourceIsLocalStorage;
|
||||
virStorageSourceNewFromBacking;
|
||||
virStorageSourceParseRBDColonString;
|
||||
virStorageSourcePoolDefFree;
|
||||
virStorageSourcePoolModeTypeFromString;
|
||||
virStorageSourcePoolModeTypeToString;
|
||||
|
@ -2535,137 +2535,20 @@ qemuGetSecretString(virConnectPtr conn,
|
||||
}
|
||||
|
||||
|
||||
static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
|
||||
static int
|
||||
qemuParseRBDString(virDomainDiskDefPtr disk)
|
||||
{
|
||||
char *port;
|
||||
size_t skip;
|
||||
char **parts;
|
||||
char *source = disk->src->path;
|
||||
int ret;
|
||||
|
||||
if (VIR_EXPAND_N(disk->src->hosts, disk->src->nhosts, 1) < 0)
|
||||
return -1;
|
||||
disk->src->path = NULL;
|
||||
|
||||
if ((port = strchr(hostport, ']'))) {
|
||||
/* ipv6, strip brackets */
|
||||
hostport += 1;
|
||||
skip = 3;
|
||||
} else {
|
||||
port = strstr(hostport, "\\:");
|
||||
skip = 2;
|
||||
ret = virStorageSourceParseRBDColonString(source, disk->src);
|
||||
|
||||
VIR_FREE(source);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
disk->src->hosts[disk->src->nhosts-1].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
|
||||
disk->src->hosts[disk->src->nhosts-1].socket = NULL;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
VIR_FREE(disk->src->hosts[disk->src->nhosts-1].port);
|
||||
VIR_FREE(disk->src->hosts[disk->src->nhosts-1].name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
|
@ -2208,6 +2208,151 @@ 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,
|
||||
virStorageAuthTypeToString(VIR_STORAGE_AUTH_TYPE_CEPHX)) < 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)
|
||||
|
@ -363,6 +363,10 @@ virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
|
||||
bool backingChain)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
int virStorageSourceParseRBDColonString(const char *rbdstr,
|
||||
virStorageSourcePtr src)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
typedef int
|
||||
(*virStorageFileSimplifyPathReadlinkCallback)(const char *path,
|
||||
char **link,
|
||||
|
Loading…
x
Reference in New Issue
Block a user