qemu: Split out formatting of network disk source URI

The snapshot code will need to use qemu-style formatted URIs of network
disks. Split out the code to avoid duplication.
This commit is contained in:
Peter Krempa 2013-11-15 16:29:35 +01:00
parent e1a4d08baf
commit a29d33ffcb
2 changed files with 91 additions and 61 deletions

View File

@ -3626,105 +3626,124 @@ error:
return -1; return -1;
} }
static int
qemuBuildDriveURIString(virConnectPtr conn, char *
virDomainDiskDefPtr disk, virBufferPtr opt, qemuBuildNetworkDriveURI(int protocol,
const char *scheme, virSecretUsageType secretUsageType) const char *src,
size_t nhosts,
virDomainDiskHostDefPtr hosts,
const char *username,
const char *secret)
{ {
int ret = -1; char *ret = NULL;
int port = 0; virURIPtr uri = NULL;
char *secret = NULL;
char *tmpscheme = NULL; if (nhosts != 1) {
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 */
};
if (disk->nhosts != 1) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("%s accepts only one host"), scheme); _("protocol '%s' accepts only one host"),
return -1; virDomainDiskProtocolTypeToString(protocol));
return NULL;
} }
virBufferAddLit(opt, "file="); if (VIR_ALLOC(uri) < 0)
transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport); return NULL;
if (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) { if (hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
if (VIR_STRDUP(tmpscheme, scheme) < 0) if (VIR_STRDUP(uri->scheme, virDomainDiskProtocolTypeToString(protocol)) < 0)
goto cleanup; goto cleanup;
} else { } else {
if (virAsprintf(&tmpscheme, "%s+%s", scheme, transp) < 0) if (virAsprintf(&uri->scheme, "%s+%s",
virDomainDiskProtocolTypeToString(protocol),
virDomainDiskProtocolTransportTypeToString(hosts->transport)) < 0)
goto cleanup; goto cleanup;
} }
if (disk->src && virAsprintf(&volimg, "/%s", disk->src) < 0) if (src &&
virAsprintf(&uri->path, "/%s", src) < 0)
goto cleanup; goto cleanup;
if (disk->hosts->port) { if (hosts->port &&
port = atoi(disk->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 (disk->hosts->socket && if (hosts->socket &&
virAsprintf(&sock, "socket=%s", disk->hosts->socket) < 0) virAsprintf(&uri->query, "socket=%s", hosts->socket) < 0)
goto cleanup; goto cleanup;
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 (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) { if (disk->auth.username && secretUsageType != VIR_SECRET_USAGE_TYPE_NONE) {
/* Get the secret string using the virDomainDiskDef */ /* 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.secretType,
disk->auth.username, disk->auth.username,
disk->auth.secret.uuid, disk->auth.secret.uuid,
disk->auth.secret.usage, disk->auth.secret.usage,
secretUsageType))) secretUsageType)))
goto cleanup; goto cleanup;
if (virAsprintf(&user, "%s:%s", disk->auth.username, secret) < 0)
goto cleanup;
} }
uri.scheme = tmpscheme; /* gluster+<transport> */ if (!(builturi = qemuBuildNetworkDriveURI(protocol,
uri.server = disk->hosts->name; disk->src,
uri.user = user; disk->nhosts,
uri.port = port; disk->hosts,
uri.path = volimg; disk->auth.username,
uri.query = sock; secret)))
goto cleanup;
builturi = virURIFormat(&uri);
virBufferEscape(opt, ',', ",", "%s", builturi); virBufferEscape(opt, ',', ",", "%s", builturi);
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(builturi);
VIR_FREE(tmpscheme);
VIR_FREE(volimg);
VIR_FREE(sock);
VIR_FREE(secret); VIR_FREE(secret);
VIR_FREE(user); VIR_FREE(builturi);
return ret; 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" #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 static int
qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt) qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
{ {
@ -3741,7 +3760,8 @@ qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr op
&& !disk->hosts->name) && !disk->hosts->name)
|| (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX || (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX
&& disk->hosts->socket && disk->hosts->socket[0] != '/')) && 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); VIR_SECRET_USAGE_TYPE_NONE);
virBufferAddLit(opt, "file=nbd:"); virBufferAddLit(opt, "file=nbd:");
@ -3910,12 +3930,16 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
virBufferAddChar(&opt, ','); virBufferAddChar(&opt, ',');
break; break;
case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER: 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; goto error;
virBufferAddChar(&opt, ','); virBufferAddChar(&opt, ',');
break; break;
case VIR_DOMAIN_DISK_PROTOCOL_ISCSI: 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; goto error;
virBufferAddChar(&opt, ','); virBufferAddChar(&opt, ',');
break; break;

View File

@ -180,6 +180,12 @@ char * qemuBuildHubDevStr(virDomainDefPtr def,
char * qemuBuildRedirdevDevStr(virDomainDefPtr def, char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
virDomainRedirdevDefPtr dev, virDomainRedirdevDefPtr dev,
virQEMUCapsPtr qemuCaps); virQEMUCapsPtr qemuCaps);
char *qemuBuildNetworkDriveURI(int proto,
const char *src,
size_t nhosts,
virDomainDiskHostDefPtr hosts,
const char *username,
const char *secret);
int qemuNetworkIfaceConnect(virDomainDefPtr def, int qemuNetworkIfaceConnect(virDomainDefPtr def,
virConnectPtr conn, virConnectPtr conn,