Skip to content

Commit

Permalink
zkexec: recovery shell arbitrary kexec wrapper
Browse files Browse the repository at this point in the history
zkexec is designed to allow a user to easily kexec any kernel and
initramfs found in a boot environment. It will tab complete any file in
/boot in the ZFS file system provided as the first argument. No
validation is performed - it willy happily load a kernel as an initramfs
and vice-versa.

Closes #201
  • Loading branch information
zdykstra committed Aug 28, 2021
1 parent 6aac531 commit a79b9d0
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
6 changes: 5 additions & 1 deletion 90zfsbootmenu/help-files/134/recovery-shell.pod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
zfsbootmenu
Launch the interactive boot environment menu.

zfs-chroot zfs filesystem
zfs-chroot filesystem
Enter a chroot of the specified boot environment. The boot environment is mounted read/write if the zpool is imported read/write.

zkexec filesystem kernel initramfs
Directly kexec a kernel and initramfs from a boot environment, allowing any kernel and initramfs to be loaded into memory and
immediately booted.

set_rw_pool pool
Export, then re-import the pool read/write.

Expand Down
7 changes: 6 additions & 1 deletion 90zfsbootmenu/help-files/54/recovery-shell.pod
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
zfsbootmenu
Launch the interactive boot environment menu.

zfs-chroot zfs filesystem
zfs-chroot filesystem
Enter a chroot of the specified boot environment.
The boot environment is mounted read/write if the
zpool is imported read/write.

zkexec filesystem kernel initramfs
Directly kexec a kernel and initramfs from a boot
environment, allowing any kernel and initramfs to be
loaded into memory and immediately booted.

set_rw_pool pool
Export, then re-import the pool read/write.

Expand Down
6 changes: 5 additions & 1 deletion 90zfsbootmenu/help-files/94/recovery-shell.pod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
zfsbootmenu
Launch the interactive boot environment menu.

zfs-chroot zfs filesystem
zfs-chroot filesystem
Enter a chroot of the specified boot environment. The boot environment is mounted read/write
if the zpool is imported read/write.

zkexec filesystem kernel initramfs
Directly kexec a kernel and initramfs from a boot environment, allowing any kernel and
initramfs to be loaded into memory and immediately booted.

set_rw_pool pool
Export, then re-import the pool read/write.

Expand Down
1 change: 1 addition & 0 deletions 90zfsbootmenu/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ install() {
inst_simple "${moddir}/zfsbootmenu.sh" "/bin/zfsbootmenu" || _ret=$?
inst_simple "${moddir}/zlogtail.sh" "/bin/zlogtail" || _ret=$?
inst_simple "${moddir}/ztrace.sh" "/bin/ztrace" || _ret=$?
inst_simple "${moddir}/zkexec.sh" "/bin/zkexec" || _ret=$?
inst_hook cmdline 95 "${moddir}/zfsbootmenu-parse-commandline.sh" || _ret=$?
inst_hook pre-mount 90 "${moddir}/zfsbootmenu-preinit.sh" || _ret=$?

Expand Down
31 changes: 31 additions & 0 deletions 90zfsbootmenu/zfsbootmenu-completions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,34 @@ _mount_zfs() {
COMPREPLY=( $( compgen -W "${ZFS[*]}" -- "${COMP_WORDS[1]}" ) )
}
complete -F _mount_zfs mount_zfs

_zkexec() {
local ARG index
COMPREPLY=()

shopt -s nullglob

index="${#COMP_WORDS[@]}"
case "${index}" in
2)
for FS in $( zfs list -H -o name ) ; do
ARG+=("${FS}")
done

COMPREPLY=( $( compgen -W "${ARG[*]}" -- "${COMP_WORDS[1]}" ) )
;;
3|4)
mp="$( mount_zfs "${COMP_WORDS[1]}" )"
[ -d "${mp}/boot" ] || return

for BIN in "${mp}"/boot/* ; do
BIN="${BIN##*/}"
ARG+=("${BIN}")
done
umount "${mp}"
COMPREPLY=( $( compgen -W "${ARG[*]}" -- "${COMP_WORDS[$(( index - 1))]}" ) )
;;
esac

}
complete -F _zkexec zkexec
15 changes: 15 additions & 0 deletions 90zfsbootmenu/zkexec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# shellcheck disable=SC1091
[ -f /lib/zfsbootmenu-lib.sh ] && source /lib/zfsbootmenu-lib.sh

if [ $# -ne 3 ] ; then
echo "Usage: $0 filesystem kernel initramfs"
exit
fi

fs="${1}"
kernel="/boot/${2}"
initramfs="/boot/${3}"

kexec_kernel "${fs} ${kernel} ${initramfs}"
6 changes: 5 additions & 1 deletion pod/online/recovery-shell.pod
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ B<zfsbootmenu> - Recovery Shell

Launch the interactive boot environment menu.

=item I<zfs-chroot> B<zfs filesystem>
=item I<zfs-chroot> B<filesystem>

Enter a chroot of the specified boot environment. The boot environment is mounted I<read/write> if the zpool is imported I<read/write>.

=item I<zkexec> B<filesystem> B<kernel> B<initramfs>

Directly I<kexec> a kernel and initramfs from a boot environment, allowing any kernel and initramfs to be loaded into memory and immediately booted.

=item I<set_rw_pool> B<pool>

Export, then re-import the pool I<read/write>.
Expand Down

0 comments on commit a79b9d0

Please sign in to comment.