Skip to content

Commit 32f138f

Browse files
committed
Try to inherit key (encryptionroot) in duplicate_snapshot
A raw send (necessary to preserve properties and avoid a decryption pass on encrypted filesystems) will cause the target to be its own encryption root, which is surprising and probably undesirable. If the source is not its own encryption root, make the target inherit its key from a (common) parent. Closes #225.
1 parent 357aa5e commit 32f138f

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

90zfsbootmenu/zfsbootmenu-lib.sh

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ kexec_kernel() {
792792

793793
duplicate_snapshot() {
794794
local selected target target_parent pool recv_args
795-
local encroot keylocation
795+
local fs encroot keylocation
796796

797797
selected="${1}"
798798
if [ -z "$selected" ]; then
@@ -825,15 +825,19 @@ duplicate_snapshot() {
825825
CLEAR_SCREEN=0 load_key "${target_parent}"
826826
fi
827827

828-
recv_args=( "-u" "-o" "canmount=noauto" "-o" "mountpoint=/" "${target}" )
828+
recv_args=( "-u" "-o" "canmount=noauto" "-o" "mountpoint=/" )
829829

830-
if encroot="$( be_has_encroot "${selected}" )" ; then
830+
if encroot="$( be_has_encroot "${selected}" )"; then
831831
keylocation="$( zfs get -H -o value keylocation "${encroot}" 2>/dev/null )"
832832
if [ -n "${keylocation}" ] && [ "${keylocation}" != "-" ]; then
833833
recv_args+=( "-o" "keylocation=${keylocation}" )
834834
fi
835835
fi
836836

837+
recv_args+=( "${target}" )
838+
839+
echo ""
840+
837841
(
838842
trap 'exit 0' SIGINT
839843
if command -v mbuffer >/dev/null 2>&1; then
@@ -842,7 +846,26 @@ duplicate_snapshot() {
842846
else
843847
zfs send -p -w "${selected}" | zfs recv "${recv_args[@]}"
844848
fi
845-
)
849+
) || return
850+
851+
echo ""
852+
853+
# If the source was encrypted, the raw send will have created a new
854+
# encryption root at the target. Move the encryption root to the parent if
855+
# the source was not its own encryption root.
856+
857+
fs="${selected%@*}"
858+
if [ -z "${encroot}" ] || [ "${encroot}" = "${fs}" ]; then
859+
return 0
860+
fi
861+
862+
if encroot="$( be_has_encroot "${target}" )"; then
863+
if [ "${encroot}" = "${target}" ]; then
864+
# Key must be loaded before changing
865+
CLEAR_SCREEN=0 load_key "${target}"
866+
zfs change-key -i "${target}"
867+
fi
868+
fi
846869
}
847870

848871
# arg1: snapshot name
@@ -2013,14 +2036,14 @@ set_ro_pool() {
20132036
}
20142037

20152038

2016-
# arg1: ZFS filesystem
2039+
# arg1: ZFS filesystem or snapshot
20172040
# prints: name of encryption root, if present
20182041
# returns: 0 if system has an encryption root, 1 otherwise
20192042

20202043
be_has_encroot() {
20212044
local fs pool encroot
20222045

2023-
fs="${1}"
2046+
fs="${1%@*}"
20242047
if [ -z "${fs}" ]; then
20252048
zerror "fs is undefined"
20262049
return 1

0 commit comments

Comments
 (0)