diff options
author | Dan Bungert <[email protected]> | 2025-05-23 16:43:56 -0600 |
---|---|---|
committer | Dan Bungert <[email protected]> | 2025-07-24 10:40:30 -0600 |
commit | 4091113c44cd9c9f1634c7e8599c981aa2178dda (patch) | |
tree | 44f16ec4ba577e7f3d93d6fbb831491f9d2ff443 | |
parent | 2a5390a3436c53bd89226afd73751d3954aaef3d (diff) |
zfs: choose our luks header size
Choosing a luks header size allows us to protect against surprises later
if the detected luks header size changes.
LP: #2107381 LP: #2118578
(cherry picked from commit ac353a34e70c4b916d385c310ecb4f713f49e204)
-rw-r--r-- | curtin/block/zfs.py | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/curtin/block/zfs.py b/curtin/block/zfs.py index 519fa513..bb781380 100644 --- a/curtin/block/zfs.py +++ b/curtin/block/zfs.py @@ -31,6 +31,21 @@ ZFS_DEFAULT_PROPERTIES = { ZFS_UNSUPPORTED_ARCHES = ['i386'] ZFS_UNSUPPORTED_RELEASES = ['precise', 'trusty'] +# The keystore consists of the LUKS header, which is a size we can configure, +# and the usable volume size of the keystore. While the file we store here is +# rather small we leave a little room. In LP: #2107381 we learned that the +# cryptsetup detected offset can vary, so choosing a LUKS header size avoids +# surprises later where luksFormat fails due to insufficient volume size. +# The mechanism behind that: cryptsetup LUKS2_hdr_get_storage_params() decides +# on several values, including offset to the actual usable device space. +# offset may be supplied with the cryptset --offset argument, or it will be +# chosen in a way based on the BLKIOOPT / BLKALIGNOFF ioctls in cryptsetup +# device_topology_alignment(), which is a bit overkill for the keystore, so +# just choose a size and keep it small. +LUKS_HEADER_SIZE = 16 << 20 +USABLE_VOLUME_SIZE = 4 << 20 +KEYSTORE_VOLUME_SIZE = LUKS_HEADER_SIZE + USABLE_VOLUME_SIZE + class ZPoolEncryption: def __init__(self, vdevs, poolname, style, keyfile): @@ -86,9 +101,9 @@ class ZPoolEncryption: # Create the dataset for the keystore. This is a bit special as it # won't be ZFS despite being on the zpool. - keystore_size = util.human2bytes("20M") zfs_create( - self.poolname, "keystore", {"encryption": "off"}, keystore_size, + self.poolname, "keystore", {"encryption": "off"}, + str(KEYSTORE_VOLUME_SIZE), ) keystore_volume = f"/dev/zvol/{self.poolname}/keystore" udevadm_settle(exists=keystore_volume) @@ -97,8 +112,16 @@ class ZPoolEncryption: for vdev in self.vdevs: es.enter_context(util.FlockEx(vdev)) - # cryptsetup format and open this keystore - cmd = ["cryptsetup", "luksFormat", keystore_volume, self.keyfile] + # cryptsetup format and open this keystore. pick a fixed offset + # size, in sectors, to work with the fixed volume size. + cmd = [ + "cryptsetup", + "luksFormat", + "--offset", + str(LUKS_HEADER_SIZE // 512), + keystore_volume, + self.keyfile + ] # strace has shown that udevd does indeed probe this keystore with util.FlockEx(keystore_volume): |