Skip to content

Commit a79b9d0

Browse files
committed
zkexec: recovery shell arbitrary kexec wrapper
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
1 parent 6aac531 commit a79b9d0

File tree

7 files changed

+68
-4
lines changed

7 files changed

+68
-4
lines changed

90zfsbootmenu/help-files/134/recovery-shell.pod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
zfsbootmenu
88
Launch the interactive boot environment menu.
99

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

13+
zkexec filesystem kernel initramfs
14+
Directly kexec a kernel and initramfs from a boot environment, allowing any kernel and initramfs to be loaded into memory and
15+
immediately booted.
16+
1317
set_rw_pool pool
1418
Export, then re-import the pool read/write.
1519

90zfsbootmenu/help-files/54/recovery-shell.pod

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@
77
zfsbootmenu
88
Launch the interactive boot environment menu.
99

10-
zfs-chroot zfs filesystem
10+
zfs-chroot filesystem
1111
Enter a chroot of the specified boot environment.
1212
The boot environment is mounted read/write if the
1313
zpool is imported read/write.
1414

15+
zkexec filesystem kernel initramfs
16+
Directly kexec a kernel and initramfs from a boot
17+
environment, allowing any kernel and initramfs to be
18+
loaded into memory and immediately booted.
19+
1520
set_rw_pool pool
1621
Export, then re-import the pool read/write.
1722

90zfsbootmenu/help-files/94/recovery-shell.pod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
zfsbootmenu
88
Launch the interactive boot environment menu.
99

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

14+
zkexec filesystem kernel initramfs
15+
Directly kexec a kernel and initramfs from a boot environment, allowing any kernel and
16+
initramfs to be loaded into memory and immediately booted.
17+
1418
set_rw_pool pool
1519
Export, then re-import the pool read/write.
1620

90zfsbootmenu/module-setup.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ install() {
156156
inst_simple "${moddir}/zfsbootmenu.sh" "/bin/zfsbootmenu" || _ret=$?
157157
inst_simple "${moddir}/zlogtail.sh" "/bin/zlogtail" || _ret=$?
158158
inst_simple "${moddir}/ztrace.sh" "/bin/ztrace" || _ret=$?
159+
inst_simple "${moddir}/zkexec.sh" "/bin/zkexec" || _ret=$?
159160
inst_hook cmdline 95 "${moddir}/zfsbootmenu-parse-commandline.sh" || _ret=$?
160161
inst_hook pre-mount 90 "${moddir}/zfsbootmenu-preinit.sh" || _ret=$?
161162

90zfsbootmenu/zfsbootmenu-completions.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,34 @@ _mount_zfs() {
7070
COMPREPLY=( $( compgen -W "${ZFS[*]}" -- "${COMP_WORDS[1]}" ) )
7171
}
7272
complete -F _mount_zfs mount_zfs
73+
74+
_zkexec() {
75+
local ARG index
76+
COMPREPLY=()
77+
78+
shopt -s nullglob
79+
80+
index="${#COMP_WORDS[@]}"
81+
case "${index}" in
82+
2)
83+
for FS in $( zfs list -H -o name ) ; do
84+
ARG+=("${FS}")
85+
done
86+
87+
COMPREPLY=( $( compgen -W "${ARG[*]}" -- "${COMP_WORDS[1]}" ) )
88+
;;
89+
3|4)
90+
mp="$( mount_zfs "${COMP_WORDS[1]}" )"
91+
[ -d "${mp}/boot" ] || return
92+
93+
for BIN in "${mp}"/boot/* ; do
94+
BIN="${BIN##*/}"
95+
ARG+=("${BIN}")
96+
done
97+
umount "${mp}"
98+
COMPREPLY=( $( compgen -W "${ARG[*]}" -- "${COMP_WORDS[$(( index - 1))]}" ) )
99+
;;
100+
esac
101+
102+
}
103+
complete -F _zkexec zkexec

90zfsbootmenu/zkexec.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
# shellcheck disable=SC1091
4+
[ -f /lib/zfsbootmenu-lib.sh ] && source /lib/zfsbootmenu-lib.sh
5+
6+
if [ $# -ne 3 ] ; then
7+
echo "Usage: $0 filesystem kernel initramfs"
8+
exit
9+
fi
10+
11+
fs="${1}"
12+
kernel="/boot/${2}"
13+
initramfs="/boot/${3}"
14+
15+
kexec_kernel "${fs} ${kernel} ${initramfs}"

pod/online/recovery-shell.pod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ B<zfsbootmenu> - Recovery Shell
1212

1313
Launch the interactive boot environment menu.
1414

15-
=item I<zfs-chroot> B<zfs filesystem>
15+
=item I<zfs-chroot> B<filesystem>
1616

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

19+
=item I<zkexec> B<filesystem> B<kernel> B<initramfs>
20+
21+
Directly I<kexec> a kernel and initramfs from a boot environment, allowing any kernel and initramfs to be loaded into memory and immediately booted.
22+
1923
=item I<set_rw_pool> B<pool>
2024

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

0 commit comments

Comments
 (0)