Changeset View
Standalone View
libexec/rc/rc.d/zfskeys
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/bin/sh | |||||||||||||
# PROVIDE: zfskeys | |||||||||||||
# REQUIRE: zpool | |||||||||||||
# BEFORE: zfs zvol | |||||||||||||
. /etc/rc.subr | |||||||||||||
name="zfskeys" | |||||||||||||
desc="Load dataset keys" | |||||||||||||
rcvar="zfskeys_enable" | |||||||||||||
extra_commands="status" | |||||||||||||
start_cmd="load_zfs_keys" | |||||||||||||
stop_cmd="unload_zfs_keys" | |||||||||||||
status_cmd="status_zfs_keys" | |||||||||||||
required_modules="zfs" | |||||||||||||
# Note that zfskeys_datasets must have any character found in IFS escaped. | |||||||||||||
# Forcibly unmounting/unloading only applies to filesystems; ignored for zvols. | |||||||||||||
: ${zfskeys_datasets:=''} | |||||||||||||
: ${zfskeys_timeout:=10} | |||||||||||||
: ${zfskeys_unload_force:='NO'} | |||||||||||||
encode_args() | |||||||||||||
{ | |||||||||||||
shift && [ $# -gt 0 ] && printf "%s\0" "$@" | b64encode -r - | |||||||||||||
} | |||||||||||||
dteske: Current test will fail to pass a very-real (but NULL) positional argument to b64encode. Use… | |||||||||||||
Done Inline Actions
Current test will fail to pass a very-real (but NULL) positional argument to b64encode. Use number of arguments instead of content of arguments to determine whether to encode args or not. Combine into single statement for code efficiency (no need to test number of args if initial shift fails -- i.e., in the case of no args given). Also, the wrong /bin/sh variable is used. "$@" will expand to multiple positional arguments but the %s operator in printf will only take a single string. To make the two match, I suggest "$*" which will squish multiple positional arguments into a single string to fit into printf's %s operator. dteske: Current test will fail to pass a very-real (but NULL) positional argument to b64encode. Use… | |||||||||||||
Not Done Inline Actions
I'm a bit uncertain here; the problem I'm trying to solve is the mangling of $@ in rc, so the real solution would be to handle an arbitrary number of arguments and concatenate those into a null-terminated string. However in this script we only ever expect to see one argument (a dataset), so perhaps saying $1 explicitly after the shift is more appropriate? ltning-freebsd_anduin.net: > Also, the wrong `/bin/sh` variable is used. `"$@"` will expand to multiple positional… | |||||||||||||
Done Inline ActionsI'll be keeping the "$@" here, unless I misunderstood something: $ foofunc() { printf "%s\0" "$@" ; } $ foofunc foo bar baz | xargs -0 -n 1 echo foo bar baz $ ltning-freebsd_anduin.net: I'll be keeping the "$@" here, unless I misunderstood something:
```
$ foofunc() { printf… | |||||||||||||
list_datasets() | |||||||||||||
{ | |||||||||||||
if [ "$zfskeys_args" ]; then | |||||||||||||
echo "$zfskeys_args" | b64decode -r | | |||||||||||||
xargs -0 zfs get -H -s local -o value,name keylocation | |||||||||||||
elif [ ! "$zfskeys_datasets" ]; then | |||||||||||||
Done Inline Actions
Split on pipe (reason: line >80 char) dteske: Split on pipe (reason: line >80 char) | |||||||||||||
zfs get -H -t filesystem,volume -s local -o value,name keylocation | |||||||||||||
Done Inline Actions
Use "NOT" operator; ditch the space before semi-colon (apply globally please). dteske: Use "NOT" operator; ditch the space before semi-colon (apply globally please). | |||||||||||||
else | |||||||||||||
Done Inline Actions
Split on flag (reason: line >80 char) dteske: Split on flag (reason: line >80 char) | |||||||||||||
Done Inline Actions
I land at 75 chars here..? ltning-freebsd_anduin.net: > Split on flag (reason: line >80 char)
I land at 75 chars here..? | |||||||||||||
echo "$zfskeys_datasets" | xargs -n 1 zfs get -H -s local \ | |||||||||||||
-o value,name keylocation | |||||||||||||
Done Inline Actions
Split on flag (reason: line >80 char) dteske: Split on flag (reason: line >80 char) | |||||||||||||
fi | |||||||||||||
} | |||||||||||||
unlock_fs() | |||||||||||||
{ | |||||||||||||
local fs="$1" | |||||||||||||
local kl="$2" | |||||||||||||
Done Inline Actions
Positional arguments should be quoted. dteske: Positional arguments should be quoted. | |||||||||||||
local k="${kl##file://}" | |||||||||||||
Done Inline Actions
Blank line after declarations (apply globally please). dteske: Blank line after declarations (apply globally please). | |||||||||||||
if [ "$k" ] && [ -f "$k" ] && [ -s "$k" ] && [ -r "$k" ]; then | |||||||||||||
if [ "$(zfs get -Ho value keystatus "$fs")" = 'available' ]; then | |||||||||||||
echo "Key already loaded for $fs." | |||||||||||||
elif keytest=$(zfs load-key -n -L "$kl" "$fs" 2>&1); then | |||||||||||||
echo "Loading key for $fs from $kl.." | |||||||||||||
if ! keyload=$(timeout $zfskeys_timeout zfs load-key -L "$kl" "$fs" 2>&1) ; then | |||||||||||||
if [ $? -eq 124 ]; then | |||||||||||||
echo "Timed out loading key from $kl for $fs" | |||||||||||||
else | |||||||||||||
echo "Failed to load key from $kl for $fs:" | |||||||||||||
echo "$keyload" | |||||||||||||
fi | |||||||||||||
fi | |||||||||||||
else | |||||||||||||
echo "Could not verify key from $kl for $fs:" | |||||||||||||
echo "$keytest" | |||||||||||||
fi | |||||||||||||
else | |||||||||||||
echo "Key file $k not found, empty or unreadable. Skipping $fs.." | |||||||||||||
fi | |||||||||||||
} | |||||||||||||
lock_fs() | |||||||||||||
{ | |||||||||||||
local fs=$1 | |||||||||||||
if [ "$(zfs get -Ho value mounted "$fs")" = 'yes' ]; then | |||||||||||||
if checkyesno zfskeys_unload_force ; then | |||||||||||||
zfs unmount -f "$fs" && echo "Forcibly unmounted $fs." | |||||||||||||
else | |||||||||||||
zfs unmount "$fs" && echo "Unmounted $fs." | |||||||||||||
fi | |||||||||||||
fi | |||||||||||||
if [ "$?" -ne 0 ]; then | |||||||||||||
echo "Unmount failed for $fs" | |||||||||||||
elif [ "$(zfs get -Ho value keystatus "$fs")" = 'available' ]; then | |||||||||||||
zfs unload-key "$fs" && echo "Unloaded key for $fs." | |||||||||||||
else | |||||||||||||
echo "No key loaded for $fs." | |||||||||||||
fi | |||||||||||||
} | |||||||||||||
status_zfs_keys() | |||||||||||||
{ | |||||||||||||
local IFS=$(printf "\t") | |||||||||||||
list_datasets | while read kl fs ; do | |||||||||||||
echo "$fs: $(zfs get -Ho value keystatus "$fs")" | |||||||||||||
done | |||||||||||||
} | |||||||||||||
load_zfs_keys() | |||||||||||||
{ | |||||||||||||
local IFS=$(printf "\t") | |||||||||||||
list_datasets | while read kl fs ; do | |||||||||||||
unlock_fs "$fs" "$kl" | |||||||||||||
done | |||||||||||||
} | |||||||||||||
unload_zfs_keys() | |||||||||||||
{ | |||||||||||||
local IFS=$(printf "\t") | |||||||||||||
list_datasets | while read kl fs ; do | |||||||||||||
lock_fs "$fs" | |||||||||||||
done | |||||||||||||
} | |||||||||||||
zfskeys_args=$(encode_args "$@") | |||||||||||||
load_rc_config $name | |||||||||||||
run_rc_command "$1" |
Current test will fail to pass a very-real (but NULL) positional argument to b64encode. Use number of arguments instead of content of arguments to determine whether to encode args or not.