[libvirt] [PATCH v2] Add support for Veritas HyperScale (VxHS) block device protocol

Ashish Mittal ashmit602 at gmail.com
Thu Jan 12 03:08:37 UTC 2017


Sample XML for a vxhs vdisk is as follows:

<disk type='network' device='disk'>
  <driver name='qemu' type='raw' cache='none'/>
  <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc251'>
    <host name='192.168.0.1' port='9999'/>
  </source>
  <backingStore/>
  <target dev='vda' bus='virtio'/>
  <serial>eb90327c-8302-4725-9e1b-4e85ed4dc251</serial>
  <alias name='virtio-disk0'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
function='0x0'/>
</disk>

Signed-off-by: Ashish Mittal <Ashish.Mittal at veritas.com>
---
v2 changelog:
(1) Added code for JSON parsing of a VxHS vdisk.
(2) Added test case to verify JSON parsing.
(3) Added missing switch-case checks for VIR_STORAGE_NET_PROTOCOL_VXHS.
(4) Fixed line wrap in qemuxml2argv-disk-drive-network-vxhs.args.

 docs/formatdomain.html.in                          | 15 ++++--
 docs/schemas/domaincommon.rng                      |  1 +
 src/libxl/libxl_conf.c                             |  1 +
 src/qemu/qemu_command.c                            |  4 ++
 src/qemu/qemu_driver.c                             |  3 ++
 src/qemu/qemu_parse_command.c                      | 25 +++++++++
 src/util/virstoragefile.c                          | 63 +++++++++++++++++++++-
 src/util/virstoragefile.h                          |  1 +
 src/xenconfig/xen_xl.c                             |  1 +
 .../qemuxml2argv-disk-drive-network-vxhs.args      | 24 +++++++++
 .../qemuxml2argv-disk-drive-network-vxhs.xml       | 34 ++++++++++++
 tests/qemuxml2argvtest.c                           |  1 +
 tests/virstoragetest.c                             | 16 ++++++
 13 files changed, 185 insertions(+), 4 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f7bef51..2a071c9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2319,9 +2319,9 @@
               <dd>
               The <code>protocol</code> attribute specifies the protocol to
               access to the requested image. Possible values are "nbd",
-              "iscsi", "rbd", "sheepdog" or "gluster".  If the
-              <code>protocol</code> attribute is "rbd", "sheepdog" or
-              "gluster", an additional attribute <code>name</code> is
+              "iscsi", "rbd", "sheepdog", "gluster" or "vxhs".  If the
+              <code>protocol</code> attribute is "rbd", "sheepdog", "gluster"
+              or "vxhs", an additional attribute <code>name</code> is
               mandatory to specify which volume/image will be used. For "nbd",
               the <code>name</code> attribute is optional. For "iscsi"
               (<span class="since">since 1.0.4</span>), the <code>name</code>
@@ -2329,6 +2329,9 @@
               target's name by a slash (e.g.,
               <code>iqn.2013-07.com.example:iscsi-pool/1</code>). If not
               specified, the default LUN is zero.
+              For "vxhs" (<span class="since">since 2.5.0</span>), the
+              <code>name</code> is the UUID of the volume, assigned by the
+              HyperScale sever.
               <span class="since">Since 0.8.7</span>
               </dd>
             <dt><code>volume</code></dt>
@@ -2431,6 +2434,12 @@
                 <td> one or more (<span class="since">Since 2.1.0</span>), just one prior to that </td>
                 <td> 24007 </td>
               </tr>
+              <tr>
+                <td> vxhs </td>
+                <td> a server running Veritas HyperScale daemon </td>
+                <td> only one </td>
+                <td> 9999 </td>
+              </tr>
             </table>
             <p>
             gluster supports "tcp", "rdma", "unix" as valid values for the
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4d76315..cdc39ca 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1470,6 +1470,7 @@
             <value>ftp</value>
             <value>ftps</value>
             <value>tftp</value>
+            <value>vxhs</value>
           </choice>
         </attribute>
         <optional>
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index b569dda..7e12d32 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -604,6 +604,7 @@ libxlMakeNetworkDiskSrcStr(virStorageSourcePtr src,
     case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
     case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
     case VIR_STORAGE_NET_PROTOCOL_SSH:
+    case VIR_STORAGE_NET_PROTOCOL_VXHS:
     case VIR_STORAGE_NET_PROTOCOL_LAST:
     case VIR_STORAGE_NET_PROTOCOL_NONE:
         virReportError(VIR_ERR_NO_SUPPORT,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f8e48d2..1a52f12 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -491,6 +491,9 @@ qemuNetworkDriveGetPort(int protocol,
             /* no default port specified */
             return 0;
 
+        case VIR_STORAGE_NET_PROTOCOL_VXHS:
+            return 9999;
+
         case VIR_STORAGE_NET_PROTOCOL_RBD:
         case VIR_STORAGE_NET_PROTOCOL_LAST:
         case VIR_STORAGE_NET_PROTOCOL_NONE:
@@ -1034,6 +1037,7 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
         case VIR_STORAGE_NET_PROTOCOL_TFTP:
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
         case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
+        case VIR_STORAGE_NET_PROTOCOL_VXHS:
             ret = qemuBuildNetworkDriveURI(src, secinfo);
             break;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b359e77..c76e9d4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13788,6 +13788,7 @@ qemuDomainSnapshotPrepareDiskExternalBackingInactive(virDomainDiskDefPtr disk)
         case VIR_STORAGE_NET_PROTOCOL_FTPS:
         case VIR_STORAGE_NET_PROTOCOL_TFTP:
         case VIR_STORAGE_NET_PROTOCOL_SSH:
+        case VIR_STORAGE_NET_PROTOCOL_VXHS:
         case VIR_STORAGE_NET_PROTOCOL_LAST:
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("external inactive snapshots are not supported on "
@@ -13851,6 +13852,7 @@ qemuDomainSnapshotPrepareDiskExternalOverlayActive(virDomainSnapshotDiskDefPtr d
         case VIR_STORAGE_NET_PROTOCOL_FTPS:
         case VIR_STORAGE_NET_PROTOCOL_TFTP:
         case VIR_STORAGE_NET_PROTOCOL_SSH:
+        case VIR_STORAGE_NET_PROTOCOL_VXHS:
         case VIR_STORAGE_NET_PROTOCOL_LAST:
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("external active snapshots are not supported on "
@@ -13996,6 +13998,7 @@ qemuDomainSnapshotPrepareDiskInternal(virConnectPtr conn,
         case VIR_STORAGE_NET_PROTOCOL_FTPS:
         case VIR_STORAGE_NET_PROTOCOL_TFTP:
         case VIR_STORAGE_NET_PROTOCOL_SSH:
+        case VIR_STORAGE_NET_PROTOCOL_VXHS:
         case VIR_STORAGE_NET_PROTOCOL_LAST:
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("internal inactive snapshots are not supported on "
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index 405e655..150e011 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -263,6 +263,16 @@ qemuParseNBDString(virDomainDiskDefPtr disk)
     return -1;
 }
 
+static int
+qemuParseVxHSString(virDomainDiskDefPtr def)
+{
+    virURIPtr uri = NULL;
+
+    if (!(uri = virURIParse(def->src->path)))
+        return -1;
+
+    return qemuParseDriveURIString(def, uri, "vxhs");
+}
 
 /*
  * This method takes a string representing a QEMU command line ARGV set
@@ -737,6 +747,12 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
                         if (VIR_STRDUP(def->src->path, vdi) < 0)
                             goto error;
                     }
+                } else if (STRPREFIX(def->src->path, "vxhs:")) {
+                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
+                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_VXHS;
+
+                    if (qemuParseVxHSString(def) < 0)
+                        goto error;
                 } else {
                     def->src->type = VIR_STORAGE_TYPE_FILE;
                 }
@@ -1947,6 +1963,10 @@ qemuParseCommandLine(virCapsPtr caps,
                 disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                 disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG;
                 val += strlen("sheepdog:");
+            } else if (STRPREFIX(val, "vxhs:")) {
+                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
+                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_VXHS;
+                val += strlen("vxhs:");
             } else {
                 disk->src->type = VIR_STORAGE_TYPE_FILE;
             }
@@ -2023,6 +2043,11 @@ qemuParseCommandLine(virCapsPtr caps,
                         goto error;
 
                     break;
+                case VIR_STORAGE_NET_PROTOCOL_VXHS:
+                    if (qemuParseVxHSString(disk) < 0)
+                        goto error;
+
+                    break;
                 case VIR_STORAGE_NET_PROTOCOL_HTTP:
                 case VIR_STORAGE_NET_PROTOCOL_HTTPS:
                 case VIR_STORAGE_NET_PROTOCOL_FTP:
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index ce6d213..e62f4e6 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -85,7 +85,8 @@ VIR_ENUM_IMPL(virStorageNetProtocol, VIR_STORAGE_NET_PROTOCOL_LAST,
               "ftp",
               "ftps",
               "tftp",
-              "ssh")
+              "ssh",
+              "vxhs")
 
 VIR_ENUM_IMPL(virStorageNetHostTransport, VIR_STORAGE_NET_HOST_TRANS_LAST,
               "tcp",
@@ -2633,6 +2634,7 @@ virStorageSourceParseBackingColon(virStorageSourcePtr src,
     case VIR_STORAGE_NET_PROTOCOL_ISCSI:
     case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
     case VIR_STORAGE_NET_PROTOCOL_SSH:
+    case VIR_STORAGE_NET_PROTOCOL_VXHS:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("malformed backing store path for protocol %s"),
                        protocol);
@@ -2964,6 +2966,64 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
 }
 
 
+static int
+virStorageSourceParseBackingJSONVXHS(virStorageSourcePtr src,
+                                    virJSONValuePtr json,
+                                    int opaque ATTRIBUTE_UNUSED)
+{
+    virJSONValuePtr server;
+    const char *hostname, *port;
+    const char *uri = virJSONValueObjectGetString(json, "filename");
+    const char *vdisk_id = virJSONValueObjectGetString(json, "vdisk-id");
+
+    src->type = VIR_STORAGE_TYPE_NETWORK;
+    src->protocol = VIR_STORAGE_NET_PROTOCOL_VXHS;
+
+    /* legacy URI based syntax passed via 'filename' option */
+    if (uri)
+        return virStorageSourceParseBackingJSONUriStr(src, uri,
+                                                      VIR_STORAGE_NET_PROTOCOL_VXHS);
+
+    server = virJSONValueObjectGetObject(json, "server");
+    hostname = virJSONValueObjectGetString(server, "host");
+    port = virJSONValueObjectGetString(server, "port");
+
+    if (!vdisk_id) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("missing 'vdisk-id' attribute in "
+                         "JSON backing definition for VxHS volume"));
+        return -1;
+    }
+    if (!server) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("missing 'server' attribute in "
+                         "JSON backing definition for VxHS volume"));
+        return -1;
+    }
+    if (!hostname) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("missing hostname for tcp backing server in "
+                       "JSON backing definition for VxHS volume"));
+        return -1;
+    }
+
+
+    if (VIR_STRDUP(src->path, vdisk_id) < 0)
+        return -1;
+
+    if (VIR_ALLOC_N(src->hosts, 1) < 0)
+        return -1;
+    src->nhosts = 1;
+
+    src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+
+    if (VIR_STRDUP(src->hosts[0].name, hostname) < 0 ||
+        VIR_STRDUP(src->hosts[0].port, port) < 0)
+        return -1;
+
+    return 0;
+}
+
 struct virStorageSourceJSONDriverParser {
     const char *drvname;
     int (*func)(virStorageSourcePtr src, virJSONValuePtr json, int opaque);
@@ -2985,6 +3045,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
     {"sheepdog", virStorageSourceParseBackingJSONSheepdog, 0},
     {"ssh", virStorageSourceParseBackingJSONSSH, 0},
     {"rbd", virStorageSourceParseBackingJSONRBD, 0},
+    {"vxhs", virStorageSourceParseBackingJSONVXHS, 0},
 };
 
 
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 1f62244..e60b6e9 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -134,6 +134,7 @@ typedef enum {
     VIR_STORAGE_NET_PROTOCOL_FTPS,
     VIR_STORAGE_NET_PROTOCOL_TFTP,
     VIR_STORAGE_NET_PROTOCOL_SSH,
+    VIR_STORAGE_NET_PROTOCOL_VXHS,
 
     VIR_STORAGE_NET_PROTOCOL_LAST
 } virStorageNetProtocol;
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index 18d9fe3..9fe24d6 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -942,6 +942,7 @@ xenFormatXLDiskSrcNet(virStorageSourcePtr src)
     case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
     case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
     case VIR_STORAGE_NET_PROTOCOL_SSH:
+    case VIR_STORAGE_NET_PROTOCOL_VXHS:
     case VIR_STORAGE_NET_PROTOCOL_LAST:
     case VIR_STORAGE_NET_PROTOCOL_NONE:
         virReportError(VIR_ERR_NO_SUPPORT,
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args
new file mode 100644
index 0000000..f6e3e37
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args
@@ -0,0 +1,24 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/libexec/qemu-kvm \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-cpu qemu32 \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=vxhs://192.168.0.1:9999/eb90327c-8302-4725-9e1b-4e85ed4dc251,\
+format=raw,if=none,id=drive-virtio-disk0,cache=none \
+-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+id=virtio-disk0
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.xml
new file mode 100644
index 0000000..45c807f
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.xml
@@ -0,0 +1,34 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>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/libexec/qemu-kvm</emulator>
+    <disk type='network' device='disk'>
+      <driver name='qemu' type='raw' cache='none'/>
+      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc251'>
+        <host name='192.168.0.1' port='9999'/>
+      </source>
+      <backingStore/>
+      <target dev='vda' bus='virtio'/>
+      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc251</serial>
+      <alias name='virtio-disk0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ab3ad08..0c3470b 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -892,6 +892,7 @@ mymain(void)
 # endif
     DO_TEST("disk-drive-network-rbd-ipv6", NONE);
     DO_TEST_FAILURE("disk-drive-network-rbd-no-colon", NONE);
+    DO_TEST("disk-drive-network-vxhs", NONE);
     DO_TEST("disk-drive-no-boot",
             QEMU_CAPS_BOOTINDEX);
     DO_TEST_PARSE_ERROR("disk-device-lun-type-invalid",
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index f766df1..a28fbd9 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -1492,6 +1492,22 @@ mymain(void)
                        "<source protocol='rbd' name='testshare'>\n"
                        "  <host name='example.com'/>\n"
                        "</source>\n");
+    TEST_BACKING_PARSE("json:{\"file.driver\":\"vxhs\","
+                             "\"file.filename\":\"vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0\""
+                            "}",
+                       "<source protocol='vxhs' name='c6718f6b-0401-441d-a8c3-1f0064d75ee0'>\n"
+                       "  <host name='192.168.0.1' port='9999'/>\n"
+                       "</source>\n");
+    TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"vxhs\","
+                                       "\"vdisk-id\":\"c6718f6b-0401-441d-a8c3-1f0064d75ee0\","
+                                       "\"server\": { \"host\":\"example.com\","
+                                                      "\"port\":\"1234\""
+                                                   "}"
+                                      "}"
+                            "}",
+                       "<source protocol='vxhs' name='c6718f6b-0401-441d-a8c3-1f0064d75ee0'>\n"
+                       "  <host name='example.com' port='1234'/>\n"
+                       "</source>\n");
 
  cleanup:
     /* Final cleanup */
-- 
2.5.5




More information about the libvir-list mailing list