Skip to content

Commit da69d2f

Browse files
black-dragon74ceph-csi-bot
authored andcommitted
util: use csi objectuuid for rados locks
CSI vol ids > 100bytes fail with error `ENAMETOOLONG` when acquiring rados lock as ceph sets default value for `osd_max_attr_name_len` to 100. This patch fixes the issue by decomposing the CSI ID and using the ObjectUUID to ensure the lock names are always < 100 bytes ("lock." + UUID + "-mutexlock"" = 51bytes). "lock."(5 bytes) is a prefix applied by Ceph internally for every lock name so we can only pass lock names that are <= 95bytes. The hash based approach is not used to keep things debuggable. Fixes: #5419 Signed-off-by: Niraj Yadav <niryadav@redhat.com>
1 parent fdeb66c commit da69d2f

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

internal/cephfs/nodeserver.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,19 @@ func maybeUnlockFileEncryption(
138138
return nil
139139
}
140140

141-
// Define Mutex Lock variables
141+
// Extract the ObjectUUID from the volume ID to use as the RADOS lock name.
142+
// Using the full ID would exceed Ceph's default osd_max_attr_name_len i.e. 100bytes.
143+
// Ceph also prefixes "lock." (5 bytes) internally to every lock name.
142144
volIDStr := string(volID)
143-
lockName := volIDStr + "-mutexLock"
145+
var csiID util.CSIIdentifier
146+
if err := csiID.DecomposeCSIID(volIDStr); err != nil {
147+
log.ErrorLog(ctx, "failed to decompose volume ID %s: %v", volID, err)
148+
149+
return err
150+
}
151+
objectUUID := csiID.ObjectUUID
152+
// 5(lock.) + 36(uuid) + 10(suffix) = 51 bytes < 100 bytes limit.
153+
lockName := objectUUID + "-mutexLock"
144154
lockDesc := "Lock for " + volIDStr
145155
lockDuration := 150 * time.Second
146156
// Generate a consistent lock cookie for the client using hostname and process ID
@@ -156,7 +166,7 @@ func maybeUnlockFileEncryption(
156166
}
157167
defer ioctx.Destroy()
158168

159-
lock := iolock.NewLock(ioctx, volIDStr, lockName, lockCookie, lockDesc, lockDuration)
169+
lock := iolock.NewLock(ioctx, objectUUID, lockName, lockCookie, lockDesc, lockDuration)
160170
err = lock.LockExclusive(ctx)
161171
if err != nil {
162172
log.ErrorLog(ctx, "failed to create lock for volume ID %s: %v", volID, err)

internal/rbd/encryption.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -549,10 +549,18 @@ func (rv *rbdVolume) RotateEncryptionKey(ctx context.Context) error {
549549
return fmt.Errorf("failed to open ioctx, err: %w", err)
550550
}
551551

552-
// Lock params
553-
lockName := rv.VolID + "-mutexlock"
552+
// Extract the ObjectUUID from the volume ID to use as the RADOS lock name.
553+
// Using the full ID would exceed Ceph's default osd_max_attr_name_len i.e. 100bytes.
554+
// Ceph also prefixes "lock." (5 bytes) internally to every lock name.
555+
var csiID util.CSIIdentifier
556+
if err = csiID.DecomposeCSIID(rv.VolID); err != nil {
557+
return fmt.Errorf("failed to decompose volume ID %s: %w", rv.VolID, err)
558+
}
559+
objectUUID := csiID.ObjectUUID
560+
// 5(lock.) + 36(uuid) + 10(suffix) = 51 bytes < 100 bytes limit.
561+
lockName := objectUUID + "-mutexLock"
554562
lockDesc := "Key rotation mutex lock for " + rv.VolID
555-
lockCookie := rv.VolID + "-enc-key-rotate"
563+
lockCookie := objectUUID + "-enc-key-rotate"
556564

557565
// Keep this a little more than ExecutionTimeout to have some buffer
558566
// for cleanup. If this lock is a part of some gRPC call, the client
@@ -562,7 +570,7 @@ func (rv *rbdVolume) RotateEncryptionKey(ctx context.Context) error {
562570
defer cancel()
563571

564572
// Acquire the exclusive lock based on vol id
565-
lck := lock.NewLock(rv.ioctx, rv.VolID, lockName, lockCookie, lockDesc, lockDuration)
573+
lck := lock.NewLock(rv.ioctx, objectUUID, lockName, lockCookie, lockDesc, lockDuration)
566574
err = lck.LockExclusive(ctx)
567575
if err != nil {
568576
return err

0 commit comments

Comments
 (0)