Print this page
11581 'debug' loader option is a little obscure
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/boot/sys/boot/forth/beadm.4th.man.txt
+++ new/usr/src/boot/sys/boot/forth/beadm.4th.man.txt
1 1 () ()
2 2
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3
4 4
5 5 This file and its contents are supplied under the terms of the Common
6 6 Development and Distribution License ("CDDL"), version 1.0. You may only use
7 7 this file in accordance with the terms of version 1.0 of the CDDL. A full
8 8 copy of the text of the CDDL should have accompanied this source. A copy of
9 9 the CDDL is also available via the Internet at
10 10 http://www.illumos.org/license/CDDL.
11 11
12 12 Copyright 2017 Toomas Soome <tsoome@me.com> Copyright 2019 OmniOS Community
13 -Edition (OmniOSce) Association.
13 +Edition (OmniOSce) Association. Copyright 2019 Joyent, Inc.
14 14
15 15 This module is implementing the beadm user command to support listing and
16 16 switching Boot Environments (BE) from command line and support words to
17 17 provide data for BE menu in loader menu system. Note: this module needs an
18 18 update to provide proper BE vocabulary.
19 19
20 20 only forth also support-functions also file-processing also file-processing
21 21 definitions also parser also line-reading definitions also builtins
22 22 definitions
23 23
24 24 variable page_count variable page_remainder 0 page_count ! 0 page_remainder !
25 25
26 26 from menu.4th : +c! ( N C-ADDR/U K -- C-ADDR/U ) 3 pick 3 pick ( n c-
27 27 addr/u k -- n c-addr/u k n c-addr ) rot + c! ( n c-addr/u k n c-addr -- n
28 28 c-addr/u ) rot drop ( n c-addr/u -- c-addr/u ) ;
29 29
30 30 : get_value ( -- ) eat_space line_pointer skip_to_end_of_line
31 31 line_pointer over - strdup value_buffer strset ['] exit to
32 32 parsing_function ;
33 33
34 34 : get_name ( -- ) read_name ['] get_value to parsing_function ;
35 35
36 36 : get_name_value line_buffer strget + to end_of_line line_buffer .addr
37 37 @ to line_pointer ['] get_name to parsing_function begin
38 38 end_of_line? 0= while parsing_function execute
39 39 repeat ;
40 40
41 41 beadm support : beadm_longest_title ( addr len -- width ) 0 to end_of_file?
42 42 O_RDONLY fopen fd ! reset_line_reading fd @ -1 = if EOPEN throw
43 43 then 0 >r length into return stack begin end_of_file?
44 44 0= while free_buffers read_line get_name_value
45 45 value_buffer .len @ r@ > if r> drop value_buffer .len @ >r then
46 46 free_buffers read_line repeat fd @ fclose r> 1 +
47 47 space between columns ;
48 48
49 49 Pretty print BE list : beadm_list ( width addr len -- ) 0 to end_of_file?
50 50 O_RDONLY fopen fd ! reset_line_reading fd @ -1 = if EOPEN throw
51 51 then ." BE" dup 2 - spaces ." Type Device" cr begin
52 52 end_of_file? 0= while free_buffers read_line
53 53 get_name_value value_buffer strget type dup
54 54 value_buffer .len @ - spaces free_buffers read_line
55 55 get_name_value name_buffer strget type name_buffer
56 56 strget s" bootfs" compare 0= if 2 spaces then name_buffer strget s"
57 57 chain" compare 0= if 3 spaces then value_buffer strget type cr
58 58 free_buffers repeat fd @ fclose drop ;
59 59
60 60 \[u00A0]we are called with strings be_name menu_file, to simplify the stack
61 61 management, we open the menu and free the menu_file. : beadm_bootfs ( be_addr
62 62 be_len maddr mlen -- addr len taddr tlen flag | flag ) 0 to end_of_file?
63 63 2dup O_RDONLY fopen fd ! drop free-memory fd @ -1 = if EOPEN
64 64 throw then reset_line_reading begin end_of_file? 0= while
65 65 free_buffers read_line get_name_value
66 66 2dup value_buffer strget compare 0= if ( title == be )
67 67 2drop drop be_name free_buffers
68 68 read_line get_name_value
69 69 value_buffer strget strdup name_buffer strget
70 70 strdup -1 free_buffers 1 to end_of_file? mark end
71 71 of file to skip the rest else read_line skip over
72 72 next line then repeat fd @ fclose line_buffer strfree
73 73 read_buffer strfree dup -1 > if ( be_addr be_len ) 2drop
74 74 0 then ;
75 75
76 76 : current-dev ( -- addr len ) return current dev s" currdev" getenv
77 77 2dup [char] / strchr nip dup 0> if ( strchr '/' != NULL ) - else
78 78 drop then we have now zfs:pool or diskname: ;
79 79
80 80 chop trailing ':' : colon- ( addr len -- addr len - 1 | addr len ) 2dup 1 -
81 81 + C@ [char] : = if ( string[len-1] == ':' ) 1 - then ;
82 82
83 83 add trailing ':' : colon+ ( addr len -- addr len+1 ) 2dup +
84 84 addr len -- addr+len [char] : swap c! save ':' at the
85 85 end of the string 1+ addr len -- addr len+1 ;
86 86
87 87 make menu.lst path : menu.lst ( addr len -- addr' len' ) colon- need to
88 88 allocate space for len + 16 dup 16 + allocate if ENOMEM throw then swap
89 89 2dup 2>R copy of new addr len to return stack move 2R> s"
90 90 :/boot/menu.lst" strcat ;
91 91
92 92 list be's on device : list-dev ( addr len -- ) menu.lst 2dup 2>R
93 93 beadm_longest_title line_buffer strfree read_buffer strfree
94 94 R@ swap 2R> addr width addr len beadm_list free-memory ."
95 95 Current boot device: " s" currdev" getenv type cr line_buffer strfree
96 96 read_buffer strfree ;
97 97
98 98 activate be on device. if be name was not given, set currdev otherwize, we
99 99 query device:/boot/menu.lst for bootfs and if found, and bootfs type is
100 100 chain, attempt chainload. set currdev to bootfs. if we were able to set
101 101 currdev, reload the config
102 102
103 103 : activate-dev ( dev.addr dev.len be.addr be.len -- )
104 104
105 105 dup 0= if 2drop colon- remove : at the
106 106 end of the dev name dup 1+ allocate if ENOMEM throw then dup
107 107 2swap 0 -rot strcat colon+ s" currdev" setenv setenv
108 108 currdev = device free-memory else 2swap menu.lst
109 109 beadm_bootfs if ( addr len taddr tlen ) 2dup s"
110 110 chain" compare 0= if drop free-memory free type
111 111 2dup dup 6 + allocate if ENOMEM throw
112 112 then dup >R 0 s" chain " strcat
113 113 2swap strcat ['] evaluate catch drop We
114 114 are still there? R> free-memory free chain command
115 115 drop free-memory free addr exit
116 116 then drop free-memory free type
117 117 check last char in the name 2dup + c@ [char] : <>
118 118 if have dataset and need to get zfs:pool/ROOT/be:
↓ open down ↓ |
95 lines elided |
↑ open up ↑ |
119 119 dup 5 + allocate if ENOMEM throw then 0
120 120 s" zfs:" strcat 2swap strcat colon+
121 121 then 2dup s" currdev" setenv drop
122 122 free-memory else ." No such BE in menu.lst or menu.lst
123 123 is missing." cr exit then then
124 124
125 125 reset BE menu 0 page_count ! need to do: 0 unload drop
126 126 free-module-options unset the env variables with kernel arguments
127 127 s" acpi-user-options" unsetenv s" boot-args" unsetenv s" boot_ask"
128 128 unsetenv s" boot_single" unsetenv s" boot_verbose" unsetenv s"
129 -boot_kmdb" unsetenv s" boot_debug" unsetenv s" boot_reconfigure"
130 -unsetenv start load config, kernel and modules ." Current
131 -boot device: " s" currdev" getenv type cr ;
129 +boot_kmdb" unsetenv s" boot_drop_into_kmdb" unsetenv s"
130 +boot_reconfigure" unsetenv start load config, kernel and
131 +modules ." Current boot device: " s" currdev" getenv type cr ;
132 132
133 133 beadm list [device] beadm activate BE [device] | device lists BE's from
134 134 current or specified device /boot/menu.lst file activates specified BE by
135 135 unloading modules, setting currdev and running start to load configuration.
136 136 : beadm ( -- ) ( throws: abort ) 0= if ( interpreted ) get_arguments then
137 137
138 138 dup 0= if ." Usage:" cr ." beadm activate {beName
139 139 [device] | device}" cr ." beadm list [device]" cr ." Use lsdev
140 140 to get device names." cr drop exit then First argument is
141 141 0 when we're interprated. See support.4th for get_arguments reading the
142 142 rest of the line and parsing it stack: argN lenN ... arg1 len1 N rotate
143 143 arg1 len1, dont use argv[] as we want to get arg1 out of stack -rot 2dup
144 144
145 145 s" list" compare-insensitive 0= if ( list ) 2drop argc 1 =
146 146 if ( list currdev ) add dev to list of args and switch to case
147 147 2 current-dev rot 1 + then 2 = if ( list
148 148 device ) list-dev exit then ." too many arguments" cr abort then
149 149 s" activate" compare-insensitive 0= if ( activate ) argc 1 = if (
150 150 missing be ) drop ." missing bName" cr abort then
151 151 argc 2 = if ( activate be ) need to set arg list into
152 152 proper order 1+ >R save argc+1 to return stack
153 153
154 154 if the prefix is fd, cd, net or disk and we have :
155 155 in the name, it is device and inject empty be name
156 156 over 2 s" fd" compare 0= >R over 2 s" cd" compare
157 157 0= R> or >R over 3 s" net" compare 0= R> or >R
158 158 over 4 s" disk" compare 0= R> or if ( prefix is fd
159 159 or cd or net or disk ) 2dup [char] : strchr nip
160 160 if ( its : in name ) true
161 161 else false
162 162 then else false
163 163 then
164 164
165 165 if ( it is device name ) 0 0 R>
166 166 else add device, swap with be and receive
167 167 argc current-dev 2swap R> then
168 168 then 3 = if ( activate be device ) activate-dev exit then
169 169 ." too many arguments" cr abort then ." Unknown argument" cr
170 170 abort ;
171 171
172 172 also forth definitions also builtins
173 173
174 174 make beadm available as user command. builtin: beadm
175 175
176 176 count the pages of BE list leave FALSE in stack in case of error : be-pages
177 177 ( -- flag ) 1 local flag 0 0 2local currdev 0 0 2local title end-
178 178 locals
179 179
180 180 current-dev menu.lst 2dup 2>R 0 to end_of_file? O_RDONLY fopen fd
181 181 ! 2R> drop free-memory reset_line_reading fd @ -1 = if FALSE else
182 182 s" currdev" getenv over ( addr len addr ) 4
183 183 s" zfs:" compare 0= if 5 - len -= 5
184 184 swap 4 + addr += 4 swap to currdev
185 185 then
186 186
187 187 0 begin end_of_file? 0= while
188 188 read_line get_name_value s"
189 189 title" name_buffer strget compare 0= if 1+ then
190 190
191 191 flag if check for title value_buffer
192 192 strget strdup to title free_buffers read_line get
193 193 bootfs get_name_value value_buffer
194 194 strget currdev compare 0= if title s" zfs_be_active"
195 195 setenv 0 to flag then
196 196 title drop free-memory 0 0 to title
197 197 free_buffers else
198 198 free_buffers read_line get bootfs
199 199 then repeat fd @ fclose line_buffer
200 200 strfree read_buffer strfree 5 /mod swap dup page_remainder !
201 201 save remainder if 1+ then dup page_count !
202 202 save count n2s s" zfs_be_pages" setenv
203 203 TRUE then ;
204 204
205 205 : be-set-page { | entry count n device -- } page_count @ 0= if be-pages
206 206 page_count @ 0= if exit then then
207 207
208 208 0 to device 1 s" zfs_be_currpage" getenvn 5 * page_count @ 5 *
209 209 page_remainder @ if 5 page_remainder @ - - then swap -
210 210 dup to entry 0 < if entry 5 + to count 0 to entry
211 211 else 5 to count then current-dev menu.lst 2dup 2>R
212 212 0 to end_of_file? O_RDONLY fopen fd ! 2R> drop free-memory
213 213 reset_line_reading fd @ -1 = if EOPEN throw then 0 to n begin
214 214 end_of_file? 0= while n entry < if
215 215 read_line skip title read_line skip
216 216 bootfs n 1+ to n else Use reverse loop
217 217 to display descending order for BE list. 0 count
218 218 1- do read_line read title line
219 219 get_name_value value_buffer strget
220 220 52 i + ascii 4 + i s"
221 221 bootenvmenu_caption[4]" 20 +c! setenv value_buffer strget
222 222 52 i + ascii 4 + i s"
223 223 bootenvansi_caption[4]" 20 +c! setenv
224 224
225 225 free_buffers read_line read value
226 226 line get_name_value
227 227
228 228 set menu entry command name_buffer strget
229 229 s" chain" compare 0= if s"
230 230 set_be_chain" else s" set_bootenv"
231 231 then 52 i + ascii 4 + i
232 232 s" bootenvmenu_command[4]" 20 +c! setenv
233 233
234 234 set device name name_buffer strget s"
235 235 chain" compare 0= if \[u00A0]for
236 236 chain, use the value as is value_buffer strget
237 237 else check last char in the name
238 238 value_buffer strget 2dup + c@
239 239 [char] : <> if make
240 240 zfs device name swap drop
241 241 5 + allocate if
242 242 ENOMEM throw
243 243 then s" zfs:" (
244 244 addr addr' len' ) 2 pick swap move ( addr )
245 245 dup to device 4
246 246 value_buffer strget strcat ( addr len )
247 247 s" :" strcat then
248 248 then
249 249
250 250 52 i + ascii 4 + i s"
251 251 bootenv_root[4]" 13 +c! setenv device free-memory 0 to
252 252 device free_buffers -1 +loop
253 253
254 254 5 count do unset unused entries 52
255 255 i + ascii 4 + i dup s" bootenvmenu_caption[4]" 20
256 256 +c! unsetenv dup s" bootenvansi_caption[4]" 20 +c! unsetenv
257 257 dup s" bootenvmenu_command[4]" 20 +c! unsetenv
258 258 s" bootenv_root[4]" 13 +c! unsetenv loop
259 259
260 260 1 to end_of_file? we are done then repeat
261 261 fd @ fclose line_buffer strfree read_buffer strfree ;
262 262
263 263
264 264
265 265 August 28, 2019 ()
↓ open down ↓ |
124 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX