From b7586df88abf2181ef9714ca2713d91c5b94ef93 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 | 4 ++++ internal/rbd/rbd_util.go | 15 ++++++++++++--- internal/util/cryptsetup.go | 18 +++++++++++++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 3b6c58d06a9a..e131d5a41031 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -1627,6 +1627,10 @@ func (cs *ControllerServer) ControllerExpandVolume( } } + 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..8cb9429748c7 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -443,8 +443,12 @@ 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) + 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 +1850,12 @@ 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) + 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..09bd5f61a140 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", + fmt.Sprintf("%sk", strconv.Itoa(luks2MetadataSize)), + "--luks2-keyslots-size", + fmt.Sprintf("%sk", strconv.Itoa(luks2KeySlotsSize)), "--pbkdf-memory", strconv.Itoa(cryptsetupPBKDFMemoryLimit), devicePath,