* [PATCH] add network disk support
@ 2010-11-25 20:49 MORITA Kazutaka
2010-12-02 13:19 ` Daniel P. Berrange
0 siblings, 1 reply; 11+ messages in thread
From: MORITA Kazutaka @ 2010-11-25 20:49 UTC (permalink / raw)
To: berrange-H+wXaHxf7aLQT0dZR+AlfA,
libvir-list-H+wXaHxf7aLQT0dZR+AlfA
Cc: ceph-devel-u79uwXL29TY76Z2rM5mHXA,
sheepdog-CJ+3F33aHDCwRfvgX43A7Q
This patch adds network disk support to libvirt/QEMU. The currently
supported protcols are nbd, rbd, and sheepdog. The XML syntax is like
this:
<disk type="network" device="disk">
<driver name="qemu" type="raw" />
<source protocol='rbd|sheepdog|nbd' name="...some image identifier...">
<host name="mon1.example.org" port="6000">
<host name="mon2.example.org" port="6000">
<host name="mon3.example.org" port="6000">
</source>
<target dev="vda" bus="virtio" />
</disk>
Signed-off-by: MORITA Kazutaka <morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
---
This patch addresses the discussion on
https://www.redhat.com/archives/libvir-list/2010-November/msg00759.html
Josh mentioned that the monitor hostnames of RBD can be set through
the environment variables, but I couldn't find any documentations
about it, so the monitors are not set in this patch. I hope someone
who is familiar with RBD implements it.
I appreciate any feedback.
Thanks,
Kazutaka
docs/schemas/domain.rng | 31 +++++++++
src/conf/domain_conf.c | 68 +++++++++++++++++--
src/conf/domain_conf.h | 20 ++++++
src/qemu/qemu_conf.c | 169 +++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 279 insertions(+), 9 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index fb44335..81f4004 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -612,6 +612,37 @@
<ref name="diskspec"/>
</interleave>
</group>
+ <group>
+ <attribute name="type">
+ <value>network</value>
+ </attribute>
+ <interleave>
+ <optional>
+ <element name="source">
+ <attribute name="protocol">
+ <choice>
+ <value>nbd</value>
+ <value>rbd</value>
+ <value>sheepdog</value>
+ </choice>
+ </attribute>
+ <attribute name="name"/>
+ <zeroOrMore>
+ <element name="host">
+ <attribute name="name">
+ <ref name="genericName"/>
+ </attribute>
+ <attribute name="port">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </element>
+ </zeroOrMore>
+ <empty/>
+ </element>
+ </optional>
+ <ref name="diskspec"/>
+ </interleave>
+ </group>
<ref name="diskspec"/>
</choice>
</element>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3f14cee..b9dbc61 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -113,7 +113,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block",
"file",
- "dir")
+ "dir",
+ "network")
VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
"disk",
@@ -142,6 +143,11 @@ VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST,
"ignore",
"enospace")
+VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
+ "nbd",
+ "rbd",
+ "sheepdog")
+
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide",
"fdc",
@@ -508,6 +514,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->serial);
VIR_FREE(def->src);
+ VIR_FREE(def->hosts);
VIR_FREE(def->dst);
VIR_FREE(def->driverName);
VIR_FREE(def->driverType);
@@ -1574,13 +1581,15 @@ virDomainDiskDefParseXML(virCapsPtr caps,
xmlNodePtr node,
int flags) {
virDomainDiskDefPtr def;
- xmlNodePtr cur;
+ xmlNodePtr cur, host;
char *type = NULL;
char *device = NULL;
char *driverName = NULL;
char *driverType = NULL;
char *source = NULL;
char *target = NULL;
+ char *protocol = NULL;
+ virDomainDiskHostDefPtr hosts = NULL;
char *bus = NULL;
char *cachetag = NULL;
char *error_policy = NULL;
@@ -1607,7 +1616,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
- if ((source == NULL) &&
+ if ((source == NULL && hosts == NULL) &&
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
switch (def->type) {
@@ -1620,6 +1629,30 @@ virDomainDiskDefParseXML(virCapsPtr caps,
case VIR_DOMAIN_DISK_TYPE_DIR:
source = virXMLPropString(cur, "dir");
break;
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
+ protocol = virXMLPropString(cur, "protocol");
+ if (protocol == NULL) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ "%s", _("missing protocol type"));
+ break;
+ }
+ def->protocol = virDomainDiskProtocolTypeFromString(protocol);
+ source = virXMLPropString(cur, "name");
+ host = cur->children;
+ while (host != NULL) {
+ if (host->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(host->name, BAD_CAST "host")) {
+ if (VIR_REALLOC_N(hosts, def->nhosts + 1) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ hosts[def->nhosts].name = virXMLPropString(host, "name");
+ hosts[def->nhosts].port = virXMLPropString(host, "port");
+ def->nhosts++;
+ }
+ host = host->next;
+ }
+ break;
default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"),
@@ -1685,7 +1718,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
/* Only CDROM and Floppy devices are allowed missing source path
* to indicate no media present */
- if (source == NULL &&
+ if (source == NULL && hosts == NULL &&
def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
virDomainReportError(VIR_ERR_NO_SOURCE,
@@ -1791,6 +1824,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
source = NULL;
def->dst = target;
target = NULL;
+ def->hosts = hosts;
+ hosts = NULL;
def->driverName = driverName;
driverName = NULL;
def->driverType = driverType;
@@ -1819,6 +1854,8 @@ cleanup:
VIR_FREE(type);
VIR_FREE(target);
VIR_FREE(source);
+ VIR_FREE(hosts);
+ VIR_FREE(protocol);
VIR_FREE(device);
VIR_FREE(driverType);
VIR_FREE(driverName);
@@ -5887,7 +5924,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferVSprintf(buf, "/>\n");
}
- if (def->src) {
+ if (def->src || def->nhosts > 0) {
switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE:
virBufferEscapeString(buf, " <source file='%s'/>\n",
@@ -5901,6 +5938,27 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " <source dir='%s'/>\n",
def->src);
break;
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
+ virBufferVSprintf(buf, " <source protocol='%s'",
+ virDomainDiskProtocolTypeToString(def->protocol));
+ if (def->src) {
+ virBufferEscapeString(buf, " name='%s'", def->src);
+ }
+ if (def->nhosts == 0) {
+ virBufferVSprintf(buf, "/>\n");
+ } else {
+ int i;
+
+ virBufferVSprintf(buf, ">\n");
+ for (i = 0; i < def->nhosts; i++) {
+ virBufferEscapeString(buf, " <host name='%s'",
+ def->hosts[i].name);
+ virBufferEscapeString(buf, " port='%s'/>\n",
+ def->hosts[i].port);
+ }
+ virBufferVSprintf(buf, " </source>\n");
+ }
+ break;
default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 899b19f..6c97289 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -120,6 +120,7 @@ enum virDomainDiskType {
VIR_DOMAIN_DISK_TYPE_BLOCK,
VIR_DOMAIN_DISK_TYPE_FILE,
VIR_DOMAIN_DISK_TYPE_DIR,
+ VIR_DOMAIN_DISK_TYPE_NETWORK,
VIR_DOMAIN_DISK_TYPE_LAST
};
@@ -164,6 +165,21 @@ enum virDomainDiskErrorPolicy {
VIR_DOMAIN_DISK_ERROR_POLICY_LAST
};
+enum virDomainDiskProtocol {
+ VIR_DOMAIN_DISK_PROTOCOL_NBD,
+ VIR_DOMAIN_DISK_PROTOCOL_RBD,
+ VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG,
+
+ VIR_DOMAIN_DISK_PROTOCOL_LAST
+};
+
+typedef struct _virDomainDiskHostDef virDomainDiskHostDef;
+typedef virDomainDiskHostDef *virDomainDiskHostDefPtr;
+struct _virDomainDiskHostDef {
+ char *name;
+ char *port;
+};
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -173,6 +189,9 @@ struct _virDomainDiskDef {
int bus;
char *src;
char *dst;
+ int protocol;
+ int nhosts;
+ virDomainDiskHostDefPtr hosts;
char *driverName;
char *driverType;
char *serial;
@@ -1237,6 +1256,7 @@ VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus)
VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
+VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModel)
VIR_ENUM_DECL(virDomainFS)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 35caccc..63abd75 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2714,7 +2714,7 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
break;
}
- if (disk->src) {
+ if (disk->src || disk->nhosts > 0) {
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
/* QEMU only supports magic FAT format for now */
if (disk->driverType &&
@@ -2733,6 +2733,24 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
else
virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
+ } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+ switch (disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ virBufferVSprintf(&opt, "file=nbd:%s:%s,",
+ disk->hosts->name, disk->hosts->port);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ virBufferVSprintf(&opt, "file=rbd:%s,", disk->src);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ if (disk->nhosts > 0)
+ virBufferVSprintf(&opt, "file=sheepdog:%s:%s:%s,",
+ disk->hosts->name, disk->hosts->port,
+ disk->src);
+ else
+ virBufferVSprintf(&opt, "file=sheepdog:%s,", disk->src);
+ break;
+ }
} else {
virBufferVSprintf(&opt, "file=%s,", disk->src);
}
@@ -4722,6 +4740,24 @@ int qemudBuildCommandLine(virConnectPtr conn,
snprintf(file, PATH_MAX, "fat:floppy:%s", disk->src);
else
snprintf(file, PATH_MAX, "fat:%s", disk->src);
+ } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+ switch (disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ snprintf(file, PATH_MAX, "nbd:%s:%s,",
+ disk->hosts->name, disk->hosts->port);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ snprintf(file, PATH_MAX, "rbd:%s,", disk->src);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ if (disk->nhosts > 0)
+ snprintf(file, PATH_MAX, "sheepdog:%s:%s:%s,",
+ disk->hosts->name, disk->hosts->port,
+ disk->src);
+ else
+ snprintf(file, PATH_MAX, "sheepdog:%s,", disk->src);
+ break;
+ }
} else {
snprintf(file, PATH_MAX, "%s", disk->src);
}
@@ -5794,7 +5830,67 @@ qemuParseCommandLineDisk(virCapsPtr caps,
values[i] = NULL;
if (STRPREFIX(def->src, "/dev/"))
def->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
- else
+ else if (STRPREFIX(def->src, "nbd:")) {
+ char *host, *port;
+
+ def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ host = def->src + strlen("nbd:");
+ port = strchr(host, ':');
+ if (!port) {
+ def = NULL;
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse nbd filename '%s'"), def->src);
+ goto cleanup;
+ }
+ *port++ = '\0';
+ if (VIR_ALLOC(def->hosts) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->nhosts = 1;
+ def->hosts->name = strdup(host);
+ def->hosts->port = strdup(port);
+
+ VIR_FREE(def->src);
+ def->src = NULL;
+ } else if (STRPREFIX(def->src, "rbd:")) {
+ char *p = def->src;
+
+ def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ def->src = strdup(p + strlen("rbd:"));
+
+ VIR_FREE(p);
+ } else if (STRPREFIX(def->src, "sheepdog:")) {
+ char *p = def->src;
+ char *port, *vdi;
+
+ def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ def->src = strdup(p + strlen("sheepdog:"));
+
+ /* def->src must be [vdiname] or [host]:[port]:[vdiname] */
+ port = strchr(def->src, ':');
+ if (port) {
+ *port++ = '\0';
+ vdi = strchr(port, ':');
+ if (!vdi) {
+ def = NULL;
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse sheepdog filename '%s'"), p);
+ goto cleanup;
+ }
+ *vdi++ = '\0';
+ if (VIR_ALLOC(def->hosts) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->nhosts = 1;
+ def->hosts->name = def->src;
+ def->hosts->port = strdup(port);
+ def->src = strdup(vdi);
+ }
+
+ VIR_FREE(p);
+ } else
def->type = VIR_DOMAIN_DISK_TYPE_FILE;
} else {
def->type = VIR_DOMAIN_DISK_TYPE_FILE;
@@ -6731,7 +6827,19 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
if (STRPREFIX(val, "/dev/"))
disk->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
- else
+ 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;
+ val += strlen("rbd:");
+ } else if (STRPREFIX(val, "sheepdog:")) {
+ disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
+ val += strlen("sheepdog:");
+ } else
disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
if (STREQ(arg, "-cdrom")) {
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
@@ -6751,7 +6859,60 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
disk->dst = strdup(arg + 1);
}
disk->src = strdup(val);
- if (!disk->src ||
+
+ if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+ char *host, *port;
+
+ switch (disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ host = disk->src;
+ port = strchr(host, ':');
+ if (!port) {
+ def = NULL;
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse nbd filename '%s'"), disk->src);
+ goto error;
+ }
+ *port++ = '\0';
+ if (VIR_ALLOC(disk->hosts) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ disk->nhosts = 1;
+ disk->hosts->name = host;
+ disk->hosts->port = strdup(port);
+ disk->src = NULL;
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ /* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
+ port = strchr(disk->src, ':');
+ if (port) {
+ char *vdi;
+
+ *port++ = '\0';
+ vdi = strchr(port, ':');
+ if (!vdi) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse sheepdog filename '%s'"), val);
+ goto error;
+ }
+ *vdi++ = '\0';
+ if (VIR_ALLOC(disk->hosts) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ disk->nhosts = 1;
+ disk->hosts->name = disk->src;
+ disk->hosts->port = strdup(port);
+ disk->src = strdup(vdi);
+ }
+ break;
+ }
+ }
+
+ if (!(disk->src || disk->nhosts > 0) ||
!disk->dst) {
virDomainDiskDefFree(disk);
goto no_memory;
--
1.7.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] add network disk support
2010-11-25 20:49 [PATCH] add network disk support MORITA Kazutaka
@ 2010-12-02 13:19 ` Daniel P. Berrange
[not found] ` <20101202131928.GV2502-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 11+ messages in thread
From: Daniel P. Berrange @ 2010-12-02 13:19 UTC (permalink / raw)
To: MORITA Kazutaka; +Cc: libvir-list, sheepdog, ceph-devel
On Fri, Nov 26, 2010 at 05:49:56AM +0900, MORITA Kazutaka wrote:
> This patch adds network disk support to libvirt/QEMU. The currently
> supported protcols are nbd, rbd, and sheepdog. The XML syntax is like
> this:
>
> <disk type="network" device="disk">
> <driver name="qemu" type="raw" />
> <source protocol='rbd|sheepdog|nbd' name="...some image identifier...">
> <host name="mon1.example.org" port="6000">
> <host name="mon2.example.org" port="6000">
> <host name="mon3.example.org" port="6000">
> </source>
> <target dev="vda" bus="virtio" />
> </disk>
This design looks good to me.
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
> ---
>
> This patch addresses the discussion on
> https://www.redhat.com/archives/libvir-list/2010-November/msg00759.html
>
> Josh mentioned that the monitor hostnames of RBD can be set through
> the environment variables, but I couldn't find any documentations
> about it, so the monitors are not set in this patch. I hope someone
> who is familiar with RBD implements it.
>
> @@ -1620,6 +1629,30 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> case VIR_DOMAIN_DISK_TYPE_DIR:
> source = virXMLPropString(cur, "dir");
> break;
> + case VIR_DOMAIN_DISK_TYPE_NETWORK:
> + protocol = virXMLPropString(cur, "protocol");
> + if (protocol == NULL) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + "%s", _("missing protocol type"));
> + break;
> + }
> + def->protocol = virDomainDiskProtocolTypeFromString(protocol);
Should check for def->protocal < 0 & raise an error, which
would indicate that 'protocol' was not one of the expected
values.
> + source = virXMLPropString(cur, "name");
> + host = cur->children;
> + while (host != NULL) {
> + if (host->type == XML_ELEMENT_NODE &&
> + xmlStrEqual(host->name, BAD_CAST "host")) {
> + if (VIR_REALLOC_N(hosts, def->nhosts + 1) < 0) {
> + virReportOOMError();
> + goto error;
> + }
> + hosts[def->nhosts].name = virXMLPropString(host, "name");
> + hosts[def->nhosts].port = virXMLPropString(host, "port");
> + def->nhosts++;
Ought to check for NULLs returned by virXMLPropString here
I think.
> + }
> + host = host->next;
> + }
> + break;
> default:
> virDomainReportError(VIR_ERR_INTERNAL_ERROR,
> _("unexpected disk type %s"),
> @@ -1685,7 +1718,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>
> /* Only CDROM and Floppy devices are allowed missing source path
> * to indicate no media present */
> - if (source == NULL &&
> + if (source == NULL && hosts == NULL &&
> def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
> def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
> virDomainReportError(VIR_ERR_NO_SOURCE,
> @@ -1791,6 +1824,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> source = NULL;
> def->dst = target;
> target = NULL;
> + def->hosts = hosts;
> + hosts = NULL;
> def->driverName = driverName;
> driverName = NULL;
> def->driverType = driverType;
> @@ -1819,6 +1854,8 @@ cleanup:
> VIR_FREE(type);
> VIR_FREE(target);
> VIR_FREE(source);
> + VIR_FREE(hosts);
I think you need to free the fields inside 'hosts' too, otherwise
we'd leak memory for the port + host strings in the error path.
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index 35caccc..63abd75 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -2714,7 +2714,7 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
> break;
> }
>
> - if (disk->src) {
> + if (disk->src || disk->nhosts > 0) {
If you check for nhosts > 0 here
> if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
> /* QEMU only supports magic FAT format for now */
> if (disk->driverType &&
> @@ -2733,6 +2733,24 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
> virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
> else
> virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
> + } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
> + switch (disk->protocol) {
> + case VIR_DOMAIN_DISK_PROTOCOL_NBD:
> + virBufferVSprintf(&opt, "file=nbd:%s:%s,",
> + disk->hosts->name, disk->hosts->port);
> + break;
> + case VIR_DOMAIN_DISK_PROTOCOL_RBD:
> + virBufferVSprintf(&opt, "file=rbd:%s,", disk->src);
> + break;
> + case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
> + if (disk->nhosts > 0)
> + virBufferVSprintf(&opt, "file=sheepdog:%s:%s:%s,",
> + disk->hosts->name, disk->hosts->port,
> + disk->src);
> + else
> + virBufferVSprintf(&opt, "file=sheepdog:%s,", disk->src);
> + break;
This else branch for sheepdog will never execute. So I think
it is better to check the nhosts value in each of these
conditionals. eg We should report an error if nhosts == 0,
or nhosts > 1 for NBD since it only wants 1 host. Likewise
for other protocols as nedeed.
> @@ -5794,7 +5830,67 @@ qemuParseCommandLineDisk(virCapsPtr caps,
> values[i] = NULL;
> if (STRPREFIX(def->src, "/dev/"))
> def->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
> - else
> + else if (STRPREFIX(def->src, "nbd:")) {
> + char *host, *port;
> +
> + def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
> + host = def->src + strlen("nbd:");
> + port = strchr(host, ':');
> + if (!port) {
> + def = NULL;
> + qemuReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot parse nbd filename '%s'"), def->src);
> + goto cleanup;
> + }
> + *port++ = '\0';
> + if (VIR_ALLOC(def->hosts) < 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> + def->nhosts = 1;
> + def->hosts->name = strdup(host);
> + def->hosts->port = strdup(port);
Should check for NULL in both of these strdup cases.
> +
> + VIR_FREE(def->src);
> + def->src = NULL;
> + } else if (STRPREFIX(def->src, "rbd:")) {
> + char *p = def->src;
> +
> + def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
> + def->src = strdup(p + strlen("rbd:"));
And this one, and a few more strdup's later in the patch.
Regards,
Daniel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2] add network disk support
[not found] ` <20101202131928.GV2502-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2010-12-06 7:24 ` MORITA Kazutaka
2010-12-07 19:54 ` [PATCH 0/2] rbd " Josh Durgin
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: MORITA Kazutaka @ 2010-12-06 7:24 UTC (permalink / raw)
To: berrange-H+wXaHxf7aLQT0dZR+AlfA,
libvir-list-H+wXaHxf7aLQT0dZR+AlfA
Cc: ceph-devel-u79uwXL29TY76Z2rM5mHXA,
sheepdog-CJ+3F33aHDCwRfvgX43A7Q
This patch adds network disk support to libvirt/QEMU. The currently
supported protocols are nbd, rbd, and sheepdog. The XML syntax is like
this:
<disk type="network" device="disk">
<driver name="qemu" type="raw" />
<source protocol='rbd|sheepdog|nbd' name="...some image identifier...">
<host name="mon1.example.org" port="6000">
<host name="mon2.example.org" port="6000">
<host name="mon3.example.org" port="6000">
</source>
<target dev="vda" bus="virtio" />
</disk>
Signed-off-by: MORITA Kazutaka <morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
---
Hi,
Thanks for your comments, Daniel. Here is a fixed version.
Changes from v1 to v2 are:
- check whether the XML input is valid or not more strictly
- fix memory leak in the error path
- add NULL check of the return value of strdup()
Thanks,
Kazutaka
docs/schemas/domain.rng | 31 +++++++
src/conf/domain_conf.c | 95 +++++++++++++++++++-
src/conf/domain_conf.h | 20 ++++
src/qemu/qemu_conf.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 358 insertions(+), 9 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 08ebefb..3b76c9f 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -612,6 +612,37 @@
<ref name="diskspec"/>
</interleave>
</group>
+ <group>
+ <attribute name="type">
+ <value>network</value>
+ </attribute>
+ <interleave>
+ <optional>
+ <element name="source">
+ <attribute name="protocol">
+ <choice>
+ <value>nbd</value>
+ <value>rbd</value>
+ <value>sheepdog</value>
+ </choice>
+ </attribute>
+ <attribute name="name"/>
+ <zeroOrMore>
+ <element name="host">
+ <attribute name="name">
+ <ref name="genericName"/>
+ </attribute>
+ <attribute name="port">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </element>
+ </zeroOrMore>
+ <empty/>
+ </element>
+ </optional>
+ <ref name="diskspec"/>
+ </interleave>
+ </group>
<ref name="diskspec"/>
</choice>
</element>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9516427..1350e22 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -112,7 +112,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block",
"file",
- "dir")
+ "dir",
+ "network")
VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
"disk",
@@ -141,6 +142,11 @@ VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST,
"ignore",
"enospace")
+VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
+ "nbd",
+ "rbd",
+ "sheepdog")
+
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide",
"fdc",
@@ -507,6 +513,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->serial);
VIR_FREE(def->src);
+ VIR_FREE(def->hosts);
VIR_FREE(def->dst);
VIR_FREE(def->driverName);
VIR_FREE(def->driverType);
@@ -1573,13 +1580,16 @@ virDomainDiskDefParseXML(virCapsPtr caps,
xmlNodePtr node,
int flags) {
virDomainDiskDefPtr def;
- xmlNodePtr cur;
+ xmlNodePtr cur, host;
char *type = NULL;
char *device = NULL;
char *driverName = NULL;
char *driverType = NULL;
char *source = NULL;
char *target = NULL;
+ char *protocol = NULL;
+ virDomainDiskHostDefPtr hosts = NULL;
+ int nhosts = 0;
char *bus = NULL;
char *cachetag = NULL;
char *error_policy = NULL;
@@ -1606,7 +1616,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
- if ((source == NULL) &&
+ if ((source == NULL && hosts == NULL) &&
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
switch (def->type) {
@@ -1619,6 +1629,49 @@ virDomainDiskDefParseXML(virCapsPtr caps,
case VIR_DOMAIN_DISK_TYPE_DIR:
source = virXMLPropString(cur, "dir");
break;
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
+ protocol = virXMLPropString(cur, "protocol");
+ if (protocol == NULL) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing protocol type"));
+ goto error;
+ }
+ def->protocol = virDomainDiskProtocolTypeFromString(protocol);
+ if (def->protocol < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown protocol type '%s'"),
+ protocol);
+ goto error;
+ }
+ source = virXMLPropString(cur, "name");
+ host = cur->children;
+ while (host != NULL) {
+ if (host->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(host->name, BAD_CAST "host")) {
+ if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ hosts[nhosts].name = NULL;
+ hosts[nhosts].port = NULL;
+ nhosts++;
+
+ hosts[nhosts - 1].name = virXMLPropString(host, "name");
+ if (!hosts[nhosts - 1].name) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing name for host"));
+ goto error;
+ }
+ hosts[nhosts - 1].port = virXMLPropString(host, "port");
+ if (!hosts[nhosts - 1].port) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing port for host"));
+ goto error;
+ }
+ }
+ host = host->next;
+ }
+ break;
default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"),
@@ -1684,7 +1737,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
/* Only CDROM and Floppy devices are allowed missing source path
* to indicate no media present */
- if (source == NULL &&
+ if (source == NULL && hosts == NULL &&
def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
virDomainReportError(VIR_ERR_NO_SOURCE,
@@ -1790,6 +1843,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
source = NULL;
def->dst = target;
target = NULL;
+ def->hosts = hosts;
+ hosts = NULL;
+ def->nhosts = nhosts;
+ nhosts = 0;
def->driverName = driverName;
driverName = NULL;
def->driverType = driverType;
@@ -1818,6 +1875,13 @@ cleanup:
VIR_FREE(type);
VIR_FREE(target);
VIR_FREE(source);
+ while (nhosts > 0) {
+ VIR_FREE(hosts[nhosts - 1].name);
+ VIR_FREE(hosts[nhosts - 1].port);
+ nhosts--;
+ }
+ VIR_FREE(hosts);
+ VIR_FREE(protocol);
VIR_FREE(device);
VIR_FREE(driverType);
VIR_FREE(driverName);
@@ -5886,7 +5950,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferVSprintf(buf, "/>\n");
}
- if (def->src) {
+ if (def->src || def->nhosts > 0) {
switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE:
virBufferEscapeString(buf, " <source file='%s'/>\n",
@@ -5900,6 +5964,27 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " <source dir='%s'/>\n",
def->src);
break;
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
+ virBufferVSprintf(buf, " <source protocol='%s'",
+ virDomainDiskProtocolTypeToString(def->protocol));
+ if (def->src) {
+ virBufferEscapeString(buf, " name='%s'", def->src);
+ }
+ if (def->nhosts == 0) {
+ virBufferVSprintf(buf, "/>\n");
+ } else {
+ int i;
+
+ virBufferVSprintf(buf, ">\n");
+ for (i = 0; i < def->nhosts; i++) {
+ virBufferEscapeString(buf, " <host name='%s'",
+ def->hosts[i].name);
+ virBufferEscapeString(buf, " port='%s'/>\n",
+ def->hosts[i].port);
+ }
+ virBufferVSprintf(buf, " </source>\n");
+ }
+ break;
default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 899b19f..6c97289 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -120,6 +120,7 @@ enum virDomainDiskType {
VIR_DOMAIN_DISK_TYPE_BLOCK,
VIR_DOMAIN_DISK_TYPE_FILE,
VIR_DOMAIN_DISK_TYPE_DIR,
+ VIR_DOMAIN_DISK_TYPE_NETWORK,
VIR_DOMAIN_DISK_TYPE_LAST
};
@@ -164,6 +165,21 @@ enum virDomainDiskErrorPolicy {
VIR_DOMAIN_DISK_ERROR_POLICY_LAST
};
+enum virDomainDiskProtocol {
+ VIR_DOMAIN_DISK_PROTOCOL_NBD,
+ VIR_DOMAIN_DISK_PROTOCOL_RBD,
+ VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG,
+
+ VIR_DOMAIN_DISK_PROTOCOL_LAST
+};
+
+typedef struct _virDomainDiskHostDef virDomainDiskHostDef;
+typedef virDomainDiskHostDef *virDomainDiskHostDefPtr;
+struct _virDomainDiskHostDef {
+ char *name;
+ char *port;
+};
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -173,6 +189,9 @@ struct _virDomainDiskDef {
int bus;
char *src;
char *dst;
+ int protocol;
+ int nhosts;
+ virDomainDiskHostDefPtr hosts;
char *driverName;
char *driverType;
char *serial;
@@ -1237,6 +1256,7 @@ VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus)
VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
+VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModel)
VIR_ENUM_DECL(virDomainFS)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 925585a..1296cef 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2726,7 +2726,9 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
break;
}
- if (disk->src) {
+ /* disk->src is NULL when we use nbd disks */
+ if (disk->src || (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
+ disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) {
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
/* QEMU only supports magic FAT format for now */
if (disk->driverType &&
@@ -2745,6 +2747,31 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
else
virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
+ } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+ switch (disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ if (disk->nhosts != 1) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("NBD accepts only one host"));
+ goto error;
+ }
+ virBufferVSprintf(&opt, "file=nbd:%s:%s,",
+ disk->hosts->name, disk->hosts->port);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ /* TODO: set monitor hostnames */
+ virBufferVSprintf(&opt, "file=rbd:%s,", disk->src);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ if (disk->nhosts == 0)
+ virBufferVSprintf(&opt, "file=sheepdog:%s,", disk->src);
+ else
+ /* only one host is supported now */
+ virBufferVSprintf(&opt, "file=sheepdog:%s:%s:%s,",
+ disk->hosts->name, disk->hosts->port,
+ disk->src);
+ break;
+ }
} else {
virBufferVSprintf(&opt, "file=%s,", disk->src);
}
@@ -4636,6 +4663,30 @@ qemudBuildCommandLine(virConnectPtr conn,
snprintf(file, PATH_MAX, "fat:floppy:%s", disk->src);
else
snprintf(file, PATH_MAX, "fat:%s", disk->src);
+ } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+ switch (disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ if (disk->nhosts != 1) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("NBD accepts only one host"));
+ goto error;
+ }
+ snprintf(file, PATH_MAX, "nbd:%s:%s,",
+ disk->hosts->name, disk->hosts->port);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ snprintf(file, PATH_MAX, "rbd:%s,", disk->src);
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ if (disk->nhosts == 0)
+ snprintf(file, PATH_MAX, "sheepdog:%s,", disk->src);
+ else
+ /* only one host is supported now */
+ snprintf(file, PATH_MAX, "sheepdog:%s:%s:%s,",
+ disk->hosts->name, disk->hosts->port,
+ disk->src);
+ break;
+ }
} else {
snprintf(file, PATH_MAX, "%s", disk->src);
}
@@ -5649,7 +5700,91 @@ qemuParseCommandLineDisk(virCapsPtr caps,
values[i] = NULL;
if (STRPREFIX(def->src, "/dev/"))
def->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
- else
+ else if (STRPREFIX(def->src, "nbd:")) {
+ char *host, *port;
+
+ def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ host = def->src + strlen("nbd:");
+ port = strchr(host, ':');
+ if (!port) {
+ def = NULL;
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse nbd filename '%s'"), def->src);
+ goto cleanup;
+ }
+ *port++ = '\0';
+ if (VIR_ALLOC(def->hosts) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->nhosts = 1;
+ def->hosts->name = strdup(host);
+ if (!def->hosts->name) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->hosts->port = strdup(port);
+ if (!def->hosts->port) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ VIR_FREE(def->src);
+ def->src = NULL;
+ } else if (STRPREFIX(def->src, "rbd:")) {
+ char *p = def->src;
+
+ def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ def->src = strdup(p + strlen("rbd:"));
+ if (!def->src) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ VIR_FREE(p);
+ } else if (STRPREFIX(def->src, "sheepdog:")) {
+ char *p = def->src;
+ char *port, *vdi;
+
+ def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ def->src = strdup(p + strlen("sheepdog:"));
+ if (!def->src) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* def->src must be [vdiname] or [host]:[port]:[vdiname] */
+ port = strchr(def->src, ':');
+ if (port) {
+ *port++ = '\0';
+ vdi = strchr(port, ':');
+ if (!vdi) {
+ def = NULL;
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse sheepdog filename '%s'"), p);
+ goto cleanup;
+ }
+ *vdi++ = '\0';
+ if (VIR_ALLOC(def->hosts) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->nhosts = 1;
+ def->hosts->name = def->src;
+ def->hosts->port = strdup(port);
+ if (!def->hosts->port) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->src = strdup(vdi);
+ if (!def->src) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ VIR_FREE(p);
+ } else
def->type = VIR_DOMAIN_DISK_TYPE_FILE;
} else {
def->type = VIR_DOMAIN_DISK_TYPE_FILE;
@@ -6586,7 +6721,19 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
if (STRPREFIX(val, "/dev/"))
disk->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
- else
+ 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;
+ val += strlen("rbd:");
+ } else if (STRPREFIX(val, "sheepdog:")) {
+ disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
+ val += strlen("sheepdog:");
+ } else
disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
if (STREQ(arg, "-cdrom")) {
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
@@ -6606,7 +6753,73 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
disk->dst = strdup(arg + 1);
}
disk->src = strdup(val);
- if (!disk->src ||
+
+ if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+ char *host, *port;
+
+ switch (disk->protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ host = disk->src;
+ port = strchr(host, ':');
+ if (!port) {
+ def = NULL;
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse nbd filename '%s'"), disk->src);
+ goto error;
+ }
+ *port++ = '\0';
+ if (VIR_ALLOC(disk->hosts) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ disk->nhosts = 1;
+ disk->hosts->name = host;
+ disk->hosts->port = strdup(port);
+ if (!disk->hosts->port) {
+ virReportOOMError();
+ goto error;
+ }
+ disk->src = NULL;
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ /* TODO: set monitor hostnames */
+ break;
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ /* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
+ port = strchr(disk->src, ':');
+ if (port) {
+ char *vdi;
+
+ *port++ = '\0';
+ vdi = strchr(port, ':');
+ if (!vdi) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse sheepdog filename '%s'"), val);
+ goto error;
+ }
+ *vdi++ = '\0';
+ if (VIR_ALLOC(disk->hosts) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ disk->nhosts = 1;
+ disk->hosts->name = disk->src;
+ disk->hosts->port = strdup(port);
+ if (!disk->hosts->port) {
+ virReportOOMError();
+ goto error;
+ }
+ disk->src = strdup(vdi);
+ if (!disk->src) {
+ virReportOOMError();
+ goto error;
+ }
+ }
+ break;
+ }
+ }
+
+ if (!(disk->src || disk->nhosts > 0) ||
!disk->dst) {
virDomainDiskDefFree(disk);
goto no_memory;
--
1.7.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 0/2] rbd network disk support
2010-12-06 7:24 ` [PATCH v2] " MORITA Kazutaka
@ 2010-12-07 19:54 ` Josh Durgin
[not found] ` <1291620249-19645-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Josh Durgin @ 2010-12-07 19:54 UTC (permalink / raw)
To: libvir-list; +Cc: ceph-devel, sheepdog
Here are patches on top of Kazutaka's v2 to add RBD support and fix
some general network disk problems. There's also a test for each type
of network disk.
Josh Durgin (2):
qemu: Add RBD support and some network disk fixes
tests: Add tests for network disks
docs/schemas/domain.rng | 11 ++-
src/conf/domain_conf.c | 25 +++-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_conf.c | 143 ++++++++++++++++++--
tests/qemuargv2xmltest.c | 3 +
.../qemuxml2argv-disk-drive-network-nbd.args | 1 +
.../qemuxml2argv-disk-drive-network-nbd.xml | 32 +++++
.../qemuxml2argv-disk-drive-network-rbd.args | 1 +
.../qemuxml2argv-disk-drive-network-rbd.xml | 34 +++++
.../qemuxml2argv-disk-drive-network-sheepdog.args | 1 +
.../qemuxml2argv-disk-drive-network-sheepdog.xml | 32 +++++
tests/qemuxml2argvtest.c | 6 +
12 files changed, 275 insertions(+), 15 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.xml
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] qemu: Add RBD support and some network disk fixes
[not found] ` <1291620249-19645-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
@ 2010-12-07 19:56 ` Josh Durgin
2010-12-09 11:10 ` [libvirt] " Daniel P. Berrange
0 siblings, 1 reply; 11+ messages in thread
From: Josh Durgin @ 2010-12-07 19:56 UTC (permalink / raw)
To: libvir-list-H+wXaHxf7aLQT0dZR+AlfA
Cc: ceph-devel-u79uwXL29TY76Z2rM5mHXA,
sheepdog-CJ+3F33aHDCwRfvgX43A7Q
Changes common to all network disks:
-Make source name optional in the domain schema, since NBD doesn't use it
-Add a hostName type to the domain schema, and use it instead of genericName, which doesn't include .
-Don't leak host names or ports
-Set the source protocol in qemuParseCommandline
Signed-off-by: Josh Durgin <joshd-L5o5AL9CYN0tUFlbccrkMA@public.gmane.org>
---
docs/schemas/domain.rng | 11 +++-
src/conf/domain_conf.c | 25 +++++++-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_conf.c | 143 ++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 165 insertions(+), 15 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 4463884..51aae14 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -626,11 +626,13 @@
<value>sheepdog</value>
</choice>
</attribute>
- <attribute name="name"/>
+ <optional>
+ <attribute name="name"/>
+ </optional>
<zeroOrMore>
<element name="host">
<attribute name="name">
- <ref name="genericName"/>
+ <ref name="hostName"/>
</attribute>
<attribute name="port">
<ref name="unsignedInt"/>
@@ -2024,6 +2026,11 @@
<param name="minInclusive">1</param>
</data>
</define>
+ <define name="hostName">
+ <data type="string">
+ <param name="pattern">[a-zA-Z0-9\.\-]+</param>
+ </data>
+ </define>
<define name="PortNumber">
<data type="short">
<param name="minInclusive">-1</param>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5e2422b..6b4320a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -508,21 +508,34 @@ void virDomainInputDefFree(virDomainInputDefPtr def)
void virDomainDiskDefFree(virDomainDiskDefPtr def)
{
+ unsigned int i;
+
if (!def)
return;
VIR_FREE(def->serial);
VIR_FREE(def->src);
- VIR_FREE(def->hosts);
VIR_FREE(def->dst);
VIR_FREE(def->driverName);
VIR_FREE(def->driverType);
virStorageEncryptionFree(def->encryption);
virDomainDeviceInfoClear(&def->info);
+ for (i = 0 ; i < def->nhosts ; i++)
+ virDomainDiskHostDefFree(&def->hosts[i]);
+
VIR_FREE(def);
}
+void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def->name);
+ VIR_FREE(def->port);
+}
+
void virDomainControllerDefFree(virDomainControllerDefPtr def)
{
if (!def)
@@ -1643,7 +1656,12 @@ virDomainDiskDefParseXML(virCapsPtr caps,
protocol);
goto error;
}
- source = virXMLPropString(cur, "name");
+ if (!(source = virXMLPropString(cur, "name")) &&
+ def->protocol != VIR_DOMAIN_DISK_PROTOCOL_NBD) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing name for disk source"));
+ goto error;
+ }
host = cur->children;
while (host != NULL) {
if (host->type == XML_ELEMENT_NODE &&
@@ -1876,8 +1894,7 @@ cleanup:
VIR_FREE(target);
VIR_FREE(source);
while (nhosts > 0) {
- VIR_FREE(hosts[nhosts - 1].name);
- VIR_FREE(hosts[nhosts - 1].port);
+ virDomainDiskHostDefFree(&hosts[nhosts - 1]);
nhosts--;
}
VIR_FREE(hosts);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6c97289..c1e39ba 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1070,6 +1070,7 @@ virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms,
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
void virDomainInputDefFree(virDomainInputDefPtr def);
void virDomainDiskDefFree(virDomainDiskDefPtr def);
+void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
void virDomainControllerDefFree(virDomainControllerDefPtr def);
void virDomainFSDefFree(virDomainFSDefPtr def);
void virDomainNetDefFree(virDomainNetDefPtr def);
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 55e193f..d1368dc 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -4010,6 +4010,8 @@ qemudBuildCommandLine(virConnectPtr conn,
int last_good_net = -1;
bool hasHwVirt = false;
virCommandPtr cmd;
+ bool has_rbd_hosts = false;
+ virBuffer rbd_hosts = VIR_BUFFER_INITIALIZER;
uname_normalize(&ut);
@@ -4550,6 +4552,7 @@ qemudBuildCommandLine(virConnectPtr conn,
int bootable = 0;
virDomainDiskDefPtr disk = def->disks[i];
int withDeviceArg = 0;
+ int j;
/* Unless we have -device, then USB disks need special
handling */
@@ -4599,6 +4602,27 @@ qemudBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, optstr);
VIR_FREE(optstr);
+ if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
+ disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
+ for (j = 0 ; j < disk->nhosts ; j++) {
+ if (!has_rbd_hosts) {
+ virBufferAddLit(&rbd_hosts, "-m ");
+ has_rbd_hosts = true;
+ } else {
+ virBufferAddLit(&rbd_hosts, ",");
+ }
+ virDomainDiskHostDefPtr host = &disk->hosts[j];
+ if (host->port) {
+ virBufferVSprintf(&rbd_hosts, "%s:%s",
+ host->name,
+ host->port);
+ } else {
+ virBufferVSprintf(&rbd_hosts, "%s",
+ host->name);
+ }
+ }
+ }
+
if (withDeviceArg) {
if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) {
virCommandAddArg(cmd, "-global");
@@ -4621,6 +4645,7 @@ qemudBuildCommandLine(virConnectPtr conn,
char dev[NAME_MAX];
char file[PATH_MAX];
virDomainDiskDefPtr disk = def->disks[i];
+ int j;
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
@@ -4684,6 +4709,23 @@ qemudBuildCommandLine(virConnectPtr conn,
break;
case VIR_DOMAIN_DISK_PROTOCOL_RBD:
snprintf(file, PATH_MAX, "rbd:%s,", disk->src);
+ for (j = 0 ; j < disk->nhosts ; j++) {
+ if (!has_rbd_hosts) {
+ virBufferAddLit(&rbd_hosts, "-m ");
+ has_rbd_hosts = true;
+ } else {
+ virBufferAddLit(&rbd_hosts, ",");
+ }
+ virDomainDiskHostDefPtr host = &disk->hosts[j];
+ if (host->port) {
+ virBufferVSprintf(&rbd_hosts, "%s:%s",
+ host->name,
+ host->port);
+ } else {
+ virBufferVSprintf(&rbd_hosts, "%s",
+ host->name);
+ }
+ }
break;
case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
if (disk->nhosts == 0)
@@ -4703,6 +4745,13 @@ qemudBuildCommandLine(virConnectPtr conn,
}
}
+ if (virBufferError(&rbd_hosts)) {
+ virBufferFreeAndReset(&rbd_hosts);
+ goto no_memory;
+ }
+ if (has_rbd_hosts)
+ virCommandAddEnvPair(cmd, "CEPH_ARGS", virBufferContentAndReset(&rbd_hosts));
+
if (qemuCmdFlags & QEMUD_CMD_FLAG_FSDEV) {
for (i = 0 ; i < def->nfss ; i++) {
char *optstr;
@@ -5468,6 +5517,7 @@ static int qemuStringToArgvEnv(const char *args,
int envend;
int i;
const char *curr = args;
+ const char *start;
const char **progenv = NULL;
const char **progargv = NULL;
@@ -5475,14 +5525,22 @@ static int qemuStringToArgvEnv(const char *args,
while (curr && *curr != '\0') {
char *arg;
const char *next;
- if (*curr == '\'') {
- curr++;
- next = strchr(curr, '\'');
- } else if (*curr == '"') {
- curr++;
- next = strchr(curr, '"');
+
+ start = curr;
+ /* accept a space in CEPH_ARGS */
+ if (STRPREFIX(curr, "CEPH_ARGS=-m ")) {
+ start += strlen("CEPH_ARGS=-m ");
+ }
+ if (*start == '\'') {
+ if (start == curr)
+ curr++;
+ next = strchr(start + 1, '\'');
+ } else if (*start == '"') {
+ if (start == curr)
+ curr++;
+ next = strchr(start + 1, '"');
} else {
- next = strchr(curr, ' ');
+ next = strchr(start, ' ');
}
if (!next)
next = strchr(curr, '\n');
@@ -5712,6 +5770,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
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) {
@@ -5743,6 +5802,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
char *p = def->src;
def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ def->protocol = VIR_DOMAIN_DISK_PROTOCOL_RBD;
def->src = strdup(p + strlen("rbd:"));
if (!def->src) {
virReportOOMError();
@@ -5755,6 +5815,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
char *port, *vdi;
def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ def->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
def->src = strdup(p + strlen("sheepdog:"));
if (!def->src) {
virReportOOMError();
@@ -5870,7 +5931,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
}
if (!def->src &&
- def->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+ def->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
+ def->type != VIR_DOMAIN_DISK_TYPE_NETWORK) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("missing file parameter in drive '%s'"), val);
virDomainDiskDefFree(def);
@@ -6790,7 +6852,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
disk->src = NULL;
break;
case VIR_DOMAIN_DISK_PROTOCOL_RBD:
- /* TODO: set monitor hostnames */
+ /* handled later since the hosts for all disks are in CEPH_ARGS */
break;
case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
/* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
@@ -7117,6 +7179,69 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
}
#undef WANT_VALUE
+ if (def->ndisks > 0) {
+ const char *ceph_args = qemuFindEnv(progenv, "CEPH_ARGS");
+ if (ceph_args) {
+ char *hosts, *port, *saveptr, *token;
+ virDomainDiskDefPtr first_rbd_disk = NULL;
+ for (i = 0 ; i < def->ndisks ; i++) {
+ virDomainDiskDefPtr disk = def->disks[i];
+ if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
+ disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
+ first_rbd_disk = disk;
+ break;
+ }
+ }
+
+ if (!first_rbd_disk) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("CEPH_ARGS was set without an rbd disk"));
+ goto error;
+ }
+
+ /* CEPH_ARGS should be: -m host1[:port1][,host2[:port2]]... */
+ if (!STRPREFIX(ceph_args, "-m ")) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not parse CEPH_ARGS '%s'"), ceph_args);
+ goto error;
+ }
+ hosts = strdup(strchr(ceph_args, ' ') + 1);
+ if (!hosts)
+ goto no_memory;
+ first_rbd_disk->nhosts = 0;
+ token = strtok_r(hosts, ",", &saveptr);
+ while (token != NULL) {
+ if (VIR_REALLOC_N(first_rbd_disk->hosts, first_rbd_disk->nhosts + 1) < 0) {
+ VIR_FREE(hosts);
+ goto no_memory;
+ }
+ port = strchr(token, ':');
+ if (port) {
+ *port++ = '\0';
+ port = strdup(port);
+ if (!port) {
+ VIR_FREE(hosts);
+ goto no_memory;
+ }
+ }
+ first_rbd_disk->hosts[first_rbd_disk->nhosts].port = port;
+ first_rbd_disk->hosts[first_rbd_disk->nhosts].name = strdup(token);
+ if (!first_rbd_disk->hosts[first_rbd_disk->nhosts].name) {
+ VIR_FREE(hosts);
+ goto no_memory;
+ }
+ first_rbd_disk->nhosts++;
+ token = strtok_r(NULL, ",", &saveptr);
+ }
+ VIR_FREE(hosts);
+
+ if (first_rbd_disk->nhosts == 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("found no rbd hosts in CEPH_ARGS '%s'"), ceph_args);
+ goto error;
+ }
+ }
+ }
if (!nographics && def->ngraphics == 0) {
virDomainGraphicsDefPtr sdl;
--
1.5.6.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/2] tests: Add tests for network disks
2010-12-06 7:24 ` [PATCH v2] " MORITA Kazutaka
2010-12-07 19:54 ` [PATCH 0/2] rbd " Josh Durgin
[not found] ` <1291620249-19645-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
@ 2010-12-07 19:57 ` Josh Durgin
2010-12-09 11:10 ` [libvirt] " Daniel P. Berrange
2010-12-09 11:09 ` [PATCH v2] add network disk support Daniel P. Berrange
3 siblings, 1 reply; 11+ messages in thread
From: Josh Durgin @ 2010-12-07 19:57 UTC (permalink / raw)
To: libvir-list; +Cc: ceph-devel, sheepdog
Signed-off-by: Josh Durgin <joshd@hq.newdream.net>
---
tests/qemuargv2xmltest.c | 3 ++
.../qemuxml2argv-disk-drive-network-nbd.args | 1 +
.../qemuxml2argv-disk-drive-network-nbd.xml | 32 ++++++++++++++++++
.../qemuxml2argv-disk-drive-network-rbd.args | 1 +
.../qemuxml2argv-disk-drive-network-rbd.xml | 34 ++++++++++++++++++++
.../qemuxml2argv-disk-drive-network-sheepdog.args | 1 +
.../qemuxml2argv-disk-drive-network-sheepdog.xml | 32 ++++++++++++++++++
tests/qemuxml2argvtest.c | 6 +++
8 files changed, 110 insertions(+), 0 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.xml
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index d941b0b..adff05a 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -173,6 +173,9 @@ mymain(int argc, char **argv)
DO_TEST("disk-drive-cache-v2-wt");
DO_TEST("disk-drive-cache-v2-wb");
DO_TEST("disk-drive-cache-v2-none");
+ DO_TEST("disk-drive-network-nbd");
+ DO_TEST("disk-drive-network-rbd");
+ DO_TEST("disk-drive-network-sheepdog");
DO_TEST("disk-usb");
DO_TEST("graphics-vnc");
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.args
new file mode 100644
index 0000000..75d74ab
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive file=nbd:example.org:6000,if=virtio,format=raw -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.xml
new file mode 100644
index 0000000..863165d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <disk type='network' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='nbd'>
+ <host name='example.org' port='6000'/>
+ </source>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args
new file mode 100644
index 0000000..7e19beb
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test CEPH_ARGS=-m mon1.example.org:6321,mon2.example.org:6322,mon3.example.org:6322 /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive file=rbd:pool/image,if=virtio,format=raw -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.xml
new file mode 100644
index 0000000..118d890
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.xml
@@ -0,0 +1,34 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <disk type='network' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='rbd' name='pool/image'>
+ <host name='mon1.example.org' port='6321'/>
+ <host name='mon2.example.org' port='6322'/>
+ <host name='mon3.example.org' port='6322'/>
+ </source>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.args
new file mode 100644
index 0000000..147378f
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive file=sheepdog:example.org:6000:image,if=virtio,format=raw -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.xml
new file mode 100644
index 0000000..5313d75
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <disk type='network' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='sheepdog' name='image'>
+ <host name='example.org' port='6000'/>
+ </source>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 5fe91f1..bb184fc 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -302,6 +302,12 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_DRIVE_FORMAT, false);
DO_TEST("disk-drive-cache-v2-none", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_DRIVE_FORMAT, false);
+ DO_TEST("disk-drive-network-nbd", QEMUD_CMD_FLAG_DRIVE |
+ QEMUD_CMD_FLAG_DRIVE_FORMAT, false);
+ DO_TEST("disk-drive-network-rbd", QEMUD_CMD_FLAG_DRIVE |
+ QEMUD_CMD_FLAG_DRIVE_FORMAT, false);
+ DO_TEST("disk-drive-network-sheepdog", QEMUD_CMD_FLAG_DRIVE |
+ QEMUD_CMD_FLAG_DRIVE_FORMAT, false);
DO_TEST("disk-usb", 0, false);
DO_TEST("disk-usb-device", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG, false);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2] add network disk support
2010-12-06 7:24 ` [PATCH v2] " MORITA Kazutaka
` (2 preceding siblings ...)
2010-12-07 19:57 ` [PATCH 2/2] tests: Add tests for network disks Josh Durgin
@ 2010-12-09 11:09 ` Daniel P. Berrange
2010-12-09 19:13 ` [libvirt] " Eric Blake
3 siblings, 1 reply; 11+ messages in thread
From: Daniel P. Berrange @ 2010-12-09 11:09 UTC (permalink / raw)
To: MORITA Kazutaka; +Cc: libvir-list, sheepdog, ceph-devel
On Mon, Dec 06, 2010 at 04:24:09PM +0900, MORITA Kazutaka wrote:
> This patch adds network disk support to libvirt/QEMU. The currently
> supported protocols are nbd, rbd, and sheepdog. The XML syntax is like
> this:
>
> <disk type="network" device="disk">
> <driver name="qemu" type="raw" />
> <source protocol='rbd|sheepdog|nbd' name="...some image identifier...">
> <host name="mon1.example.org" port="6000">
> <host name="mon2.example.org" port="6000">
> <host name="mon3.example.org" port="6000">
> </source>
> <target dev="vda" bus="virtio" />
> </disk>
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
> ---
>
> Hi,
>
> Thanks for your comments, Daniel. Here is a fixed version.
>
> Changes from v1 to v2 are:
> - check whether the XML input is valid or not more strictly
> - fix memory leak in the error path
> - add NULL check of the return value of strdup()
>
> Thanks,
>
> Kazutaka
>
>
> docs/schemas/domain.rng | 31 +++++++
> src/conf/domain_conf.c | 95 +++++++++++++++++++-
> src/conf/domain_conf.h | 20 ++++
> src/qemu/qemu_conf.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++-
> 4 files changed, 358 insertions(+), 9 deletions(-)
ACK
Daniel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [libvirt] [PATCH 1/2] qemu: Add RBD support and some network disk fixes
2010-12-07 19:56 ` [PATCH 1/2] qemu: Add RBD support and some network disk fixes Josh Durgin
@ 2010-12-09 11:10 ` Daniel P. Berrange
0 siblings, 0 replies; 11+ messages in thread
From: Daniel P. Berrange @ 2010-12-09 11:10 UTC (permalink / raw)
To: Josh Durgin; +Cc: libvir-list, ceph-devel, sheepdog
On Tue, Dec 07, 2010 at 11:56:34AM -0800, Josh Durgin wrote:
>
> Changes common to all network disks:
> -Make source name optional in the domain schema, since NBD doesn't use it
> -Add a hostName type to the domain schema, and use it instead of genericName, which doesn't include .
> -Don't leak host names or ports
> -Set the source protocol in qemuParseCommandline
>
> Signed-off-by: Josh Durgin <joshd@hq.newdream.net>
> ---
> docs/schemas/domain.rng | 11 +++-
> src/conf/domain_conf.c | 25 +++++++-
> src/conf/domain_conf.h | 1 +
> src/qemu/qemu_conf.c | 143 ++++++++++++++++++++++++++++++++++++++++++++---
> 4 files changed, 165 insertions(+), 15 deletions(-)
ACK
Daniel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [libvirt] [PATCH 2/2] tests: Add tests for network disks
2010-12-07 19:57 ` [PATCH 2/2] tests: Add tests for network disks Josh Durgin
@ 2010-12-09 11:10 ` Daniel P. Berrange
0 siblings, 0 replies; 11+ messages in thread
From: Daniel P. Berrange @ 2010-12-09 11:10 UTC (permalink / raw)
To: Josh Durgin; +Cc: libvir-list, ceph-devel, sheepdog
On Tue, Dec 07, 2010 at 11:57:33AM -0800, Josh Durgin wrote:
>
> Signed-off-by: Josh Durgin <joshd@hq.newdream.net>
> ---
> tests/qemuargv2xmltest.c | 3 ++
> .../qemuxml2argv-disk-drive-network-nbd.args | 1 +
> .../qemuxml2argv-disk-drive-network-nbd.xml | 32 ++++++++++++++++++
> .../qemuxml2argv-disk-drive-network-rbd.args | 1 +
> .../qemuxml2argv-disk-drive-network-rbd.xml | 34 ++++++++++++++++++++
> .../qemuxml2argv-disk-drive-network-sheepdog.args | 1 +
> .../qemuxml2argv-disk-drive-network-sheepdog.xml | 32 ++++++++++++++++++
> tests/qemuxml2argvtest.c | 6 +++
> 8 files changed, 110 insertions(+), 0 deletions(-)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd.xml
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.xml
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-sheepdog.xml
ACK
Daniel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [libvirt] [PATCH v2] add network disk support
2010-12-09 11:09 ` [PATCH v2] add network disk support Daniel P. Berrange
@ 2010-12-09 19:13 ` Eric Blake
2010-12-09 21:31 ` Eric Blake
0 siblings, 1 reply; 11+ messages in thread
From: Eric Blake @ 2010-12-09 19:13 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: MORITA Kazutaka, libvir-list, ceph-devel, sheepdog
[-- Attachment #1: Type: text/plain, Size: 1628 bytes --]
On 12/09/2010 04:09 AM, Daniel P. Berrange wrote:
> On Mon, Dec 06, 2010 at 04:24:09PM +0900, MORITA Kazutaka wrote:
>> This patch adds network disk support to libvirt/QEMU. The currently
>> supported protocols are nbd, rbd, and sheepdog. The XML syntax is like
>> this:
>>
>> <disk type="network" device="disk">
>> <driver name="qemu" type="raw" />
>> <source protocol='rbd|sheepdog|nbd' name="...some image identifier...">
>> <host name="mon1.example.org" port="6000">
>> <host name="mon2.example.org" port="6000">
>> <host name="mon3.example.org" port="6000">
>> </source>
>> <target dev="vda" bus="virtio" />
>> </disk>
>>
>> docs/schemas/domain.rng | 31 +++++++
Hmm; missing a corresponding update to docs/formatdomain.html.in to
document the new XML.
> ACK
NACK. After applying this patch, I get 'make check' failures:
TEST: vmx2xmltest
/bin/sh: line 5: 15285 Segmentation fault (core dumped)
abs_top_builddir=`cd '..'; pwd` abs_top_srcdir=`cd '..'; pwd`
abs_builddir=`cd '.'; pwd` abs_srcdir=`cd '.'; pwd` CONFIG_HEADER="`cd
'..'; pwd`/config.h"
PATH="$abs_top_builddir/src:$abs_top_builddir/daemon:$abs_top_builddir/tools:$PATH"
SHELL="/bin/sh"
LIBVIRT_DRIVER_DIR="/home/remote/eblake/libvirt/src/.libs" LC_ALL=C
${dir}$tst
FAIL: vmx2xmltest
TEST: xml2vmxtest
...!!!!!!!!!!...............!!!!!!!!!.. 39 FAIL
I haven't looked into root cause. Kazutaka, would you mind preparing a v3?
--
Eric Blake eblake@redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [libvirt] [PATCH v2] add network disk support
2010-12-09 19:13 ` [libvirt] " Eric Blake
@ 2010-12-09 21:31 ` Eric Blake
0 siblings, 0 replies; 11+ messages in thread
From: Eric Blake @ 2010-12-09 21:31 UTC (permalink / raw)
Cc: Daniel P. Berrange, libvir-list, ceph-devel, sheepdog,
MORITA Kazutaka
[-- Attachment #1: Type: text/plain, Size: 1121 bytes --]
On 12/09/2010 12:13 PM, Eric Blake wrote:
> On 12/09/2010 04:09 AM, Daniel P. Berrange wrote:
>> On Mon, Dec 06, 2010 at 04:24:09PM +0900, MORITA Kazutaka wrote:
>>> This patch adds network disk support to libvirt/QEMU. The currently
>>> supported protocols are nbd, rbd, and sheepdog. The XML syntax is like
>>> this:
>>>
>
>> ACK
>
> NACK. After applying this patch, I get 'make check' failures:
>
> TEST: vmx2xmltest
> /bin/sh: line 5: 15285 Segmentation fault (core dumped)
Weird. After 'make clean', I was no longer able to reproduce the
failure; I then did a complete fresh checkout to verify on a pristine
tree. I must have had some bad cruft lying around in my tree, and
wonder what it was about your patch to expose that cruft?
At any rate, given that your patch does not fail after all, I will go
ahead and push it. However, we still need a follow-up patch:
> Hmm; missing a corresponding update to docs/formatdomain.html.in to
> document the new XML.
--
Eric Blake eblake@redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-12-09 21:31 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-25 20:49 [PATCH] add network disk support MORITA Kazutaka
2010-12-02 13:19 ` Daniel P. Berrange
[not found] ` <20101202131928.GV2502-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-12-06 7:24 ` [PATCH v2] " MORITA Kazutaka
2010-12-07 19:54 ` [PATCH 0/2] rbd " Josh Durgin
[not found] ` <1291620249-19645-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2010-12-07 19:56 ` [PATCH 1/2] qemu: Add RBD support and some network disk fixes Josh Durgin
2010-12-09 11:10 ` [libvirt] " Daniel P. Berrange
2010-12-07 19:57 ` [PATCH 2/2] tests: Add tests for network disks Josh Durgin
2010-12-09 11:10 ` [libvirt] " Daniel P. Berrange
2010-12-09 11:09 ` [PATCH v2] add network disk support Daniel P. Berrange
2010-12-09 19:13 ` [libvirt] " Eric Blake
2010-12-09 21:31 ` Eric Blake
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.