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;
|
virStorageSourceIsEmpty;
|
||||||
virStorageSourceIsLocalStorage;
|
virStorageSourceIsLocalStorage;
|
||||||
virStorageSourceNewFromBacking;
|
virStorageSourceNewFromBacking;
|
||||||
|
virStorageSourceParseRBDColonString;
|
||||||
virStorageSourcePoolDefFree;
|
virStorageSourcePoolDefFree;
|
||||||
virStorageSourcePoolModeTypeFromString;
|
virStorageSourcePoolModeTypeFromString;
|
||||||
virStorageSourcePoolModeTypeToString;
|
virStorageSourcePoolModeTypeToString;
|
||||||
|
@ -2535,137 +2535,20 @@ qemuGetSecretString(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
|
static int
|
||||||
|
qemuParseRBDString(virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
char *port;
|
char *source = disk->src->path;
|
||||||
size_t skip;
|
int ret;
|
||||||
char **parts;
|
|
||||||
|
|
||||||
if (VIR_EXPAND_N(disk->src->hosts, disk->src->nhosts, 1) < 0)
|
disk->src->path = NULL;
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((port = strchr(hostport, ']'))) {
|
ret = virStorageSourceParseRBDColonString(source, disk->src);
|
||||||
/* ipv6, strip brackets */
|
|
||||||
hostport += 1;
|
|
||||||
skip = 3;
|
|
||||||
} else {
|
|
||||||
port = strstr(hostport, "\\:");
|
|
||||||
skip = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port) {
|
VIR_FREE(source);
|
||||||
*port = '\0';
|
return ret;
|
||||||
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
|
static int
|
||||||
qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
|
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
|
static int
|
||||||
virStorageSourceParseBackingColon(virStorageSourcePtr src,
|
virStorageSourceParseBackingColon(virStorageSourcePtr src,
|
||||||
const char *path)
|
const char *path)
|
||||||
|
@ -363,6 +363,10 @@ virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
|
|||||||
bool backingChain)
|
bool backingChain)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
int virStorageSourceParseRBDColonString(const char *rbdstr,
|
||||||
|
virStorageSourcePtr src)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
typedef int
|
typedef int
|
||||||
(*virStorageFileSimplifyPathReadlinkCallback)(const char *path,
|
(*virStorageFileSimplifyPathReadlinkCallback)(const char *path,
|
||||||
char **link,
|
char **link,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user