summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2017-04-30 13:56:40 +0300
committerHans Rosenfeld <hans.rosenfeld@joyent.com>2017-06-12 12:54:34 +0200
commit115716444da43c8948885b687239f3c4187d0897 (patch)
tree1d81ac7cde22f396de90217ee5dad5ade57986b0
parente2f4f3dab373b605b62ac175115f264a5c417eb6 (diff)
downloadillumos-joyent-115716444da43c8948885b687239f3c4187d0897.tar.gz
8131 loader: add support for chain and device BE's
Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
-rw-r--r--usr/src/boot/sys/boot/forth/beadm.4th145
-rw-r--r--usr/src/boot/sys/boot/forth/menu-commands.4th17
2 files changed, 109 insertions, 53 deletions
diff --git a/usr/src/boot/sys/boot/forth/beadm.4th b/usr/src/boot/sys/boot/forth/beadm.4th
index 6ed81e8913..31b1fe5db1 100644
--- a/usr/src/boot/sys/boot/forth/beadm.4th
+++ b/usr/src/boot/sys/boot/forth/beadm.4th
@@ -8,7 +8,7 @@
\ source. A copy of the CDDL is also available via the Internet at
\ http://www.illumos.org/license/CDDL.
-\ Copyright 2015 Toomas Soome <tsoome@me.com>
+\ Copyright 2017 Toomas Soome <tsoome@me.com>
\ This module is implementing the beadm user command to support listing
\ and switching Boot Environments (BE) from command line and
@@ -83,7 +83,7 @@ variable page_remainder
O_RDONLY fopen fd !
reset_line_reading
fd @ -1 = if EOPEN throw then
- ." BE" dup 2 - spaces ." bootfs" cr
+ ." BE" dup 2 - spaces ." Type Device" cr
begin
end_of_file? 0=
while
@@ -95,6 +95,9 @@ variable page_remainder
free_buffers
read_line
get_name_value
+ name_buffer strget type
+ name_buffer strget s" bootfs" compare 0= if 2 spaces then
+ name_buffer strget s" chain" compare 0= if 3 spaces then
value_buffer strget type cr
free_buffers
repeat
@@ -102,12 +105,14 @@ variable page_remainder
drop
;
-: beadm_bootfs ( be_addr be_len menu_addr menu_len -- addr len flag )
+\ we are called with strings be_name menu_file, to simplify the stack
+\ management, we open the menu and free the menu_file.
+: beadm_bootfs ( be_addr be_len maddr mlen -- addr len taddr tlen flag | flag )
0 to end_of_file?
- O_RDONLY fopen fd !
- reset_line_reading
+ 2dup O_RDONLY fopen fd !
+ drop free-memory
fd @ -1 = if EOPEN throw then
- 2swap
+ reset_line_reading
begin
end_of_file? 0=
while
@@ -116,11 +121,12 @@ variable page_remainder
get_name_value
2dup value_buffer strget compare
0= if ( title == be )
- 2drop
+ 2drop \ drop be_name
free_buffers
read_line
get_name_value
- value_buffer strget strdup -1
+ value_buffer strget strdup
+ name_buffer strget strdup -1
free_buffers
1 to end_of_file? \ mark end of file to skip the rest
else
@@ -130,9 +136,9 @@ variable page_remainder
fd @ fclose
line_buffer strfree
read_buffer strfree
- dup -1 > if ( dev_addr dev_len )
+ dup -1 > if ( be_addr be_len )
2drop
- 0 0 0
+ 0
then
;
@@ -179,43 +185,55 @@ variable page_remainder
;
\ activate be on device.
-\ in case of zfs, we query device:/boot/menu.lst for bootfs and
-\ use zfs:bootfs: for currdev
-\ in case of ufs we have device name without ':', so we just
-\ set currdev=device: and hope for best - there are no multiple BE's on ufs
+\ if be name was not given, set currdev
+\ otherwize, we query device:/boot/menu.lst for bootfs and
+\ if found, and bootfs type is chain, attempt chainload.
+\ set currdev to bootfs.
+\ if we were able to set currdev, reload the config
: activate-dev ( dev.addr dev.len be.addr be.len -- )
- 2swap colon- \ remove : at the end of the dev name
- 2dup [char] : strchr nip
- 0= if ( no ':' in dev name, its ufs )
- 2swap 2drop
+
+ dup 0= if
+ 2drop
+ colon- \ remove : at the end of the dev name
dup 1+ allocate if ENOMEM throw then
dup 2swap 0 -rot strcat
colon+
s" currdev" setenv \ setenv currdev = device
free-memory
else
- dup 16 + allocate if ENOMEM throw then
- swap 2dup 2>R \ copy of new addr len to return stack
- move 2R> \ copy dev name and concat file name
- s" :/boot/menu.lst" strcat 2dup \ leave copy to stack
- beadm_bootfs if ( dev_addr dev_len addr len )
- 2swap \ addr len dev_addr dev_len
- drop
- free-memory
+ 2swap menu.lst
+ beadm_bootfs if ( addr len taddr tlen )
+ 2dup s" chain" compare 0= if
+ drop free-memory \ free type
+ 2dup
+ dup 6 + allocate if ENOMEM throw then
+ dup >R
+ 0 s" chain " strcat
+ 2swap strcat ['] evaluate catch drop
+ \ We are still there?
+ R> free-memory \ free chain command
+ drop free-memory \ free addr
+ exit
+ then
+ drop free-memory \ free type
+ 2dup [char] : strchr nip 0= if
\ have dataset and need to get zfs:pool/ROOT/be:
- dup 5 + allocate if ENOMEM throw then
- 0 s" zfs:" strcat
- 2swap strcat
- colon+
+ dup 5 + allocate if ENOMEM throw then
+ 0 s" zfs:" strcat
+ 2swap strcat
+ colon+
+ then
2dup s" currdev" setenv
drop free-memory
else
- 2drop drop free \ free the file name
- ." Failed to process BE/dev" cr abort
+ ." No such BE in menu.lst or menu.lst is missing." cr
+ exit
then
then
+ \ reset BE menu
+ 0 page_count !
\ need to do:
0 unload drop
free-module-options
@@ -233,7 +251,7 @@ variable page_remainder
;
\ beadm list [device]
-\ beadm activate BE [device] BE
+\ beadm activate BE [device] | device
\
\ lists BE's from current or specified device /boot/menu.lst file
\ activates specified BE by unloading modules, setting currdev and
@@ -243,7 +261,7 @@ variable page_remainder
dup 0= if
." Usage:" cr
- ." beadm activate beName [device]" cr
+ ." beadm activate {beName [device] | device}" cr
." beadm list [device]" cr
." Use lsdev to get device names." cr
drop exit
@@ -269,12 +287,12 @@ variable page_remainder
then
argc 2 = if ( activate be )
\ need to set arg list into proper order
- 1 + >R \ save argc+1 to return stack
+ 1+ >R \ save argc+1 to return stack
\ if we have : in name, its device, inject
- \ dummy be name, as it must be ufs device
+ \ empty be name
2dup [char] : strchr nip
if ( its : in name )
- s" ufs" R>
+ 0 0 R>
else
\ add device, swap with be and receive argc
current-dev 2swap R>
@@ -348,12 +366,13 @@ builtin: beadm
then
;
-: be-set-page { | entry count n -- }
+: be-set-page { | entry count n device -- }
page_count @ 0= if
be-pages
page_count @ 0= if exit then
then
+ 0 to device
s" zfs_be_currpage" getenv dup -1 = if
drop s" 1"
then
@@ -399,25 +418,47 @@ builtin: beadm
value_buffer strget
52 i + \ ascii 4 + i
s" bootenvansi_caption[4]" 20 +c! setenv
- s" set_bootenv"
- 52 i + \ ascii 4 + i
- s" bootenvmenu_command[4]" 20 +c! setenv
+
free_buffers
read_line \ read value line
get_name_value
+
+ \ set menu entry command
+ name_buffer strget s" chain" compare
+ 0= if
+ s" set_be_chain"
+ else
+ s" set_bootenv"
+ then
+ 52 i + \ ascii 4 + i
+ s" bootenvmenu_command[4]" 20 +c! setenv
+
+ \ set device name
+ name_buffer strget s" chain" compare
+ 0= if
+ \ for chain, use the value as is
+ value_buffer strget
+ else
+ value_buffer strget 2dup
+ [char] : strchr nip
+ 0= if
+ \ make zfs device name
+ swap drop
+ 5 + allocate if
+ ENOMEM throw
+ then
+ s" zfs:" ( addr addr' len' )
+ 2 pick swap move ( addr )
+ dup to device
+ 4 value_buffer strget
+ strcat ( addr len )
+ s" :" strcat
+ then
+ then
+
52 i + \ ascii 4 + i
- value_buffer strget swap drop
- 5 + allocate if ENOMEM throw then
- s" zfs:" ( N addr addr1 len )
- 2 pick swap move ( N addr )
- swap over ( addr N addr )
- 4 value_buffer
- strget ( addr N addr 4 addr1 len )
- strcat ( addr N addr 4+len )
- s" :" strcat ( addr N addr 5+len )
- rot ( addr addr 5+len N )
s" bootenv_root[4]" 13 +c! setenv
- free-memory
+ device free-memory 0 to device
free_buffers
-1
+loop
diff --git a/usr/src/boot/sys/boot/forth/menu-commands.4th b/usr/src/boot/sys/boot/forth/menu-commands.4th
index 4460ccaf59..cfcecf78b9 100644
--- a/usr/src/boot/sys/boot/forth/menu-commands.4th
+++ b/usr/src/boot/sys/boot/forth/menu-commands.4th
@@ -565,7 +565,6 @@ also menu-namespace also menu-command-helpers
dup s" bootenv_root[E]" 13 +c! getenv
s" currdev" getenv compare 0= if
s" zfs_be_active" getenv type ." is already active"
- 500 ms \ sleep
else
dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate
dup s" bootenvmenu_caption[E]" 20 +c! getenv
@@ -578,14 +577,30 @@ also menu-namespace also menu-command-helpers
s" /boot/loader.conf" read-conf
s" /boot/loader.conf.local" read-conf
init_bootenv
+
+ s" 1" s" zfs_be_currpage" setenv
+ s" be-set-page" evaluate
then
+ 500 ms \ sleep so user can see the message
be_draw_screen
menu-redraw
TRUE
;
\
+\ Chainload this entry. Normally we do not return, in case of error
+\ from chain load, we continue with normal menu code.
+\
+
+: set_be_chain ( N -- no return | N TRUE )
+ dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop
+
+ menu-redraw
+ TRUE
+;
+
+\
\ Switch to the next page of boot environments
\