Skip to content

Commit 466e4d2

Browse files
committed
Allow rollbacks from the snapshot menu
Closes #239.
1 parent eff72d8 commit 466e4d2

File tree

2 files changed

+78
-7
lines changed

2 files changed

+78
-7
lines changed

90zfsbootmenu/zfsbootmenu-lib.sh

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -575,10 +575,10 @@ draw_snapshots() {
575575

576576
header="$( header_wrap "[RETURN] duplicate" "[CTRL+C] clone only" "[CTRL+X] clone and promote" "" \
577577
"[CTRL+N] create new snapshot" "[CTRL+J] jump into chroot" "[CTRL+D] show diff" "" \
578-
"[CTRL+L] view logs" "[CTRL+H] help" "[ESCAPE] back" )"
578+
"[CTRL+L] view logs" " " "[CTRL+H] help" "" "[ESCAPE] back" " " "[CTRL+R] rollback" )"
579579
context="Note: for diff viewer, use tab to select/deselect up to two items"
580580

581-
expects="--expect=alt-x,alt-c,alt-j,alt-o,alt-n"
581+
expects="--expect=alt-x,alt-c,alt-j,alt-o,alt-n,alt-r"
582582

583583
# ${snapshots} must always be defined so that the mod-n handler can be executed
584584
snapshots="$( zfs list -t snapshot -H -o name "${benv}" -S "${sort_key}" )"
@@ -979,6 +979,70 @@ create_snapshot() {
979979
return 0
980980
}
981981

982+
# arg1: snapshot name
983+
# prints: nothing
984+
# returns: 0 on success
985+
986+
rollback_snapshot() {
987+
local snap pool
988+
989+
snap="${1}"
990+
pool="${snap%%/*}"
991+
if [ "${pool}" = "${snap}" ]; then
992+
zerror "unable to determine pool for rollback"
993+
return 1
994+
fi
995+
996+
if ! find_be_kernels "${snap}" >/dev/null; then
997+
color=red delay=10 timed_prompt \
998+
"Snapshot ${snap} has no kernels, will not roll back" \
999+
"Use a recovery shell to manually force rollback"
1000+
return 1
1001+
fi
1002+
1003+
tput clear
1004+
tput cnorm
1005+
tput cup 0 0
1006+
1007+
cat <<-EOF
1008+
WARNING!!!
1009+
1010+
You are attempting to roll back to the snapshot
1011+
1012+
$( colorize "red" "${snap}" )
1013+
1014+
This will DESTROY curent state and all newer snapshots.
1015+
1016+
Type $( colorize "red" "ROLLBACK" ) to proceed with the rollback.
1017+
1018+
Type any other text, or just press enter, to abort.
1019+
1020+
Proceed $( colorize "red" "[No]" ) ?
1021+
EOF
1022+
1023+
decision="$( /libexec/zfsbootmenu-input )"
1024+
if [ "${decision}" != "ROLLBACK" ]; then
1025+
zdebug "aborting rollback by user request"
1026+
return 0
1027+
fi
1028+
1029+
# Re-import pool read/write
1030+
if ! set_rw_pool "${pool}"; then
1031+
zerror "unable to set ${pool} read/write"
1032+
return 1
1033+
fi
1034+
1035+
# Make sure keys are loaded
1036+
CLEAR_SCREEN=1 load_key "${snap}"
1037+
1038+
zdebug "will roll back ${snap}"
1039+
if ! output="$( zfs rollback -r "${snap}" )"; then
1040+
zerror "failed to roll back snapshot ${snap}"
1041+
zerror "${output}"
1042+
return 1
1043+
fi
1044+
}
1045+
9821046
# arg1: selected snapshot
9831047
# arg2: subkey
9841048
# prints: snapshot/filesystem creation prompt
@@ -1003,6 +1067,11 @@ snapshot_dispatcher() {
10031067
fi
10041068
zdebug "subkey: ${subkey}"
10051069

1070+
if [ "${subkey}" = "mod-r" ]; then
1071+
rollback_snapshot "${selected}"
1072+
return
1073+
fi
1074+
10061075
parent_ds="${selected%/*}"
10071076

10081077
# Generally, stripping "/*" from $selected will also drop the snapshot part;
@@ -1016,9 +1085,8 @@ snapshot_dispatcher() {
10161085
fi
10171086
zdebug "parent_ds: ${parent_ds}"
10181087

1019-
# Do space calculations; bail early
1020-
case "${subkey}" in
1021-
"enter")
1088+
if [ "${subkey}" = "enter" ]; then
1089+
# Do space calculations; bail early
10221090
avail_space_exact="$( zfs list -p -H -o available "${parent_ds}" )"
10231091
be_size_exact="$( zfs list -p -H -o refer "${selected}" )"
10241092
leftover_space=$(( avail_space_exact - be_size_exact ))
@@ -1030,8 +1098,7 @@ snapshot_dispatcher() {
10301098
"'${parent_ds}' has ${avail_space} free but needs ${be_size}"
10311099
return 1
10321100
fi
1033-
;;
1034-
esac
1101+
fi
10351102

10361103
# Set prompt, header, existing check prefix
10371104
case "${subkey}" in

pod/online/snapshot-management.pod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ View logs, as indicated by I<[!]>. The indicator will be yellow for warning cond
7575

7676
=back
7777

78+
=item I<[MOD+R]> B<roll back snapshot>
79+
80+
Roll back a boot environment to the selected snapshot. This is a destructive operation that will not proceed without affirmative confirmation.
81+
7882
=head2 AUTHOR
7983

8084
ZFSBootMenu Team L<https://github.com/zbm-dev/zfsbootmenu>

0 commit comments

Comments
 (0)