]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add Gluster protocol as supported network disk backend
authorHarsh Prateek Bora <harsh@linux.vnet.ibm.com>
Thu, 22 Nov 2012 18:10:38 +0000 (23:40 +0530)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 27 Nov 2012 09:19:22 +0000 (10:19 +0100)
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 <host> 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:

    <disk type='network' device='disk'>
      <driver name='qemu' type='raw'/>
      <source protocol='gluster' name='Volume1/image'>
        <host name='example.org' port='6000' transport='tcp'/>
      </source>
      <target dev='vda' bus='virtio'/>
    </disk>

    <disk type='network' device='disk'>
      <driver name='qemu' type='raw'/>
      <source protocol='gluster' name='Volume2/image'>
        <host transport='unix' socket='/path/to/sock'/>
      </source>
      <target dev='vdb' bus='virtio'/>
    </disk>

Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_command.c

index 6a3b976f6b5803414e27bdc7be876244747a5ae8..0574e68d5313370f692221ead75550b44e746714 100644 (file)
         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
index 02ad47713ba4790c0dadd63c95cbda32eb4f3ad9..0e85739989ba26c86d49a0507edf4b32ebf16567 100644 (file)
                     <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/>
index ed8b53f81e471ede22c607ee1c0425a1c2b3bce9..2ca608f8d83192ccc089db0a3ac8ec9e5fd8e6cd 100644 (file)
@@ -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, "        <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");
             }
index c3e8c1604e2ad7b0ddc32602bb31d02da1766a7f..4ab15e9c23a3e95f85f32d204d2fcd7ed3a2e8ef 100644 (file)
@@ -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)
index 0115db184a189952bef9c6f6eb59da159b9f8c55..886347cfa3074000a42c94702807e6968efaf5c7 100644 (file)
@@ -352,6 +352,8 @@ virDomainDiskInsertPreAlloced;
 virDomainDiskIoTypeFromString;
 virDomainDiskIoTypeToString;
 virDomainDiskPathByName;
+virDomainDiskProtocolTransportTypeFromString;
+virDomainDiskProtocolTransportTypeToString;
 virDomainDiskRemove;
 virDomainDiskRemoveByName;
 virDomainDiskTypeFromString;
index 03716d42ea5c62023dc34a787715d1326aa02ea7..8af42256cfabfa4c13c92a0034391d14f810cb72 100644 (file)
@@ -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);
         }