Changeset View
Standalone View
usr.sbin/bsdinstall/scripts/zfsboot
Show First 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | |||||
GPART_SET_ACTIVE='gpart set -a active -i %s "%s"' | GPART_SET_ACTIVE='gpart set -a active -i %s "%s"' | ||||
GPART_SET_LENOVOFIX='gpart set -a lenovofix "%s"' | GPART_SET_LENOVOFIX='gpart set -a lenovofix "%s"' | ||||
GPART_SET_PMBR_ACTIVE='gpart set -a active "%s"' | GPART_SET_PMBR_ACTIVE='gpart set -a active "%s"' | ||||
GRAID_DELETE='graid delete "%s"' | GRAID_DELETE='graid delete "%s"' | ||||
KLDLOAD='kldload %s' | KLDLOAD='kldload %s' | ||||
LN_SF='ln -sf "%s" "%s"' | LN_SF='ln -sf "%s" "%s"' | ||||
MKDIR_P='mkdir -p "%s"' | MKDIR_P='mkdir -p "%s"' | ||||
MOUNT_TYPE='mount -t %s "%s" "%s"' | MOUNT_TYPE='mount -t %s "%s" "%s"' | ||||
NEWFS_ESP='newfs_msdos -F %s -L "%s" "%s"' | |||||
imp: What does ESP mean? | |||||
Done Inline ActionsEFI System Partition emaste: EFI System Partition | |||||
PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\"" | PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\"" | ||||
PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"' | PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"' | ||||
SHELL_TRUNCATE=':> "%s"' | SHELL_TRUNCATE=':> "%s"' | ||||
SWAP_GMIRROR_LABEL='gmirror label swap %s' | SWAP_GMIRROR_LABEL='gmirror label swap %s' | ||||
SYSCTL_ZFS_MIN_ASHIFT_12='sysctl vfs.zfs.min_auto_ashift=12' | SYSCTL_ZFS_MIN_ASHIFT_12='sysctl vfs.zfs.min_auto_ashift=12' | ||||
UMOUNT='umount "%s"' | UMOUNT='umount "%s"' | ||||
ZFS_CREATE_WITH_OPTIONS='zfs create %s "%s"' | ZFS_CREATE_WITH_OPTIONS='zfs create %s "%s"' | ||||
ZFS_MOUNT='zfs mount "%s"' | ZFS_MOUNT='zfs mount "%s"' | ||||
▲ Show 20 Lines • Show All 623 Lines • ▼ Show 20 Lines | if [ "$ZFSBOOT_BOOT_TYPE" = "UEFI" -o "$ZFSBOOT_BOOT_TYPE" = "BIOS+UEFI" ]; then | ||||
# Enable boot pool if encryption is desired | # Enable boot pool if encryption is desired | ||||
# | # | ||||
[ "$ZFSBOOT_GELI_ENCRYPTION" ] && ZFSBOOT_BOOT_POOL=1 | [ "$ZFSBOOT_GELI_ENCRYPTION" ] && ZFSBOOT_BOOT_POOL=1 | ||||
f_eval_catch $funcname gpart \ | f_eval_catch $funcname gpart \ | ||||
"$GPART_ADD_ALIGN_LABEL_WITH_SIZE" \ | "$GPART_ADD_ALIGN_LABEL_WITH_SIZE" \ | ||||
"$align_small" efiboot$index efi 200M $disk || | "$align_small" efiboot$index efi 200M $disk || | ||||
return $FAILURE | return $FAILURE | ||||
f_eval_catch $funcname gpart "$GPART_BOOTCODE_PARTONLY" \ | |||||
/boot/boot1.efifat 1 $disk || | f_eval_catch $funcname mkdir "$MKDIR_P" \ | ||||
"$BSDINSTALL_TMPETC/esp" || return $FAILURE | |||||
f_eval_catch $funcname newfs_msdos "$NEWFS_ESP" "16" "EFISYS" \ | |||||
allanjudeAuthorUnsubmitted Not Done Inline ActionsI changed this to 'EFISYS' to match https://svnweb.freebsd.org/base?view=revision&revision=332561 allanjude: I changed this to 'EFISYS' to match https://svnweb.freebsd.org/base? | |||||
"/dev/${disk}p1" || return $FAILURE | |||||
f_eval_catch $funcname mount "$MOUNT_TYPE" "msdosfs" \ | |||||
"/dev/${disk}p1" "$BSDINSTALL_TMPETC/esp" || | |||||
return $FAILURE | return $FAILURE | ||||
f_eval_catch $funcname mkdir "$MKDIR_P" \ | |||||
"${BSDINSTALL_TMPETC}/esp/efi/boot" || | |||||
return $FAILURE | |||||
f_eval_catch $funcname cp "cp /boot/loader.efi \ | |||||
${BSDINSTALL_TMPETC}/esp/efi/boot/${ZFSBOOT_ESP_NAME}" || | |||||
Not Done Inline ActionsRemove unnecessary curlies around BSDINSTALL_TMPETC and ZFSBOOT_ESP_NAME variables dteske: Remove unnecessary curlies around `BSDINSTALL_TMPETC` and `ZFSBOOT_ESP_NAME` variables | |||||
Not Done Inline ActionsDon't forget these curlies dteske: Don't forget these curlies | |||||
Not Done Inline ActionsUnparameterized, unquoted use of f_eval_catch. Should add toward top: CP='cp = "%s" "%s"' And then do: f_eval_catch $funcname cp "$CP" /boot/loader.efi "$BSDINSTALL_TMPETC/esp/efi/boot/$ZFSBOOT_ESP_NAME" dteske: Unparameterized, unquoted use of `f_eval_catch`.
Should add toward top:
```CP='cp = "%s"… | |||||
return $FAILURE | |||||
f_eval_catch $funcname echo "echo ${ZFSBOOT_ESP_NAME} > | |||||
${BSDINSTALL_TMPETC}/esp/efi/boot/startup.nsh" || | |||||
Done Inline ActionsCurlies around ZFSBOOT_ESP_NAME and BSDINSTALL_TMPETC. Also, just curious, can either ZFSBOOT_ESP_NAME or BSDINSTALL_TMPETC. Also, this command is malformed. It should be something like this: :> "$BSDINSTALL_TMPETC/esp/efi/boot/startup.nsh f_eval_catch $funcname echo "$ECHO_APPEND" "$ZFSBOOT_ESP_NAME" $BSDINSTALL_TMPETC/esp/efi/boot/startup.sh Or if you want, dup the ECHO_APPEND definition on line 190 of the file to: ECHO_TO='echo "%s" > "%s"' And then use f_eval_catch $funcname echo "$ECHO_TO" "$ZFSBOOT_ESP_NAME" $BSDINSTALL_TMPETC/esp/efi/boot/startup.sh dteske: Curlies around `ZFSBOOT_ESP_NAME` and `BSDINSTALL_TMPETC`.
Also, just curious, can either… | |||||
return $FAILURE | |||||
f_eval_catch $funcname umount "$UMOUNT" "$BSDINSTALL_TMPETC/esp" || | |||||
return $FAILURE | |||||
fi | fi | ||||
Not Done Inline ActionsThis should be spelled something more like f_eval_catch $funcname installboot <mumble> here and for all the places we deal with boot blocks. There's too many places that have way too much knowledge of how to make things bootable. This script knows all kinds of crazy details. nanobsd knows. crochet knows. release/Makefile knows. It's just nuts. I should have installboot up for review this week. imp: This should be spelled something more like
f_eval_catch $funcname installboot <mumble>
here… | |||||
Not Done Inline Actionsinstallboot sounds like analogous to grub2-* utility suite on Linux for abstracting away details. Good or Bad, I have no opinion, just pointing out that Linux has a centralized toolchain for munging boot stuffs. Would be kind of cool to have a centralized toolchain that is specific to our loader. dteske: `installboot` sounds like analogous to `grub2-*` utility suite on Linux for abstracting away… | |||||
Not Done Inline ActionsI agree we should switch to installboot in the future. allanjude: I agree we should switch to installboot in the future. | |||||
if [ "$ZFSBOOT_BOOT_TYPE" = "BIOS" -o "$ZFSBOOT_BOOT_TYPE" = "BIOS+UEFI" ]; then | if [ "$ZFSBOOT_BOOT_TYPE" = "BIOS" -o "$ZFSBOOT_BOOT_TYPE" = "BIOS+UEFI" ]; then | ||||
f_eval_catch $funcname gpart \ | f_eval_catch $funcname gpart \ | ||||
"$GPART_ADD_ALIGN_LABEL_WITH_SIZE" \ | "$GPART_ADD_ALIGN_LABEL_WITH_SIZE" \ | ||||
"$align_small" gptboot$index freebsd-boot \ | "$align_small" gptboot$index freebsd-boot \ | ||||
512k $disk || return $FAILURE | 512k $disk || return $FAILURE | ||||
if [ "$ZFSBOOT_BOOT_TYPE" = "BIOS" ]; then | if [ "$ZFSBOOT_BOOT_TYPE" = "BIOS" ]; then | ||||
f_eval_catch $funcname gpart "$GPART_BOOTCODE_PART" \ | f_eval_catch $funcname gpart "$GPART_BOOTCODE_PART" \ | ||||
▲ Show 20 Lines • Show All 697 Lines • ▼ Show 20 Lines | arm64) | ||||
: ${ZFSBOOT_BOOT_TYPE:=UEFI} | : ${ZFSBOOT_BOOT_TYPE:=UEFI} | ||||
: ${ZFSBOOT_PARTITION_SCHEME:=GPT} | : ${ZFSBOOT_PARTITION_SCHEME:=GPT} | ||||
;; | ;; | ||||
*) | *) | ||||
# If the system was booted with UEFI, set the default boot type to UEFI | # If the system was booted with UEFI, set the default boot type to UEFI | ||||
bootmethod=$( sysctl -n machdep.bootmethod ) | bootmethod=$( sysctl -n machdep.bootmethod ) | ||||
f_dprintf "machdep.bootmethod=[%s]" "$bootmethod" | f_dprintf "machdep.bootmethod=[%s]" "$bootmethod" | ||||
if [ "$bootmethod" = "UEFI" ]; then | if [ "$bootmethod" = "UEFI" ]; then | ||||
: ${ZFSBOOT_BOOT_TYPE:=BIOS+UEFI} | : ${ZFSBOOT_BOOT_TYPE:=BIOS+UEFI} | ||||
Not Done Inline ActionsRemove extraneous new/empty-line dteske: Remove extraneous new/empty-line | |||||
: ${ZFSBOOT_PARTITION_SCHEME:=GPT} | : ${ZFSBOOT_PARTITION_SCHEME:=GPT} | ||||
Done Inline ActionsYou should use this instead: case "${UNAME_m:-$( uname -m )" in which will prevent unnecessary execution of uname(1) in the event that UNAME_m is set (uname(1) will simply return UNAME_m if/when set, meaning the fork-exec to uname(1) is really a waste of time/energy/resources when UNAME_m is set). dteske: You should use this instead:
```case "${UNAME_m:-$( uname -m )" in```
which will prevent… | |||||
Done Inline ActionsI disagree -- for code that has no performance requirement, the effort required for a reader to understand the more complex construction is not worth the minuscule waste of computing resources. Consider that in nearly all cases bsdinstall is invoked from FreeBSD install media, and will not have UNAME_m set. emaste: I disagree -- for code that has no performance requirement, the effort required for a reader to… | |||||
Done Inline ActionsSo you clearly do not install from CDROM wherein a first-time access is costly. Code should never be simplified at the cost of pedantic correctness. Also, your argument flies in the face of consistency within the code (I disagree with simplification, but if you're going to beat that horse, you have to be consistent intnerally within the tool's code and arguably bsdinstall and bsdconfig are both pedantically safe/correct. dteske: So you clearly do not install from CDROM wherein a first-time access is costly. Code should… | |||||
Done Inline ActionsHow often are users installing from a CDROM and overriding UNAME_m? And I don't see what you mean by "pedantic correctness" -- the simpler case is no less correct. emaste: How often are users installing from a CDROM and overriding UNAME_m?
And I don't see what you… | |||||
Done Inline ActionsMore often than you would like to hear. For example, the Vicor Business Unit of FIS Global, Inc. installs from CDROM several hundreds of times per year using an external USB CDROM drive. This is a requirement due to FFIEC regulations that prohibit the use of USB external hard/thumb/flash drives. If simpler is what you want, the new suggestion is as follows: case "$UNAME_M" in Line 33 of the same file: . $BSDCFG_SHARE/common.subr || exit 1 Line 63 of /usr/share/bsdconfig/share/common.subr: export UNAME_M="$( uname -m )" # Machine platform (i.e. i386) This would leverage already-stored information. To answer your question about the meaning of "pedantic correctness": true to the code's intent as defined by the original authors (Allan Jude and myself). I wrote this code and continue to write my code to be performant. An example of targeting performance in scripts that implement a UI you need to make sure that you don't make the following assumptions:
And above all else, externally tracked executables should be minimized in loops. The case of a CDROM and also the case of a slow and/or wonky NFS connection would be excellent examples of where calling "uname" to get information that was already obtained at the start of bsdinstall invocation unnecessarily causes delays in responsiveness. It is often tempting to think "my code doesn't run in a loop, this call to an externally tracked executable is harmless as it is just this one script doing this once." The reality in a structured heirarchical system of menus is that your menu -- even if it exists as a stand-alone application -- may be called in a loop if another menu ties to it and the user doesn't follow what the developer thinks to be the traditional flow (and why should they be prevented from, for example, navigating into and out-of a menu many times before they decide to do something different). Nothing teaches you better coding practice and dilligence in re-using already-available information like trying to do installs via CDROM (wherein the CDROM will spin-down during lengthy UI sessions that operate off of a single invocation of dialog; e.g., --mixed-form invocations) or slow NFS (wherein for example expanding a data center requires installing a remote datacenter by first initizling the local PXE server via some other remote PXE server with a high latency and/or low bandwidth issue given the long-distance). dteske: More often than you would like to hear. For example, the Vicor Business Unit of FIS Global, Inc. | |||||
else | else | ||||
Done Inline Actionsquotes here are superfluous emaste: quotes here are superfluous | |||||
Done Inline ActionsWhen in the argument-space of a command (regardless of whether it is a built-in, externally tracked executable, keyword, or special operator), the double-quotes prevent re-interpolation of the sub-shell response into the argv elements for the given command and thus the double-quotes are not "superfluous" as you may suggest. For example, should the execution of the following return nothing on stdout and an error on stderr, interpolation would result in case in if the code was simply case $( uname -m ) in instead of the situation where the sub-shell itself is quoted. dteske: When in the argument-space of a command (regardless of whether it is a built-in, externally… | |||||
Done Inline ActionsNote the line this comment is on - the superfluous quotes are those on the cases -- arm64, arm, etc. emaste: Note the line this comment is on - the superfluous quotes are those on the cases -- arm64, arm… | |||||
Done Inline ActionsThanks for clarification dteske: Thanks for clarification | |||||
: ${ZFSBOOT_BOOT_TYPE:=BIOS} | : ${ZFSBOOT_BOOT_TYPE:=BIOS} | ||||
: ${ZFSBOOT_PARTITION_SCHEME:=GPT} | : ${ZFSBOOT_PARTITION_SCHEME:=GPT} | ||||
fi | fi | ||||
;; | ;; | ||||
esac | esac | ||||
# | |||||
# The EFI loader installed in the ESP (EFI System Partition) must | |||||
# have the expected name in order to load correctly. | |||||
# | |||||
Done Inline Actionsthis seems a bit strange - I'd expect an amd64 case, and maybe a default that prints an error? emaste: this seems a bit strange - I'd expect an amd64 case, and maybe a default that prints an error? | |||||
Done Inline ActionsPlease condense the stanzas to one line each, remove the unnecessary quotes around the patterns, move the fallback condition inside the case, and eliminate unnecessary underride duplication (if the variable has a value, no need to do the case; when NULL or unset, use case to determine value). Example given: [ "$ZFSBOOT_ESP_NAME" ] || case "${UNAME_m:-$( uname -m )}" in arm64) ZFSBOOT_ESP_NAME=BOOTaa64.efi ;; arm) ZFSBOOT_ESP_NAME=BOOTarm.efi ;; i386) ZFSBOOT_ESP_NAME=BOOTia32.efi ;; *) ZFSBOOT_ESP_NAME=BOOTx64.efi esac dteske: Please condense the stanzas to one line each, remove the unnecessary quotes around the patterns… | |||||
Done Inline ActionsBOOTx64.efi is not a generic choice that should be an else case emaste: BOOTx64.efi is not a generic choice that should be an else case | |||||
Done Inline ActionsI agree with this. As stated earlier (disregarding the syntactical changes), emaste is correct that there should be some error condition in the else case. In other words, make amd64 a stanza in the case-statement and make the fallback * case produce an error when appropriate (e.g., when ESP is required but uname gives us a machine architecture that is unsupported by ESP) dteske: I agree with this. As stated earlier (disregarding the syntactical changes), emaste is correct… | |||||
Done Inline ActionsRemove empty line separating comment from its associated block to which it is attributed dteske: Remove empty line separating comment from its associated block to which it is attributed | |||||
case "$( uname -m )" in | |||||
"arm64") | |||||
: ${ZFSBOOT_ESP_NAME:=BOOTaa64.efi} | |||||
;; | |||||
"arm") | |||||
Not Done Inline Actions*) f_dprintf ... f_die esac dteske: ```
*)
f_dprintf ...
f_die
esac
``` | |||||
: ${ZFSBOOT_ESP_NAME:=BOOTarm.efi} | |||||
;; | |||||
"i386") | |||||
: ${ZFSBOOT_ESP_NAME:=BOOTia32.efi} | |||||
;; | |||||
esac | |||||
: ${ZFSBOOT_ESP_NAME:=BOOTx64.efi} | |||||
# | # | ||||
# Loop over the main menu until we've accomplished what we came here to do | # Loop over the main menu until we've accomplished what we came here to do | ||||
# | # | ||||
while :; do | while :; do | ||||
if ! f_interactive; then | if ! f_interactive; then | ||||
retval=$DIALOG_OK | retval=$DIALOG_OK | ||||
mtag=">>> $msg_install" | mtag=">>> $msg_install" | ||||
▲ Show 20 Lines • Show All 180 Lines • Show Last 20 Lines |
What does ESP mean?