[SLOF] [PATCH] Rework handling of the "qemu,boot-list" property
Thomas Huth
thuth at redhat.com
Fri Jan 13 20:55:34 AEDT 2017
If the user started QEMU with both, devices that are specified with
a "bootindex=..." parameter and with the parameter "-boot order=..."
(or "-boot once=..."), there are currently two issues in SLOF with
the resulting boot order:
1) Everything from "-boot order=..." gets ignored completely as soon as
one of the other devices has a "bootindex" parameter - even if we
boot with "strict=off". For example if the user starts QEMU with
"-device virtio-blk-pci,bootindex=0 -boot order=cn", the NIC has
not been specified with a "bootindex" and the block device is not
bootable, SLOF never tries to boot from the network device.
2) The "-boot once=..." feature can never be used as soon as one
device has been specified with a "bootindex" parameter.
The devices with "bootindex" are passed to SLOF in a sorted list via
the "qemu,boot-list" property, and the value from "-boot order" or
"-boot once" is passed to SLOF directly via the "qemu,boot-device"
property. To fix the problems when a user specified both, we should
rather treat the "qemu,boot-device" property as a group filter for
the "qemu,boot-list", so that we only consider those devices in
"qemu,boot-list" which match the specified classes from the
"qemu,boot-device" property.
Additionally if we're not in strict=on boot mode, we should always
continue to consider all other boot devices and not stop after
processing the devices from "qemu,boot-list".
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1410391
Signed-off-by: Thomas Huth <thuth at redhat.com>
---
board-qemu/slof/qemu-bootlist.fs | 141 +++++++++++++++++++++++++++++++++++++--
1 file changed, 137 insertions(+), 4 deletions(-)
diff --git a/board-qemu/slof/qemu-bootlist.fs b/board-qemu/slof/qemu-bootlist.fs
index 4778e16..c4e431b 100644
--- a/board-qemu/slof/qemu-bootlist.fs
+++ b/board-qemu/slof/qemu-bootlist.fs
@@ -13,6 +13,139 @@
defer set-boot-device
defer add-boot-device
+\ Add a device to the bootdevices list if it is a (non-CD-ROM) disk device
+: qemu-add-if-disk-dev ( devstr len -- )
+ 2dup find-node s" device_type" rot get-property IF
+ 2drop
+ ELSE
+ 1-
+ s" block" str= IF
+ 2dup open-dev dup s" is_cdrom" rot
+ instance>parent @ \ Get from interposed disk-label to real node
+ ( devstr len disklabel-ihandle iscdromstr iscdromlen ihandle )
+ ['] $call-method CATCH IF 3drop FALSE THEN
+ ( devstr len disklabel-ihandle iscdrom? )
+ swap close-dev 0= IF
+ strdup add-boot-device
+ ELSE
+ 2drop
+ THEN
+ ELSE
+ 2drop
+ THEN
+ THEN
+;
+
+\ Step through the "qemu,boot-device" property to process all disk devices
+: qemu-add-disks-from-boot-list ( prop len -- )
+ 2dup bl findchar IF
+ 3dup nip qemu-add-if-disk-dev
+ 1+ >r
+ 2dup r@ - swap r@ + swap ( prop len subprop sublen )
+ RECURSE
+ r> 3drop
+ EXIT
+ THEN
+ qemu-add-if-disk-dev
+;
+
+\ Add a device to the bootdevices list if it is a CD-ROM device
+: qemu-add-if-cdrom-dev ( devstr len -- )
+ 2dup find-node s" device_type" rot get-property IF
+ 2drop
+ ELSE
+ 1-
+ s" block" str= IF
+ 2dup open-dev dup s" is_cdrom" rot
+ instance>parent @ \ Get from interposed disk-label to real node
+ ( devstr len disklabel-ihandle iscdromstr iscdromlen ihandle )
+ ['] $call-method CATCH IF 3drop FALSE THEN
+ ( devstr len disklabel-ihandle iscdrom? )
+ swap close-dev IF
+ strdup add-boot-device
+ ELSE
+ 2drop
+ THEN
+ ELSE
+ 2drop
+ THEN
+ THEN
+;
+
+\ Step through the "qemu,boot-device" property to process all CD-ROM devices
+: qemu-add-cdroms-from-boot-list ( prop len -- )
+ 2dup bl findchar IF
+ 3dup nip qemu-add-if-cdrom-dev
+ 1+ >r
+ 2dup r@ - swap r@ + swap ( prop len subprop sublen )
+ RECURSE
+ r> 3drop
+ EXIT
+ THEN
+ qemu-add-if-cdrom-dev
+;
+
+\ Add a device to the bootdevices list if it is a networking device
+: qemu-add-if-network-dev ( str len -- )
+ 2dup find-node s" device_type" rot get-property IF
+ 2drop
+ ELSE
+ 1-
+ s" network" str= IF
+ strdup add-boot-device
+ ELSE
+ 2drop
+ THEN
+ THEN
+;
+
+\ Step through the "qemu,boot-device" property to process all NIC devices
+: qemu-add-nics-from-boot-list ( prop len -- )
+ 2dup bl findchar IF
+ 3dup nip qemu-add-if-network-dev
+ 1+ >r
+ 2dup r@ - swap r@ + swap ( prop len subprop sublen )
+ RECURSE
+ r> 3drop
+ EXIT
+ THEN
+ qemu-add-if-network-dev
+;
+
+\ Check whether we can add all devices from the "qemu,boot-device" property
+\ or whether we have got to filter them according to the "qemu,boot-device"
+\ property (which is set for example with the "-boot once=x" QEMU parameter)
+: qemu-bootlist-from-boot-device-property ( prop len -- strict? )
+ 1- \ Ignore the trailing NUL character
+ \ strict boot order is enabled if the last 4 character in qemu,boot-list
+ \ are "HALT". In that case, do not add other boot devices.
+ dup 4 > IF
+ 2dup + 4 - 4 s" HALT" str= IF
+ 5 -
+ TRUE ( prop len' strict? )
+ ELSE
+ FALSE ( prop len strict? )
+ THEN
+ ELSE
+ FALSE ( prop len strict? )
+ THEN
+ -rot ( strict? prop len )
+
+ s" qemu,boot-device" get-chosen IF
+ 0 ?DO
+ dup i + c@ CASE
+ [char] c OF >r 2dup qemu-add-disks-from-boot-list r> ENDOF
+ [char] d OF >r 2dup qemu-add-cdroms-from-boot-list r> ENDOF
+ [char] n OF >r 2dup qemu-add-nics-from-boot-list r> ENDOF
+ ENDCASE cr
+ LOOP
+ drop
+ 2drop
+ ELSE
+ set-boot-device
+ THEN
+;
+
8 CONSTANT MAX-ALIAS
: add-boot-aliases ( str -- )
2dup add-boot-device ( $str )
@@ -28,12 +161,12 @@ defer add-boot-device
: qemu-read-bootlist ( -- )
\ See if QEMU has set exact boot device list
" qemu,boot-list" get-chosen IF
- s" boot-device" $setenv
- EXIT
+ qemu-bootlist-from-boot-device-property
+ IF EXIT THEN
+ ELSE
+ 0 0 set-boot-device
THEN
- 0 0 set-boot-device
-
" qemu,boot-device" get-chosen not IF
\ No boot list set from qemu, so check nvram
" boot-device" evaluate swap drop 0= IF
--
1.8.3.1
More information about the SLOF
mailing list