Skip to content

Commit c1d6ce5

Browse files
committed
Support chroot'ing into a snapshot
1 parent 37149d4 commit c1d6ce5

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

90zfsbootmenu/zfs-chroot.sh

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,17 @@ if mountpoint="$( allow_rw=yes mount_zfs "${selected}" )"; then
1717
mount -t proc proc "${mountpoint}/proc"
1818
mount -t sysfs sys "${mountpoint}/sys"
1919
mount -B /dev "${mountpoint}/dev"
20-
mount -B /tmp "${mountpoint}/var/tmp"
20+
mount -B /tmp "${mountpoint}/tmp"
2121
mount -t devpts pts "${mountpoint}/dev/pts"
2222

23-
tput clear
24-
tput cnorm
25-
2623
pool="${selected%%/*}"
2724

2825
if is_writable "${pool}"; then
29-
echo "${selected} is mounted read/write"
26+
echo -n "${selected} is mounted read/write"
3027
else
31-
echo "${selected} is mounted read-only"
28+
echo -n "${selected} is mounted read-only"
3229
fi
30+
echo -e ", /tmp is shared and read/write\n"
3331

3432
if [ -f "${mountpoint}/bin/bash" ]; then
3533
_SHELL="/bin/bash"

90zfsbootmenu/zfsbootmenu-lib.sh

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ zerror() {
5151
# If the filesystem is locked, this method fails without attempting unlock
5252

5353
mount_zfs() {
54-
local fs rwo mnt ret pool
54+
local fs rwo mnt ret pool is_snapshot
5555

5656
fs="${1}"
5757
if be_is_locked "${fs}" >/dev/null; then
@@ -62,25 +62,35 @@ mount_zfs() {
6262
mnt="${BASE}/${fs}/mnt"
6363
test -d "${mnt}" || mkdir -p "${mnt}"
6464

65+
# @ always denotes a snapshot
66+
if [[ "${fs}" =~ @ ]]; then
67+
is_snapshot=1
68+
fi
69+
6570
# filesystems are readonly by default, but read-write mounts may be requested
6671
rwo="ro"
6772
# shellcheck disable=SC2154
6873
if [ -n "${allow_rw}" ]; then
6974
pool="${fs%%/*}"
70-
if is_writable "${pool}"; then
75+
if is_writable "${pool}" && [ -z "${is_snapshot}" ]; then
7176
rwo="rw"
7277
else
73-
zwarn "read-write mount of ${fs} forbidden, pool ${pool} is not writable"
78+
if [ -n "${is_snapshot}" ]; then
79+
zwarn "read-write mount of ${fs} forbidden, filesystem is a snapshot"
80+
else
81+
zwarn "read-write mount of ${fs} forbidden, pool ${pool} is not writable"
82+
fi
7483
fi
7584
fi
7685

77-
# zfsutil is required for non-legacy mounts and omitted for legacy mounts
78-
if [ "x$(zfs get -H -o value mountpoint "${fs}")" = "xlegacy" ]; then
86+
# zfsutil is required for non-legacy mounts and omitted for legacy mounts or snapshots
87+
if [ "x$(zfs get -H -o value mountpoint "${fs}")" = "xlegacy" ] || [ -n "${is_snapshot}" ]; then
7988
zdebug "mounting ${fs} at ${mnt} (${rwo})"
8089
mount -o "${rwo}" -t zfs "${fs}" "${mnt}"
8190
ret=$?
8291
else
8392
zdebug "mounting ${fs} at ${mnt} (${rwo}) with zfsutil"
93+
zdebug "mount -o zfsutil,${rwo} -t zfs ${fs} ${mnt}"
8494
mount -o "zfsutil,${rwo}" -t zfs "${fs}" "${mnt}"
8595
ret=$?
8696
fi
@@ -239,11 +249,12 @@ draw_snapshots() {
239249

240250
header="$( header_wrap \
241251
"[ENTER] duplicate" "[ESC] back" "" \
242-
"[ALT+D] show diff" "[ALT+X] clone and promote" "[ALT+C] clone only" "[ALT+H] help" )"
252+
"[ALT+D] show diff" "[ALT+E] chroot" "" \
253+
"[ALT+X] clone and promote" "[ALT+C] clone only" "[ALT+H] help" )"
243254

244255
if ! selected="$( zfs list -t snapshot -H -o name "${benv}" |
245256
HELP_SECTION=SNAPSHOT ${FUZZYSEL} --prompt "Snapshot > " \
246-
--tac --expect=alt-x,alt-c,alt-d \
257+
--tac --expect=alt-x,alt-c,alt-d,alt-e \
247258
--preview="/libexec/zfsbootmenu-preview ${BASE} ${benv} ${BOOTFS}" \
248259
--preview-window="up:${PREVIEW_HEIGHT}" \
249260
--header="${header}" )"; then
@@ -1433,6 +1444,22 @@ populate_be_list() {
14331444
return $ret
14341445
}
14351446

1447+
# arg1: ZFS filesystem
1448+
# prints: nothing
1449+
# returns: nothing
1450+
1451+
zfs_chroot() {
1452+
local fs
1453+
fs="${1}"
1454+
[ -n "${fs}" ] || return
1455+
1456+
tput clear
1457+
tput cnorm
1458+
1459+
zdebug "chroot environment: ${fs}"
1460+
/bin/bash -c "zfs-chroot ${fs}"
1461+
}
1462+
14361463

14371464
# arg1: message
14381465
# prints: nothing

90zfsbootmenu/zfsbootmenu.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ while true; do
186186
# Return to snapshot submenu, don't redraw main menu
187187
BE_SELECTED=1
188188
continue
189+
;;
190+
"alt-e")
191+
zfs_chroot "${selected_snap}"
192+
BE_SELECTED=1
193+
continue
189194
;;
190195
# Check available space early in the process
191196
"enter")
@@ -281,11 +286,7 @@ while true; do
281286
fi
282287
;;
283288
"alt-c")
284-
tput clear
285-
tput cnorm
286-
zdebug "chroot environment: ${selected_be}"
287-
echo "Entering chroot for ${selected_be}"
288-
/bin/bash -c "zfs-chroot ${selected_be}"
289+
zfs_chroot "${selected_be}"
289290
;;
290291
esac
291292
done

0 commit comments

Comments
 (0)