From 357a7271fe3a739bc4e462aa5a8a09c9bfb5df2f Mon Sep 17 00:00:00 2001 From: Praveen M Date: Thu, 28 Mar 2024 17:10:11 +0530 Subject: [PATCH] rbd: add additional space for encrypted volumes issue: when a block-mode pvc is created with encryption enabled there is some space reserved for the encryption metadata. Which doesn't allows users to write extact amount of data that they have requested for. solution: create pvc with extra space needed for the encryption metadata. `GetLuksHeaderSize()` function returns the luks2 encryption metadata(header size). Signed-off-by: Praveen M --- internal/rbd/controllerserver.go | 10 ++++++++++ internal/rbd/rbd_util.go | 19 ++++++++++++++++--- internal/util/cryptsetup.go | 18 +++++++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 3b6c58d06a9a..fc405e430ad3 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -1217,6 +1217,11 @@ func (cs *ControllerServer) CreateSnapshot( return nil, status.Error(codes.Internal, err.Error()) } + // remove the extra size of the LUKS header, if the volume is block encrypted. + if vol.isBlockEncrypted() { + vol.VolSize -= util.GetLuksHeaderSize() + } + return &csi.CreateSnapshotResponse{ Snapshot: &csi.Snapshot{ SizeBytes: vol.VolSize, @@ -1627,6 +1632,11 @@ func (cs *ControllerServer) ControllerExpandVolume( } } + // remove the extra size of the LUKS header, if the volume is block encrypted. + if rbdVol.isBlockEncrypted() { + rbdVol.VolSize -= util.GetLuksHeaderSize() + } + return &csi.ControllerExpandVolumeResponse{ CapacityBytes: rbdVol.VolSize, NodeExpansionRequired: nodeExpansion, diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index 7b37a70eb614..aac2fe2a324c 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -443,8 +443,14 @@ func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er return fmt.Errorf("failed to get IOContext: %w", err) } - err = librbd.CreateImage(pOpts.ioctx, pOpts.RbdImageName, - uint64(util.RoundOffVolSize(pOpts.VolSize)*helpers.MiB), options) + size := uint64(util.RoundOffVolSize(pOpts.VolSize) * helpers.MiB) + + // add the extra size of the LUKS header to the image size if block encryption is enabled. + if pOpts.isBlockEncrypted() { + size += uint64(util.GetLuksHeaderSize()) + } + + err = librbd.CreateImage(pOpts.ioctx, pOpts.RbdImageName, size, options) if err != nil { return fmt.Errorf("failed to create rbd image: %w", err) } @@ -1846,7 +1852,14 @@ func (ri *rbdImage) resize(newSize int64) error { } defer image.Close() - err = image.Resize(uint64(util.RoundOffVolSize(newSize) * helpers.MiB)) + size := uint64(util.RoundOffVolSize(newSize) * helpers.MiB) + + // add the extra size of the LUKS header to the image size if block encryption is enabled. + if ri.isBlockEncrypted() { + size += uint64(util.GetLuksHeaderSize()) + } + + err = image.Resize(size) if err != nil { return err } diff --git a/internal/util/cryptsetup.go b/internal/util/cryptsetup.go index e5669b425337..8fcd3185578c 100644 --- a/internal/util/cryptsetup.go +++ b/internal/util/cryptsetup.go @@ -22,10 +22,22 @@ import ( "os/exec" "strconv" "strings" + + "k8s.io/cloud-provider/volume/helpers" ) // Limit memory used by Argon2i PBKDF to 32 MiB. -const cryptsetupPBKDFMemoryLimit = 32 << 10 // 32768 KiB +const ( + cryptsetupPBKDFMemoryLimit = 32 << 10 // 32768 KiB + luks2MetadataSize = 32 << 7 // 4096 KiB + luks2KeySlotsSize = 32 << 8 // 8192 KiB +) + +func GetLuksHeaderSize() int64 { + size := int64((((2 * luks2MetadataSize) + luks2KeySlotsSize) * helpers.KiB)) + + return size +} // LuksFormat sets up volume as an encrypted LUKS partition. func LuksFormat(devicePath, passphrase string) (string, string, error) { @@ -37,6 +49,10 @@ func LuksFormat(devicePath, passphrase string) (string, string, error) { "luks2", "--hash", "sha256", + "--luks2-metadata-size", + strconv.Itoa(luks2MetadataSize)+"k", + "--luks2-keyslots-size", + strconv.Itoa(luks2KeySlotsSize)+"k", "--pbkdf-memory", strconv.Itoa(cryptsetupPBKDFMemoryLimit), devicePath,