The snapshot code will need to use qemu-style formatted URIs of network
disks. Split out the code to avoid duplication.
---
src/qemu/qemu_command.c | 146 ++++++++++++++++++++++++++++--------------------
src/qemu/qemu_command.h | 6 ++
2 files changed, 91 insertions(+), 61 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2a4390e..91b1bd2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3626,106 +3626,125 @@ error:
return -1;
}
-static int
-qemuBuildDriveURIString(virConnectPtr conn,
- virDomainDiskDefPtr disk, virBufferPtr opt,
- const char *scheme, virSecretUsageType secretUsageType)
-{
- int ret = -1;
- int port = 0;
- char *secret = NULL;
- char *tmpscheme = NULL;
- char *volimg = NULL;
- char *sock = NULL;
- char *user = NULL;
- char *builturi = NULL;
- const char *transp = NULL;
- virURI uri = {
- .port = port /* just to clear rest of bits */
- };
+char *
+qemuBuildNetworkDriveURI(int protocol,
+ const char *src,
+ size_t nhosts,
+ virDomainDiskHostDefPtr hosts,
+ const char *username,
+ const char *secret)
+{
+ char *ret = NULL;
+ virURIPtr uri = NULL;
- if (disk->nhosts != 1) {
+ if (nhosts != 1) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("%s accepts only one host"), scheme);
- return -1;
+ _("protocol '%s' accepts only one host"),
+ virDomainDiskProtocolTypeToString(protocol));
+ return NULL;
}
- virBufferAddLit(opt, "file=");
- transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport);
+ if (VIR_ALLOC(uri) < 0)
+ return NULL;
- if (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
- if (VIR_STRDUP(tmpscheme, scheme) < 0)
+ if (hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
+ if (VIR_STRDUP(uri->scheme, virDomainDiskProtocolTypeToString(protocol)) <
0)
goto cleanup;
} else {
- if (virAsprintf(&tmpscheme, "%s+%s", scheme, transp) < 0)
+ if (virAsprintf(&uri->scheme, "%s+%s",
+ virDomainDiskProtocolTypeToString(protocol),
+ virDomainDiskProtocolTransportTypeToString(hosts->transport))
< 0)
goto cleanup;
}
- if (disk->src && virAsprintf(&volimg, "/%s", disk->src)
< 0)
+ if (src &&
+ virAsprintf(&uri->path, "/%s", src) < 0)
+ goto cleanup;
+
+ if (hosts->port &&
+ virStrToLong_i(hosts->port, NULL, 10, &uri->port) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to parse port number '%s'"),
+ hosts->port);
+ goto cleanup;
+ }
+
+ if (hosts->socket &&
+ virAsprintf(&uri->query, "socket=%s", hosts->socket) < 0)
goto cleanup;
- if (disk->hosts->port) {
- port = atoi(disk->hosts->port);
+ if (username) {
+ if (secret) {
+ if (virAsprintf(&uri->user, "%s:%s", username, secret) <
0)
+ goto cleanup;
+ } else {
+ if (VIR_STRDUP(uri->user, username) < 0)
+ goto cleanup;
+ }
}
- if (disk->hosts->socket &&
- virAsprintf(&sock, "socket=%s", disk->hosts->socket) < 0)
+ if (VIR_STRDUP(uri->server, hosts->name) < 0)
goto cleanup;
+ ret = virURIFormat(uri);
+
+cleanup:
+ virURIFree(uri);
+
+ return ret;
+}
+
+
+static int
+qemuBuildDriveURIString(virConnectPtr conn,
+ virDomainDiskDefPtr disk,
+ virBufferPtr opt,
+ int protocol,
+ virSecretUsageType secretUsageType)
+{
+ char *secret = NULL;
+ char *builturi = NULL;
+ int ret = -1;
+
+ virBufferAddLit(opt, "file=");
+
if (disk->auth.username && secretUsageType != VIR_SECRET_USAGE_TYPE_NONE)
{
/* Get the secret string using the virDomainDiskDef */
- if (!(secret = qemuGetSecretString(conn, scheme, false,
+ if (!(secret = qemuGetSecretString(conn,
+ virDomainDiskProtocolTypeToString(protocol),
+ false,
disk->auth.secretType,
disk->auth.username,
disk->auth.secret.uuid,
disk->auth.secret.usage,
secretUsageType)))
goto cleanup;
- if (virAsprintf(&user, "%s:%s", disk->auth.username, secret)
< 0)
- goto cleanup;
}
- uri.scheme = tmpscheme; /* gluster+<transport> */
- uri.server = disk->hosts->name;
- uri.user = user;
- uri.port = port;
- uri.path = volimg;
- uri.query = sock;
+ if (!(builturi = qemuBuildNetworkDriveURI(protocol,
+ disk->src,
+ disk->nhosts,
+ disk->hosts,
+ disk->auth.username,
+ secret)))
+ goto cleanup;
- builturi = virURIFormat(&uri);
virBufferEscape(opt, ',', ",", "%s", builturi);
ret = 0;
cleanup:
- VIR_FREE(builturi);
- VIR_FREE(tmpscheme);
- VIR_FREE(volimg);
- VIR_FREE(sock);
VIR_FREE(secret);
- VIR_FREE(user);
+ VIR_FREE(builturi);
return ret;
}
-static int
-qemuBuildGlusterString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
-{
- return qemuBuildDriveURIString(conn, disk, opt, "gluster",
- VIR_SECRET_USAGE_TYPE_NONE);
-}
#define QEMU_DEFAULT_NBD_PORT "10809"
static int
-qemuBuildISCSIString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
-{
- return qemuBuildDriveURIString(conn, disk, opt, "iscsi",
- VIR_SECRET_USAGE_TYPE_ISCSI);
-}
-
-static int
qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
{
const char *transp;
@@ -3741,7 +3760,8 @@ qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk,
virBufferPtr op
&& !disk->hosts->name)
|| (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX
&& disk->hosts->socket && disk->hosts->socket[0]
!= '/'))
- return qemuBuildDriveURIString(conn, disk, opt, "nbd",
+ return qemuBuildDriveURIString(conn, disk, opt,
+ VIR_DOMAIN_DISK_PROTOCOL_NBD,
VIR_SECRET_USAGE_TYPE_NONE);
virBufferAddLit(opt, "file=nbd:");
@@ -3910,12 +3930,16 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
virBufferAddChar(&opt, ',');
break;
case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
- if (qemuBuildGlusterString(conn, disk, &opt) < 0)
+ if (qemuBuildDriveURIString(conn, disk, &opt,
+ VIR_DOMAIN_DISK_PROTOCOL_GLUSTER,
+ VIR_SECRET_USAGE_TYPE_NONE) < 0)
goto error;
virBufferAddChar(&opt, ',');
break;
case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
- if (qemuBuildISCSIString(conn, disk, &opt) < 0)
+ if (qemuBuildDriveURIString(conn, disk, &opt,
+ VIR_DOMAIN_DISK_PROTOCOL_ISCSI,
+ VIR_SECRET_USAGE_TYPE_ISCSI) < 0)
goto error;
virBufferAddChar(&opt, ',');
break;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 3277ba4..66c23cc 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -180,6 +180,12 @@ char * qemuBuildHubDevStr(virDomainDefPtr def,
char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
virDomainRedirdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
+char *qemuBuildNetworkDriveURI(int proto,
+ const char *src,
+ size_t nhosts,
+ virDomainDiskHostDefPtr hosts,
+ const char *username,
+ const char *secret);
int qemuNetworkIfaceConnect(virDomainDefPtr def,
virConnectPtr conn,
--
1.8.4.3