-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] kdump LUKS support #10
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1004,6 +1004,55 @@ ForwardToConsole=yes | |
EOF | ||
} | ||
|
||
kdump_check_crypt_targets() { | ||
local _luks_dev _count _devuuid _key_desc | ||
declare -a _luks_devs | ||
|
||
_luks_devs=($(get_all_kdump_crypt_dev)) | ||
_count=${#_luks_devs[@]} | ||
|
||
if [[ $_count -lt 1 ]]; then | ||
return | ||
fi | ||
|
||
# This overrides behaviour of 90crypt | ||
inst_hook cmdline 20 "/usr/lib/kdump/kexec-crypt-setup.sh" | ||
|
||
inst cryptsetup | ||
instmods dm_crypt | ||
|
||
mkdir -p $hookdir/initqueue/finished | ||
|
||
for _luks_dev in "${_luks_devs[@]}"; do | ||
_devuuid=$(maj_min_to_uuid "$_luks_dev") | ||
echo "kdump_luks_uuid=${_devuuid} " >"${initdir}/etc/cmdline.d/62kdump_luks.conf" | ||
Comment on lines
+1026
to
+1028
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/>/>>/ ? |
||
|
||
_key_desc=cryptsetup:$_devuuid | ||
|
||
mkdir -p "${initdir}/etc/udev/rules.d/" | ||
{ | ||
printf -- 'ENV{ID_FS_UUID}=="%s", ' "$_devuuid" | ||
printf -- 'RUN+="/sbin/initqueue --settled --unique --onetime ' | ||
printf -- '--name kdump-crypt-target-%%k %s ' "$(command -v cryptsetup)" | ||
printf -- 'luksOpen --volume-key-keyring %s $env{DEVNAME} %s"\n' "%%user:$_key_desc" "luks-$_devuuid" | ||
} >>"${initdir}/etc/udev/rules.d/70-luks-kdump.rules" | ||
Comment on lines
+1030
to
+1038
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the point in having |
||
|
||
|
||
done | ||
|
||
echo >"$initdir/etc/cmdline.d/90crypt.conf" | ||
echo >"$initdir/etc/crypttab" | ||
Comment on lines
+1043
to
+1044
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I understand it correctly, that you are undoing work other dracut modules have done? If so, could you please add a short comment so we still remember it in a couple of years. |
||
|
||
# latest systemd makes /usr read-only by default | ||
mkdir -p "${initdir}/etc/systemd/system.conf.d" | ||
{ | ||
echo "[Manager]" | ||
echo "ProtectSystem=false" | ||
} >>"${initdir}/etc/systemd/system.conf.d/kdump_luks.conf" | ||
Comment on lines
+1047
to
+1051
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same like above. Here-doc? |
||
|
||
dracut_need_initqueue | ||
} | ||
|
||
remove_cpu_online_rule() { | ||
local file=${initdir}/usr/lib/udev/rules.d/40-redhat.rules | ||
|
||
|
@@ -1065,6 +1114,8 @@ install() { | |
# at some point of time. | ||
kdump_check_iscsi_targets | ||
|
||
kdump_check_crypt_targets | ||
|
||
kdump_install_systemd_conf | ||
|
||
# nfs/ssh dump will need to get host ip in second kernel and need to call 'ip' tool, see get_host_ip for more detail | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -711,6 +711,8 @@ load_kdump() | |
chcon -t boot_t "$KDUMP_KERNEL" | ||
fi | ||
|
||
prepare_luks | ||
|
||
ddebug "$KEXEC $KEXEC_ARGS $standard_kexec_args --command-line=$KDUMP_COMMANDLINE --initrd=$TARGET_INITRD $KDUMP_KERNEL" | ||
|
||
# The '12' represents an intermediate temporary file descriptor | ||
|
@@ -1030,6 +1032,53 @@ check_final_action_config() | |
esac | ||
} | ||
|
||
LUKS_SYSFS=/sys/kernel/crash_dm_crypt_keys | ||
reuse_loaded_luks_keys() | ||
{ | ||
local _luks_dev _count _cmds _cmd _state | ||
declare -a _luks_devs | ||
|
||
Comment on lines
+1036
to
+1040
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most of the variables are unused. And even
Just for my understanding, what does reuse do? Does it prevent the kernel to discard the stored keys, when unloading the crash kernel? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On second thought, wouldn't it be safer to simply drop this function and always setup the a new key ring when loading the kdump kernel. It's more expensive but otherwise you could end up in a situation like
which, IIUC, should fail as the key of dev1 is now used to decrypt dev2, which most likely should fail. |
||
_state=$(< $LUKS_SYSFS) | ||
|
||
if [[ $_state == loaded ]]; then | ||
echo -n reuse > $LUKS_SYSFS | ||
return 0 | ||
fi | ||
} | ||
|
||
prepare_luks() | ||
{ | ||
local _luks_dev _count _cmds _cmd _state | ||
declare -a _luks_devs | ||
Comment on lines
+1049
to
+1052
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
_state=$(< $LUKS_SYSFS) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens when |
||
|
||
if [[ $_state == recorded ]]; then | ||
return 0 | ||
elif [[ $_state == reuse ]]; then | ||
return 0 | ||
elif [[ $_state != fresh ]] && [[ $_state != initialized ]]; then | ||
derror "Unknow state about the LUKS keys" | ||
return 1 | ||
fi | ||
Comment on lines
+1056
to
+1063
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not use a switch case, i.e.
Personally I find that easier to read. |
||
|
||
_luks_devs=($(get_all_kdump_crypt_dev)) | ||
_count=${#_luks_devs[@]} | ||
|
||
if [[ $_count -lt 1 ]]; then | ||
return | ||
fi | ||
|
||
if [[ $_state == fresh ]]; then | ||
printf "init %s" "$_count" > $LUKS_SYSFS | ||
fi | ||
|
||
for _luks_dev in "${_luks_devs[@]}"; do | ||
_devuuid=$(maj_min_to_uuid "$_luks_dev") | ||
printf "record cryptsetup:%s" "$_devuuid" > $LUKS_SYSFS | ||
done | ||
} | ||
|
||
Comment on lines
+1072
to
+1081
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no need to use |
||
start() | ||
{ | ||
check_dump_feasibility || return | ||
|
@@ -1702,6 +1751,7 @@ main() | |
exit $EXIT_CODE | ||
;; | ||
reload) | ||
reuse_loaded_luks_keys | ||
reload | ||
;; | ||
restart) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/sh | ||
# | ||
_devuuid=$(getarg kdump_luks_uuid=) | ||
|
||
if [[ -n $_devuuid ]]; then | ||
_key_desc=cryptsetup:$_devuuid | ||
echo -n "$_key_desc" > /sys/kernel/crash_dm_crypt_keys | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the point in having
_count
. It's only been used once and it's not that much shorter than${#_luks_devs[@]}
. Personaly I would use${#_luks_devs[@]}
directly.