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.
| Protocol |
@@ -1682,7 +1684,15 @@
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);
}