to the directory to use as the disk. If the disk <code>type</code>
is "network", then the <code>protocol</code> attribute specifies
the protocol to access to the requested image; possible values
- are "nbd", "rbd", and "sheepdog". If the <code>protocol</code>
- attribute is "rbd" or "sheepdog", an additional
- attribute <code>name</code> is mandatory to specify which
- image will be used. When the disk <code>type</code> is
+ are "nbd", "rbd", "sheepdog" or "gluster". If the
+ <code>protocol</code> attribute is "rbd", "sheepdog" or "gluster", an
+ additional attribute <code>name</code> is mandatory to specify which
+ volume/image will be used. When the disk <code>type</code> is
"network", the <code>source</code> may have zero or
more <code>host</code> sub-elements used to specify the hosts
to connect.
<span class='since'>Since 0.10.1</span>
</dd>
<dt><code>host</code></dt>
- <dd>The <code>host</code> 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.
+ <dd>The <code>host</code> 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.
<table class="top_table">
<tr>
<th> Protocol </th>
<td> one of the sheepdog servers (default is localhost:7000) </td>
<td> zero or one </td>
</tr>
+ <tr>
+ <td> gluster </td>
+ <td> a server running glusterd daemon </td>
+ <td> only one </td>
+ </tr>
</table>
+ 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.
</dd>
<dt><code>address</code></dt>
<dd>If present, the <code>address</code> element ties the disk
<value>nbd</value>
<value>rbd</value>
<value>sheepdog</value>
+ <value>gluster</value>
</choice>
</attribute>
<optional>
</optional>
<zeroOrMore>
<element name="host">
- <attribute name="name">
- <ref name="dnsName"/>
- </attribute>
- <attribute name="port">
- <ref name="unsignedInt"/>
- </attribute>
+ <choice>
+ <group>
+ <optional>
+ <attribute name="transport">
+ <choice>
+ <value>tcp</value>
+ <value>rdma</value>
+ </choice>
+ </attribute>
+ </optional>
+ <attribute name="name">
+ <ref name="dnsName"/>
+ </attribute>
+ <attribute name="port">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </group>
+ <group>
+ <attribute name="transport">
+ <value>unix</value>
+ </attribute>
+ <attribute name="socket">
+ <ref name="absFilePath"/>
+ </attribute>
+ </group>
+ </choice>
</element>
</zeroOrMore>
<empty/>
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",
VIR_FREE(def->name);
VIR_FREE(def->port);
+ VIR_FREE(def->socket);
}
void virDomainControllerDefFree(virDomainControllerDefPtr def)
char *source = NULL;
char *target = NULL;
char *protocol = NULL;
+ char *protocol_transport = NULL;
char *trans = NULL;
virDomainDiskHostDefPtr hosts = NULL;
int nhosts = 0;
}
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;
}
}
VIR_FREE(hosts);
VIR_FREE(protocol);
+ VIR_FREE(protocol_transport);
VIR_FREE(device);
VIR_FREE(authUsername);
VIR_FREE(usageType);
virBufferAddLit(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);
+ virBufferAddLit(buf, " <host");
+ if (def->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, " </source>\n");
}
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,
struct _virDomainDiskHostDef {
char *name;
char *port;
+ int transport; /* enum virDomainDiskProtocolTransport */
+ char *socket; /* path to unix socket */
};
enum virDomainDiskIo {
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)
virDomainDiskIoTypeFromString;
virDomainDiskIoTypeToString;
virDomainDiskPathByName;
+virDomainDiskProtocolTransportTypeFromString;
+virDomainDiskProtocolTransportTypeToString;
virDomainDiskRemove;
virDomainDiskRemoveByName;
virDomainDiskTypeFromString;
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:
virReportOOMError();
goto cleanup;
}
+ def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
+ def->hosts->socket = NULL;
VIR_FREE(def->src);
def->src = NULL;
virReportOOMError();
goto cleanup;
}
+ def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
+ def->hosts->socket = NULL;
def->src = strdup(vdi);
if (!def->src) {
virReportOOMError();
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);
}