diff options
author | Toomas Soome <tsoome@me.com> | 2017-04-30 13:56:40 +0300 |
---|---|---|
committer | Hans Rosenfeld <hans.rosenfeld@joyent.com> | 2017-06-12 12:54:34 +0200 |
commit | 115716444da43c8948885b687239f3c4187d0897 (patch) | |
tree | 1d81ac7cde22f396de90217ee5dad5ade57986b0 | |
parent | e2f4f3dab373b605b62ac175115f264a5c417eb6 (diff) | |
download | illumos-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.4th | 145 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/forth/menu-commands.4th | 17 |
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 \ |