[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