From a2d2b80fbd29dec4da31ec4072b6b555fe93d2c0 Mon Sep 17 00:00:00 2001 From: Harsh Prateek Bora Date: Thu, 22 Nov 2012 23:40:38 +0530 Subject: [PATCH] Add Gluster protocol as supported network disk backend This patch introduces the RNG schema and updates necessary data strucutures to allow various hypervisors to make use of Gluster protocol as one of the supported network disk backend. Next patch will add support to make use of this feature in Qemu since it now supports Gluster protocol as one of the network based storage backend. Two new optional attributes for element are introduced - 'transport' and 'socket'. Valid transport values are tcp, unix or rdma. If none specified, tcp is assumed. If transport is unix, socket specifies path to unix socket. This patch allows users to specify disks on gluster backends like this: Signed-off-by: Harsh Prateek Bora --- docs/formatdomain.html.in | 24 +++++++---- docs/schemas/domaincommon.rng | 33 ++++++++++++--- src/conf/domain_conf.c | 77 +++++++++++++++++++++++++++++------ src/conf/domain_conf.h | 12 ++++++ src/libvirt_private.syms | 2 + src/qemu/qemu_command.c | 11 +++++ 6 files changed, 133 insertions(+), 26 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 6a3b976f6b..0574e68d53 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1427,10 +1427,10 @@ to the directory to use as the disk. If the disk type is "network", then the protocol attribute specifies the protocol to access to the requested image; possible values - are "nbd", "rbd", and "sheepdog". If the protocol - attribute is "rbd" or "sheepdog", an additional - attribute name is mandatory to specify which - image will be used. When the disk type is + are "nbd", "rbd", "sheepdog" or "gluster". If the + protocol attribute is "rbd", "sheepdog" or "gluster", an + additional attribute name is mandatory to specify which + volume/image will be used. When the disk type is "network", the source may have zero or more host sub-elements used to specify the hosts to connect. @@ -1658,9 +1658,11 @@ Since 0.10.1
host
-
The host element has two attributes "name" and "port", - which specify the hostname and the port number. The meaning of this - element and the number of the elements depend on the protocol attribute. +
The host element supports 4 attributes, viz. "name", + "port", "transport" and "socket", which specify the hostname, the port + number, transport type and path to socket, respectively. The meaning + of this element and the number of the elements depend on the protocol + attribute. @@ -1682,7 +1684,15 @@ + + + + +
Protocol one of the sheepdog servers (default is localhost:7000) zero or one
gluster a server running glusterd daemon only one
+ In case of gluster, valid values for transport attribute are tcp, rdma + or unix. If nothing is specified, tcp is assumed. If transport is unix, + socket attribute specifies path to unix socket.
address
If present, the address element ties the disk diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 02ad47713b..0e85739989 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1048,6 +1048,7 @@ nbd rbd sheepdog + gluster @@ -1055,12 +1056,32 @@ - - - - - - + + + + + + tcp + rdma + + + + + + + + + + + + + unix + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ed8b53f81e..2ca608f8d8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -225,7 +225,13 @@ VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST, VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST, "nbd", "rbd", - "sheepdog") + "sheepdog", + "gluster") + +VIR_ENUM_IMPL(virDomainDiskProtocolTransport, VIR_DOMAIN_DISK_PROTO_TRANS_LAST, + "tcp", + "unix", + "rdma") VIR_ENUM_IMPL(virDomainDiskSecretType, VIR_DOMAIN_DISK_SECRET_TYPE_LAST, "none", @@ -1004,6 +1010,7 @@ void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def) VIR_FREE(def->name); VIR_FREE(def->port); + VIR_FREE(def->socket); } void virDomainControllerDefFree(virDomainControllerDefPtr def) @@ -3520,6 +3527,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, char *source = NULL; char *target = NULL; char *protocol = NULL; + char *protocol_transport = NULL; char *trans = NULL; virDomainDiskHostDefPtr hosts = NULL; int nhosts = 0; @@ -3626,20 +3634,50 @@ virDomainDiskDefParseXML(virCapsPtr caps, } hosts[nhosts].name = NULL; hosts[nhosts].port = NULL; + hosts[nhosts].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; + hosts[nhosts].socket = NULL; nhosts++; - hosts[nhosts - 1].name = virXMLPropString(child, "name"); - if (!hosts[nhosts - 1].name) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing name for host")); + /* transport can be tcp (default), unix or rdma. */ + protocol_transport = virXMLPropString(child, "transport"); + if (protocol_transport != NULL) { + hosts[nhosts - 1].transport = virDomainDiskProtocolTransportTypeFromString(protocol_transport); + if (hosts[nhosts - 1].transport < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown protocol transport type '%s'"), + protocol_transport); + goto error; + } + } + hosts[nhosts - 1].socket = virXMLPropString(child, "socket"); + if (hosts[nhosts - 1].transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX && + hosts[nhosts - 1].socket == NULL) { + virReportError(VIR_ERR_XML_ERROR, + "%s", _("missing socket for unix transport")); goto error; } - hosts[nhosts - 1].port = virXMLPropString(child, "port"); - if (!hosts[nhosts - 1].port) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing port for host")); + if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX && + hosts[nhosts - 1].socket != NULL) { + virReportError(VIR_ERR_XML_ERROR, + _("transport %s does not support socket attribute"), + protocol_transport); goto error; } + VIR_FREE(protocol_transport); + if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX) { + hosts[nhosts - 1].name = virXMLPropString(child, "name"); + if (!hosts[nhosts - 1].name) { + virReportError(VIR_ERR_XML_ERROR, + "%s", _("missing name for host")); + goto error; + } + hosts[nhosts - 1].port = virXMLPropString(child, "port"); + if (!hosts[nhosts - 1].port) { + virReportError(VIR_ERR_XML_ERROR, + "%s", _("missing port for host")); + goto error; + } + } } child = child->next; } @@ -4230,6 +4268,7 @@ cleanup: } VIR_FREE(hosts); VIR_FREE(protocol); + VIR_FREE(protocol_transport); VIR_FREE(device); VIR_FREE(authUsername); VIR_FREE(usageType); @@ -11997,10 +12036,22 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAddLit(buf, ">\n"); for (i = 0; i < def->nhosts; i++) { - virBufferEscapeString(buf, " hosts[i].name); - virBufferEscapeString(buf, " port='%s'/>\n", - def->hosts[i].port); + virBufferAddLit(buf, " hosts[i].name) { + virBufferEscapeString(buf, " name='%s'", def->hosts[i].name); + } + if (def->hosts[i].port) { + virBufferEscapeString(buf, " port='%s'", + def->hosts[i].port); + } + if (def->hosts[i].transport) { + virBufferAsprintf(buf, " transport='%s'", + virDomainDiskProtocolTransportTypeToString(def->hosts[i].transport)); + } + if (def->hosts[i].socket) { + virBufferEscapeString(buf, " socket='%s'", def->hosts[i].socket); + } + virBufferAddLit(buf, "/>\n"); } virBufferAddLit(buf, " \n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c3e8c1604e..4ab15e9c23 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -461,10 +461,19 @@ enum virDomainDiskProtocol { VIR_DOMAIN_DISK_PROTOCOL_NBD, VIR_DOMAIN_DISK_PROTOCOL_RBD, VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG, + VIR_DOMAIN_DISK_PROTOCOL_GLUSTER, VIR_DOMAIN_DISK_PROTOCOL_LAST }; +enum virDomainDiskProtocolTransport { + VIR_DOMAIN_DISK_PROTO_TRANS_TCP, + VIR_DOMAIN_DISK_PROTO_TRANS_UNIX, + VIR_DOMAIN_DISK_PROTO_TRANS_RDMA, + + VIR_DOMAIN_DISK_PROTO_TRANS_LAST +}; + enum virDomainDiskTray { VIR_DOMAIN_DISK_TRAY_CLOSED, VIR_DOMAIN_DISK_TRAY_OPEN, @@ -486,6 +495,8 @@ typedef virDomainDiskHostDef *virDomainDiskHostDefPtr; struct _virDomainDiskHostDef { char *name; char *port; + int transport; /* enum virDomainDiskProtocolTransport */ + char *socket; /* path to unix socket */ }; enum virDomainDiskIo { @@ -2196,6 +2207,7 @@ VIR_ENUM_DECL(virDomainDiskBus) VIR_ENUM_DECL(virDomainDiskCache) VIR_ENUM_DECL(virDomainDiskErrorPolicy) VIR_ENUM_DECL(virDomainDiskProtocol) +VIR_ENUM_DECL(virDomainDiskProtocolTransport) VIR_ENUM_DECL(virDomainDiskIo) VIR_ENUM_DECL(virDomainDiskSecretType) VIR_ENUM_DECL(virDomainDiskTray) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0115db184a..886347cfa3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -352,6 +352,8 @@ virDomainDiskInsertPreAlloced; virDomainDiskIoTypeFromString; virDomainDiskIoTypeToString; virDomainDiskPathByName; +virDomainDiskProtocolTransportTypeFromString; +virDomainDiskProtocolTransportTypeToString; virDomainDiskRemove; virDomainDiskRemoveByName; virDomainDiskTypeFromString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 03716d42ea..8af42256cf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1955,6 +1955,10 @@ static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport) disk->hosts[disk->nhosts-1].name = strdup(hostport); if (!disk->hosts[disk->nhosts-1].name) goto no_memory; + + disk->hosts[disk->nhosts-1].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; + disk->hosts[disk->nhosts-1].socket = NULL; + return 0; no_memory: @@ -7050,6 +7054,8 @@ qemuParseCommandLineDisk(virCapsPtr caps, virReportOOMError(); goto cleanup; } + def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; + def->hosts->socket = NULL; VIR_FREE(def->src); def->src = NULL; @@ -7103,6 +7109,8 @@ qemuParseCommandLineDisk(virCapsPtr caps, virReportOOMError(); goto cleanup; } + def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; + def->hosts->socket = NULL; def->src = strdup(vdi); if (!def->src) { virReportOOMError(); @@ -8835,6 +8843,9 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, VIR_FREE(hosts); goto no_memory; } + first_rbd_disk->hosts[first_rbd_disk->nhosts].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; + first_rbd_disk->hosts[first_rbd_disk->nhosts].socket = NULL; + first_rbd_disk->nhosts++; token = strtok_r(NULL, ",", &saveptr); }