Bhyve supports specifying boot order for SATA and Virtio disk devices
using the 'bootindex=' option. Update the command building code to use
this argument when <boot order='..'/> is specified in the domain XML.

Reject boot indexes that exceed the signed integer range accepted by
bhyve.

Signed-off-by: Roman Bogorodskiy <[email protected]>
---
 src/bhyve/bhyve_command.c                     | 12 +++++--
 src/bhyve/bhyve_domain.c                      |  9 +++++
 .../bhyvexml2argv-bhyveload-bootorder3.args   |  2 +-
 .../bhyvexml2argv-bootorder-invalid-index.xml | 17 ++++++++++
 .../x86_64/bhyvexml2argv-bootorder.args       | 13 +++++++
 .../x86_64/bhyvexml2argv-bootorder.ldargs     |  1 +
 .../x86_64/bhyvexml2argv-bootorder.xml        | 34 +++++++++++++++++++
 .../x86_64/bhyvexml2argv-grub-bootorder.args  |  2 +-
 .../x86_64/bhyvexml2argv-grub-bootorder2.args |  2 +-
 tests/bhyvexml2argvtest.c                     |  2 ++
 10 files changed, 89 insertions(+), 5 deletions(-)
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder-invalid-index.xml
 create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.args
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.ldargs
 create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.xml

diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index ba7e7e29cb..f48d86d6f6 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -336,6 +336,9 @@ 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);
+
         virBufferAddBuffer(&buf, &device);
     }
 
@@ -544,6 +547,7 @@ bhyveBuildVirtIODiskArgStr(const virDomainDef *def 
G_GNUC_UNUSED,
                            virCommand *cmd)
 {
     const char *disk_source;
+    g_auto(virBuffer) opts = VIR_BUFFER_INITIALIZER;
 
     if (virDomainDiskTranslateSourcePool(disk) < 0)
         return -1;
@@ -563,10 +567,14 @@ bhyveBuildVirtIODiskArgStr(const virDomainDef *def 
G_GNUC_UNUSED,
 
     disk_source = virDomainDiskGetSource(disk);
 
+    if (disk->info.bootIndex != 0)
+        virBufferAsprintf(&opts, ",bootindex=%u", disk->info.bootIndex);
+
     virCommandAddArg(cmd, "-s");
-    virCommandAddArgFormat(cmd, "%d:0,virtio-blk,%s",
+    virCommandAddArgFormat(cmd, "%d:0,virtio-blk,%s%s",
                            disk->info.addr.pci.slot,
-                           disk_source);
+                           disk_source,
+                           virBufferCurrentContent(&opts));
 
     return 0;
 }
diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
index 3ecb1d52cb..1a19b3f888 100644
--- a/src/bhyve/bhyve_domain.c
+++ b/src/bhyve/bhyve_domain.c
@@ -454,6 +454,15 @@ bhyveDomainDeviceDefValidate(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_DISK: {
         virDomainDiskDef *disk = dev->data.disk;
 
+        if ((disk->bus == VIR_DOMAIN_DISK_BUS_SATA ||
+             disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) &&
+            disk->info.bootIndex > INT_MAX) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("boot order '%1$u' is greater than bhyve's 
maximum of %2$d"),
+                           disk->info.bootIndex, INT_MAX);
+            return -1;
+        }
+
         if (disk->rotation_rate &&
             disk->bus != VIR_DOMAIN_DISK_BUS_SATA) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
diff --git 
a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bhyveload-bootorder3.args 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bhyveload-bootorder3.args
index 96e05c6c9c..bdcd73499b 100644
--- a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bhyveload-bootorder3.args
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bhyveload-bootorder3.args
@@ -5,6 +5,6 @@ bhyve \
 -H \
 -P \
 -s 0:0,hostbridge \
--s 2:0,ahci,hd:/tmp/freebsd.img,cd:/tmp/cdrom.iso \
+-s 2:0,ahci,hd:/tmp/freebsd.img,cd:/tmp/cdrom.iso,bootindex=1 \
 -s 3:0,virtio-net,faketapdev,mac=52:54:00:7a:f5:a4 \
 bhyve
diff --git 
a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder-invalid-index.xml 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder-invalid-index.xml
new file mode 100644
index 0000000000..552992d49f
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder-invalid-index.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 firmware='efi'>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd.img'/>
+      <target dev='hda' bus='sata'/>
+      <boot order='4294967295'/>
+    </disk>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.args 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.args
new file mode 100644
index 0000000000..e9caf8e71b
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.args
@@ -0,0 +1,13 @@
+bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-l bootrom,fakefirmwaredir/BHYVE_UEFI.fd,fakenvramdir/bhyve_VARS.fd,fwcfg=qemu 
\
+-s 1:0,lpc \
+-s 2:0,ahci,hd:/tmp/freebsd1.img,bootindex=2,hd:/tmp/freebsd2.img,bootindex=1 \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \
+-s 4:0,virtio-blk,/tmp/freebsd2.img,bootindex=3 \
+bhyve
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.ldargs 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.ldargs
new file mode 100644
index 0000000000..421376db9e
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.ldargs
@@ -0,0 +1 @@
+dummy
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.xml 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.xml
new file mode 100644
index 0000000000..3f24a41521
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-bootorder.xml
@@ -0,0 +1,34 @@
+<domain type='bhyve'>
+  <name>bhyve</name>
+  <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os firmware='efi'>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd1.img'/>
+      <target dev='hda' bus='sata'/>
+      <boot order="2"/>
+    </disk>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd2.img'/>
+      <target dev='vdb' bus='virtio'/>
+      <boot order="3"/>
+    </disk>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd2.img'/>
+      <target dev='hdc' bus='sata'/>
+      <boot order="1"/>
+    </disk>
+    <interface type='bridge'>
+      <mac address='52:54:00:b9:94:02'/>
+      <model type='virtio'/>
+      <source bridge="virbr0"/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder.args 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder.args
index 9ed28162ac..3a36a5c374 100644
--- a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder.args
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder.args
@@ -5,6 +5,6 @@ bhyve \
 -H \
 -P \
 -s 0:0,hostbridge \
--s 2:0,ahci,hd:/tmp/freebsd1.img,hd:/tmp/freebsd2.img,hd:/tmp/freebsd3.img \
+-s 
2:0,ahci,hd:/tmp/freebsd1.img,hd:/tmp/freebsd2.img,hd:/tmp/freebsd3.img,bootindex=1
 \
 -s 3:0,virtio-net,faketapdev,mac=52:54:00:f4:6c:be \
 bhyve
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder2.args 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder2.args
index 7ed87b2578..a16a0995ef 100644
--- a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder2.args
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-grub-bootorder2.args
@@ -5,6 +5,6 @@ bhyve \
 -H \
 -P \
 -s 0:0,hostbridge \
--s 2:0,ahci,hd:/tmp/freebsd1.img,hd:/tmp/freebsd2.img,hd:/tmp/freebsd3.img \
+-s 
2:0,ahci,hd:/tmp/freebsd1.img,bootindex=111,hd:/tmp/freebsd2.img,bootindex=22,hd:/tmp/freebsd3.img,bootindex=3
 \
 -s 3:0,virtio-net,faketapdev,mac=52:54:00:0e:d2:6f \
 bhyve
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 95969a641b..d00ceab825 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -205,6 +205,8 @@ mymain(void)
                        BHYVE_CAP_NVME | BHYVE_CAP_NUMA;
 
     DO_TEST("base");
+    DO_TEST("bootorder");
+    DO_TEST_FAILURE("bootorder-invalid-index");
     DO_TEST("wired");
     DO_TEST("acpiapic");
     driver.bhyvecaps &= ~BHYVE_CAP_ACPI;
-- 
2.55.0

Reply via email to