From: Paolo Bonzini Date: Mon, 25 Feb 2013 17:44:22 +0000 (+0100) Subject: qemu: rewrite NBD command-line builder and parser X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=db95213e595ebbc7558d6aedab0dc36bffbe894b;p=libvirt.git qemu: rewrite NBD command-line builder and parser Move the code to an external function, and structure it to prepare the addition of new features in the next few patches. Signed-off-by: Paolo Bonzini Signed-off-by: Eric Blake --- diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 03f068c251..9e2d6a9bf6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2373,6 +2373,45 @@ error: goto cleanup; } +static int +qemuParseNBDString(virDomainDiskDefPtr disk) +{ + virDomainDiskHostDefPtr h = NULL; + char *host, *port; + + if (VIR_ALLOC(h) < 0) + goto no_memory; + + host = disk->src + strlen("nbd:"); + port = strchr(host, ':'); + if (!port) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse nbd filename '%s'"), disk->src); + goto error; + } + + *port++ = '\0'; + h->name = strdup(host); + if (!h->name) + goto no_memory; + + h->port = strdup(port); + if (!h->port) + goto no_memory; + + VIR_FREE(disk->src); + disk->nhosts = 1; + disk->hosts = h; + return 0; + +no_memory: + virReportOOMError(); +error: + virDomainDiskHostDefFree(h); + VIR_FREE(h); + return -1; +} + static int qemuBuildGlusterString(virDomainDiskDefPtr disk, virBufferPtr opt) { @@ -2434,6 +2473,39 @@ no_memory: goto cleanup; } +#define QEMU_DEFAULT_NBD_PORT "10809" + +static int +qemuBuildNBDString(virDomainDiskDefPtr disk, virBufferPtr opt) +{ + const char *transp; + + if (disk->nhosts != 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("nbd accepts only one host")); + return -1; + } + + virBufferAddLit(opt, "file=nbd:"); + + switch (disk->hosts->transport) { + case VIR_DOMAIN_DISK_PROTO_TRANS_TCP: + if (disk->hosts->name) + virBufferEscape(opt, ',', ",", "%s", disk->hosts->name); + virBufferEscape(opt, ',', ",", ":%s", + disk->hosts->port ? disk->hosts->port : + QEMU_DEFAULT_NBD_PORT); + break; + default: + transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("nbd does not support transport '%s'"), transp); + break; + } + + return 0; +} + char * qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainDiskDefPtr disk, @@ -2553,13 +2625,9 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) { switch (disk->protocol) { case VIR_DOMAIN_DISK_PROTOCOL_NBD: - if (disk->nhosts != 1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("NBD accepts only one host")); + if (qemuBuildNBDString(disk, &opt) < 0) goto error; - } - virBufferAsprintf(&opt, "file=nbd:%s:%s,", - disk->hosts->name, disk->hosts->port); + virBufferAddChar(&opt, ','); break; case VIR_DOMAIN_DISK_PROTOCOL_RBD: virBufferAddLit(&opt, "file="); @@ -7731,39 +7799,11 @@ qemuParseCommandLineDisk(virCapsPtr qemuCaps, if (STRPREFIX(def->src, "/dev/")) def->type = VIR_DOMAIN_DISK_TYPE_BLOCK; else if (STRPREFIX(def->src, "nbd:")) { - char *host, *port; - def->type = VIR_DOMAIN_DISK_TYPE_NETWORK; def->protocol = VIR_DOMAIN_DISK_PROTOCOL_NBD; - host = def->src + strlen("nbd:"); - port = strchr(host, ':'); - if (!port) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse nbd filename '%s'"), - def->src); - goto error; - } - *port++ = '\0'; - if (VIR_ALLOC(def->hosts) < 0) { - virReportOOMError(); - goto error; - } - def->nhosts = 1; - def->hosts->name = strdup(host); - if (!def->hosts->name) { - virReportOOMError(); - goto error; - } - def->hosts->port = strdup(port); - if (!def->hosts->port) { - virReportOOMError(); - goto error; - } - def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; - def->hosts->socket = NULL; - VIR_FREE(def->src); - def->src = NULL; + if (qemuParseNBDString(def) < 0) + goto error; } else if (STRPREFIX(def->src, "rbd:")) { char *p = def->src; @@ -8994,7 +9034,6 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps, else if (STRPREFIX(val, "nbd:")) { disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK; disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_NBD; - val += strlen("nbd:"); } else if (STRPREFIX(val, "rbd:")) { disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK; disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_RBD; @@ -9034,26 +9073,12 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps, goto no_memory; if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) { - char *host, *port; + char *port; switch (disk->protocol) { case VIR_DOMAIN_DISK_PROTOCOL_NBD: - host = disk->src; - port = strchr(host, ':'); - if (!port) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse nbd filename '%s'"), disk->src); + if (qemuParseNBDString(disk) < 0) goto error; - } - *port++ = '\0'; - if (VIR_ALLOC(disk->hosts) < 0) - goto no_memory; - disk->nhosts = 1; - disk->hosts->name = disk->src; - disk->src = NULL; - disk->hosts->port = strdup(port); - if (!disk->hosts->port) - goto no_memory; break; case VIR_DOMAIN_DISK_PROTOCOL_RBD: /* old-style CEPH_ARGS env variable is parsed later */