Support discard='ignore' configurations and
logical and physical block sizes configured by <blockio/>.

As these options are common to the storage backend, introduce
a helper bhyveBuildCommonDiskOpts() to generate the command line
for them. This also enables bootindex configuration for the NVMe
devices.

As bhyve uses 'int' for block sizes, discard values greater than
INT_MAX. And as bhyve does not support specifying physical block
size without specifying logical block size, reject these configurations
too.

Signed-off-by: Roman Bogorodskiy <[email protected]>
---
 src/bhyve/bhyve_command.c                     | 39 ++++++++++++------
 src/bhyve/bhyve_domain.c                      | 18 +++++++-
 .../bhyvexml2argv-disk-blockio-invalid.xml    | 17 ++++++++
 .../x86_64/bhyvexml2argv-disk-options.args    | 11 +++++
 .../x86_64/bhyvexml2argv-disk-options.ldargs  |  4 ++
 .../x86_64/bhyvexml2argv-disk-options.xml     | 41 +++++++++++++++++++
 tests/bhyvexml2argvtest.c                     |  2 +
 7 files changed, 118 insertions(+), 14 deletions(-)
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-blockio-invalid.xml
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.args
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.ldargs
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.xml

diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 31ea9d6740..49c3101027 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -42,6 +42,28 @@
 
 VIR_LOG_INIT("bhyve.bhyve_command");
 
+static void
+bhyveBuildCommonDiskOpts(const virDomainDiskDef *disk,
+                         virBuffer *opt)
+{
+    if (disk->info.bootIndex != 0)
+        virBufferAsprintf(opt, ",bootindex=%u", disk->info.bootIndex);
+
+    if (disk->src->readonly)
+        virBufferAddLit(opt, ",ro");
+
+    if (disk->discard == VIR_DOMAIN_DISK_DISCARD_IGNORE)
+        virBufferAddLit(opt, ",nodelete");
+
+    if (disk->blockio.logical_block_size > 0) {
+        /* sectorsize=logical[/physical] */
+        virBufferAsprintf(opt, ",sectorsize=%u",
+                          disk->blockio.logical_block_size);
+        if (disk->blockio.physical_block_size > 0)
+            virBufferAsprintf(opt, "/%u", disk->blockio.physical_block_size);
+    }
+}
+
 static int
 bhyveBuildNetArgStr(const virDomainDef *def,
                     virDomainNetDef *net,
@@ -366,12 +388,7 @@ bhyveBuildAHCIControllerArgStr(const virDomainDef *def,
         if (disk->serial)
             virBufferAsprintf(&device, ",ser=%s", disk->serial);
 
-        if (disk->info.bootIndex != 0)
-            virBufferAsprintf(&device, ",bootindex=%u", disk->info.bootIndex);
-
-        if (disk->src->readonly)
-            virBufferAddLit(&device, ",ro");
-
+        bhyveBuildCommonDiskOpts(disk, &device);
         virBufferAddBuffer(&buf, &device);
     }
 
@@ -520,8 +537,8 @@ bhyveBuildNVMeControllerArgStr(const virDomainDef *def,
                               disk->wwn);
         if (controller->opts.nvmeopts.serial)
             virBufferAsprintf(&opt, ",ser=%s", 
controller->opts.nvmeopts.serial);
-        if (disk->src->readonly)
-            virBufferAddLit(&opt, ",ro");
+
+        bhyveBuildCommonDiskOpts(disk, &opt);
 
         nvme_opts = virBufferContentAndReset(&opt);
 
@@ -601,11 +618,7 @@ bhyveBuildVirtIODiskArgStr(const virDomainDef *def 
G_GNUC_UNUSED,
 
     disk_source = virDomainDiskGetSource(disk);
 
-    if (disk->info.bootIndex != 0)
-        virBufferAsprintf(&opts, ",bootindex=%u", disk->info.bootIndex);
-
-    if (disk->src->readonly)
-        virBufferAddLit(&opts, ",ro");
+    bhyveBuildCommonDiskOpts(disk, &opts);
 
     virCommandAddArg(cmd, "-s");
     virCommandAddArgFormat(cmd, "%d:0,virtio-blk,%s%s",
diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
index 0ee2e06664..0d076fc08c 100644
--- a/src/bhyve/bhyve_domain.c
+++ b/src/bhyve/bhyve_domain.c
@@ -463,7 +463,8 @@ bhyveDomainDeviceDefValidate(const virDomainDeviceDef *dev,
         virDomainDiskDef *disk = dev->data.disk;
 
         if ((disk->bus == VIR_DOMAIN_DISK_BUS_SATA ||
-             disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) &&
+             disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO ||
+             disk->bus == VIR_DOMAIN_DISK_BUS_NVME) &&
             disk->info.bootIndex > INT_MAX) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("boot order '%1$u' is greater than bhyve's 
maximum of %2$d"),
@@ -493,6 +494,21 @@ bhyveDomainDeviceDefValidate(const virDomainDeviceDef *dev,
             }
         }
 
+        if (disk->blockio.physical_block_size > INT_MAX ||
+            disk->blockio.logical_block_size > INT_MAX) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("block size is greater than bhyve's maximum of 
%1$d"),
+                           INT_MAX);
+            return -1;
+        }
+
+        if (disk->blockio.physical_block_size > 0 &&
+            disk->blockio.logical_block_size == 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Setting physical block size without logical 
block size is not supported"));
+            return -1;
+        }
+
         break;
     }
     case VIR_DOMAIN_DEVICE_NET: {
diff --git 
a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-blockio-invalid.xml 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-blockio-invalid.xml
new file mode 100644
index 0000000000..5e46276602
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-blockio-invalid.xml
@@ -0,0 +1,17 @@
+<domain type='bhyve'>
+  <name>bhyve</name>
+  <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd.img'/>
+      <target dev='hda' bus='sata'/>
+      <blockio physical_block_size='4096'/>
+    </disk>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.args 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.args
new file mode 100644
index 0000000000..2d82a4c6fc
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.args
@@ -0,0 +1,11 @@
+bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 
2:0,nvme,/tmp/nvme-ignore.img,maxq=2,qsz=256,eui64=0x01000000efbeadde,ser=BHYVE-NVME0-01234,nodelete,sectorsize=4096/4096
 \
+-s 
3:0,ahci,hd:/tmp/sata-ignore.img,nmrr=7200,ser=BHYVE-SATA-IGNORE,nodelete,sectorsize=512/4096,hd:/tmp/sata-unmap.img,nmrr=5400,ser=BHYVE-SATA-UNMAP,sectorsize=4096
 \
+-s 4:0,virtio-blk,/tmp/virtio-ignore.img,nodelete,sectorsize=512/4096 \
+bhyve
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.ldargs 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.ldargs
new file mode 100644
index 0000000000..b5e7d06c0a
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.ldargs
@@ -0,0 +1,4 @@
+bhyveload \
+-m 214 \
+-d /tmp/sata-ignore.img \
+bhyve
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.xml 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.xml
new file mode 100644
index 0000000000..448fba92bd
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-disk-options.xml
@@ -0,0 +1,41 @@
+<domain type='bhyve'>
+  <name>bhyve</name>
+  <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <controller type='nvme' index='0'>
+      <serial>BHYVE-NVME0-01234</serial>
+    </controller>
+    <disk type='file'>
+      <serial>BHYVE-SATA-IGNORE</serial>
+      <driver name='file' type='raw' discard='ignore'/>
+      <source file='/tmp/sata-ignore.img'/>
+      <target dev='hda' bus='sata' rotation_rate='7200'/>
+      <blockio logical_block_size='512' physical_block_size='4096'/>
+    </disk>
+    <disk type='file'>
+      <serial>BHYVE-SATA-UNMAP</serial>
+      <driver name='file' type='raw' discard='unmap'/>
+      <source file='/tmp/sata-unmap.img'/>
+      <target dev='hdb' bus='sata' rotation_rate='5400'/>
+      <blockio logical_block_size='4096'/>
+    </disk>
+    <disk type='file'>
+      <driver name='file' type='raw' discard='ignore'/>
+      <source file='/tmp/virtio-ignore.img'/>
+      <target dev='vda' bus='virtio'/>
+      <blockio logical_block_size='512' physical_block_size='4096'/>
+    </disk>
+    <disk type='file'>
+      <driver name='file' type='raw' discard='ignore' queues='2' 
queue_size='256'/>
+      <source file='/tmp/nvme-ignore.img'/>
+      <target dev='nvme0n1' bus='nvme'/>
+      <wwn>01000000efbeadde</wwn>
+      <blockio logical_block_size='4096' physical_block_size='4096'/>
+    </disk>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index c208db6311..28b5ee981b 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -240,6 +240,8 @@ mymain(void)
     DO_TEST("disk-cdrom");
     DO_TEST("disk-virtio");
     DO_TEST("disk-readonly");
+    DO_TEST("disk-options");
+    DO_TEST_FAILURE("disk-blockio-invalid");
     DO_TEST("macaddr");
     DO_TEST("serial");
     DO_TEST("console");
-- 
2.55.0

Reply via email to