Add ability to set user properties while changing encryption key

`zfs change-key` changes the key used to encrypt a ZFS dataset. When
used programmatically, it may be useful to track some external state
related to the key in a user property. E.g. a generation number,
expiration date, or application-specific source of the key.

This can be done today by running `zfs set user:prop=value` before or
after running `zfs change-key`. However, this introduces a race
condition where the property may not be set even though the key has
changed, or vice versa (depending on the order the commands are
executed).

This can be addressed by using a channel program (`zfs program`) which
calls both `zfs.sync.change_key()` and `zfs.sync.set_prop()`, changing
the property and key atomically. However, it is nontrivial to write such
a channel program to handle error cases, and provide the new key
securely (e.g. without logging it).

This issue proposes to enhance `zfs change-key` to be able to atomically
set user properties while changing the encryption key. Currently `zfs
change-key` accepts `-o property=value` arguments, but the only valid
properties are keylocation, keyformat, and pbkdf2iters. We will enhance
this to also allow user properties, e.g. `-o user:prop=value`. User
properties will also be allowed when using `zfs change-key -i` to
inherit the key from the parent dataset.

Original-patch-by: Matthew Ahrens <matt@mahrens.org>
External-issue: https://www.illumos.org/issues/17847

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #18407
This commit is contained in:
Rob Norris
2026-04-08 10:17:40 +10:00
committed by GitHub
parent 4fec688987
commit e635d27ebc
10 changed files with 146 additions and 35 deletions
+2 -1
View File
@@ -190,7 +190,8 @@ tags = ['functional', 'cli_root', 'zfs_bookmark']
[tests/functional/cli_root/zfs_change-key]
tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location',
'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones']
'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones',
'zfs_change-key_userprop']
tags = ['functional', 'cli_root', 'zfs_change-key']
[tests/functional/cli_root/zfs_clone]