-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
init: split initialization into quasi-idempotent parts
- Loading branch information
Showing
9 changed files
with
302 additions
and
244 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/bin/bash | ||
# vim: softtabstop=2 shiftwidth=2 expandtab | ||
|
||
[ "${ZFSBOOTMENU_INITIALIZATION}" = "yes" ] || return 0 | ||
|
||
# Attempt to load spl normally | ||
if ! _modload="$( modprobe spl 2>&1 )" ; then | ||
zdebug "${_modload}" | ||
|
||
# Capture the filename for spl.ko | ||
_modfilename="$( modinfo -F filename spl )" | ||
|
||
if [ -n "${_modfilename}" ] ; then | ||
zinfo "loading ${_modfilename}" | ||
|
||
# Load with a hostid of 0, so that /etc/hostid takes precedence and | ||
# invalid spl.spl_hostid values are ignored | ||
|
||
# There's a race condition between udev and insmod spl | ||
# insmod failures are no longer a hard failure - they can be because | ||
# 1. spl.ko is already loaded because of the race condition | ||
# 2. there's an invalid parameter or value for spl.ko | ||
|
||
if ! _modload="$( insmod "${_modfilename}" "spl_hostid=0" 2>&1 )" ; then | ||
zwarn "${_modload}" | ||
zwarn "unable to load SPL kernel module; attempting to load ZFS anyway" | ||
fi | ||
fi | ||
fi | ||
|
||
if ! _modload="$( modprobe zfs 2>&1 )" ; then | ||
zerror "${_modload}" | ||
emergency_shell "unable to load ZFS kernel modules" | ||
fi | ||
|
||
udevadm settle |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
# vim: softtabstop=2 shiftwidth=2 expandtab | ||
|
||
[ "${ZFSBOOTMENU_INITIALIZATION}" = "yes" ] || return 0 | ||
|
||
# Write out a default or overridden hostid | ||
if [ -n "${spl_hostid}" ] ; then | ||
if write_hostid "${spl_hostid}" ; then | ||
zinfo "writing /etc/hostid from command line: ${spl_hostid}" | ||
else | ||
# write_hostid logs an error for us, just note the new value | ||
# shellcheck disable=SC2154 | ||
write_hostid "${default_hostid}" | ||
zinfo "defaulting hostid to ${default_hostid}" | ||
fi | ||
elif [ ! -e /etc/hostid ]; then | ||
zinfo "no hostid found on kernel command line or /etc/hostid" | ||
# shellcheck disable=SC2154 | ||
zinfo "defaulting hostid to ${default_hostid}" | ||
write_hostid "${default_hostid}" | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/bin/bash | ||
# vim: softtabstop=2 shiftwidth=2 expandtab | ||
|
||
[ "${ZFSBOOTMENU_INITIALIZATION}" = "yes" ] || return 0 | ||
|
||
# Wait for devices to show up | ||
if [ -n "${zbm_wait_for_devices}" ]; then | ||
IFS=',' read -r -a user_devices <<<"${zbm_wait_for_devices}" | ||
while true; do | ||
FOUND=0 | ||
EXPECTED=0 | ||
missing=() | ||
|
||
for device in "${user_devices[@]}"; do | ||
case "${device}" in | ||
/dev/*) | ||
((EXPECTED=EXPECTED+1)) | ||
if [ -e "${device}" ] ; then | ||
((FOUND=FOUND+1)) | ||
else | ||
missing+=( "$device" ) | ||
fi | ||
;; | ||
*=*) | ||
((EXPECTED=EXPECTED+1)) | ||
path_prefix="/dev/disk/by-${device%=*}" | ||
checkfor="${path_prefix,,}/${device##*=}" | ||
if [ -e "${checkfor}" ] ; then | ||
((FOUND=FOUND+1)) | ||
else | ||
missing+=( "$device" ) | ||
fi | ||
;; | ||
*) | ||
zerror "malformed device: '${device}'" | ||
;; | ||
esac | ||
done | ||
|
||
if [ ${FOUND} -eq ${EXPECTED} ]; then | ||
break | ||
else | ||
if ! timed_prompt -d "${zbm_retry_delay:-5}" \ | ||
-e "to cancel" -m "" \ | ||
-m "$( colorize red "One or more required devices are missing" )" \ | ||
-p "retrying in $( colorize yellow "%0.2d" ) seconds" ; then | ||
for dev in "${missing[@]}" ; do | ||
zerror "required device '${dev}' not found" | ||
done | ||
|
||
break | ||
fi | ||
fi | ||
done | ||
|
||
unset FOUND EXPECTED device path_prefix checkfor | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/bash | ||
# vim: softtabstop=2 shiftwidth=2 expandtab | ||
|
||
[ "${ZFSBOOTMENU_INITIALIZATION}" = "yes" ] || return 0 | ||
|
||
# Import ZBM hooks from an external root, if they exist | ||
if [ -n "${zbm_hook_root}" ]; then | ||
import_zbm_hooks "${zbm_hook_root}" | ||
fi | ||
|
||
# Remove the executable bit from any hooks in the skip list | ||
if zbm_skip_hooks="$( get_zbm_arg zbm.skip_hooks )" && [ -n "${zbm_skip_hooks}" ]; then | ||
zdebug "processing hook skip directives: ${zbm_skip_hooks}" | ||
IFS=',' read -r -a zbm_skip_hooks <<<"${zbm_skip_hooks}" | ||
for _skip in "${zbm_skip_hooks[@]}"; do | ||
[ -n "${_skip}" ] || continue | ||
|
||
for _hook in /libexec/hooks/*.d/*; do | ||
[ -e "${_hook}" ] || continue | ||
if [ "${_skip}" = "${_hook##*/}" ]; then | ||
zinfo "Disabling hook: ${_hook}" | ||
chmod 000 "${_hook}" | ||
fi | ||
done | ||
done | ||
unset _hook _skip | ||
fi | ||
|
||
# Run early setup hooks, if they exist | ||
tput clear | ||
/libexec/zfsbootmenu-run-hooks -once "early-setup.d" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#!/bin/bash | ||
# vim: softtabstop=2 shiftwidth=2 expandtab | ||
|
||
[ "${ZFSBOOTMENU_INITIALIZATION}" = "yes" ] || return 0 | ||
|
||
# If a boot pool is specified, that will be tried first | ||
# shellcheck disable=SC2154 | ||
try_pool="${zbm_prefer_pool}" | ||
zbm_import_attempt=0 | ||
|
||
while true; do | ||
if [ -n "${try_pool}" ]; then | ||
zdebug "attempting to import preferred pool ${try_pool}" | ||
fi | ||
|
||
read_write='' import_pool "${try_pool}" | ||
|
||
# shellcheck disable=SC2154 | ||
if check_for_pools; then | ||
if [ "${zbm_require_pool}" = "only" ]; then | ||
zdebug "only importing ${try_pool}" | ||
break | ||
elif [ -n "${try_pool}" ]; then | ||
# If a single pool was requested and imported, try importing others | ||
try_pool="" | ||
continue | ||
else | ||
# Otherwise, all possible pools were imported, nothing more to try | ||
break | ||
fi | ||
elif [ "${import_policy}" == "hostid" ] && poolmatch="$( match_hostid "${try_pool}" )"; then | ||
zdebug "match_hostid returned: ${poolmatch}" | ||
|
||
spl_hostid="${poolmatch##*;}" | ||
|
||
export spl_hostid | ||
|
||
# Store the hostid to use for for KCL overrides | ||
echo -n "$spl_hostid" > "${BASE}/spl_hostid" | ||
|
||
# If match_hostid succeeds, it has imported *a* pool... | ||
if [ -n "${try_pool}" ] && [ "${zbm_require_pool}" = "only" ]; then | ||
# In "only" pool mode, the import was the sole pool desired; nothing more to do | ||
break | ||
else | ||
# Otherwise, try one more pass to pick up other pools matching this hostid | ||
try_pool="" | ||
continue | ||
fi | ||
elif [ -n "${try_pool}" ] && [ -z "${zbm_require_pool}" ]; then | ||
# If a specific pool was tried unsuccessfully but is not a requirement, | ||
# allow another pass to try any other importable pools | ||
try_pool="" | ||
continue | ||
fi | ||
|
||
zbm_import_attempt="$((zbm_import_attempt + 1))" | ||
zinfo "unable to import a pool on attempt ${zbm_import_attempt}" | ||
|
||
# Just keep retrying after a delay until the user presses ESC | ||
if timed_prompt -d "${zbm_retry_delay:-5}" \ | ||
-p "Unable to import $( colorize magenta "${try_pool:-pool}" ), retrying in $( colorize yellow "%0.2d" ) seconds" \ | ||
-r "to retry immediately" \ | ||
-e "for a recovery shell"; then | ||
continue | ||
fi | ||
|
||
log_unimportable | ||
# Allow the user to attempt recovery | ||
emergency_shell "unable to successfully import a pool" | ||
done | ||
|
||
# restrict read-write access to any unhealthy pools | ||
while IFS=$'\t' read -r _pool _health; do | ||
if [ "${_health}" != "ONLINE" ]; then | ||
echo "${_pool}" >> "${BASE}/degraded" | ||
zerror "prohibiting read/write operations on ${_pool}" | ||
fi | ||
done <<<"$( zpool list -H -o name,health )" | ||
unset _pool _health | ||
|
||
zdebug && zdebug "$( zreport )" | ||
|
||
unsupported=0 | ||
while IFS=$'\t' read -r _pool _property; do | ||
if [[ "${_property}" =~ "unsupported@" ]]; then | ||
zerror "unsupported property: ${_property}" | ||
if ! grep -q "${_pool}" "${BASE}/degraded" >/dev/null 2>&1 ; then | ||
echo "${_pool}" >> "${BASE}/degraded" | ||
fi | ||
unsupported=1 | ||
fi | ||
done <<<"$( zpool get all -H -o name,property )" | ||
|
||
if [ "${unsupported}" -ne 0 ]; then | ||
zerror "Unsupported features detected, Upgrade ZFS modules in ZFSBootMenu with generate-zbm" | ||
timed_prompt -m "$( colorize red 'Unsupported features detected')" \ | ||
-m "$( colorize red 'Upgrade ZFS modules in ZFSBootMenu with generate-zbm')" | ||
fi | ||
unset unsupported | ||
|
||
# Attempt to find the bootfs property | ||
# shellcheck disable=SC2086 | ||
while read -r _bootfs; do | ||
if [ "${_bootfs}" = "-" ]; then | ||
BOOTFS= | ||
else | ||
BOOTFS="${_bootfs}" | ||
break | ||
fi | ||
done <<<"$( zpool list -H -o bootfs "${zbm_prefer_pool:---}" )" | ||
unset _bootfs | ||
|
||
if [ -n "${BOOTFS}" ]; then | ||
export BOOTFS | ||
echo "${BOOTFS}" > "${BASE}/bootfs" | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.