From a8cc1eff4cbea011ae359404d90df04cd62b2dd0 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Wed, 23 Feb 2022 20:07:04 +0000 Subject: [PATCH] backport of commit 85c086e1ca24947c2856c486a5c1eb08c6fe2a92 --- nomad/structs/csi.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/nomad/structs/csi.go b/nomad/structs/csi.go index c948499e04b..9540d8445b2 100644 --- a/nomad/structs/csi.go +++ b/nomad/structs/csi.go @@ -411,6 +411,26 @@ func (v *CSIVolume) WriteSchedulable() bool { return false } +// HasFreeReadClaims determines if there are any free read claims available +func (v *CSIVolume) HasFreeReadClaims() bool { + switch v.AccessMode { + case CSIVolumeAccessModeSingleNodeReader: + return len(v.ReadClaims) == 0 + case CSIVolumeAccessModeSingleNodeWriter: + return len(v.ReadClaims) == 0 && len(v.WriteClaims) == 0 + case CSIVolumeAccessModeUnknown: + // This volume was created but not yet claimed, so its + // capabilities have been checked in ReadSchedulable + return true + default: + // For multi-node AccessModes, the CSI spec doesn't allow for + // setting a max number of readers we track node resource + // exhaustion through v.ResourceExhausted which is checked in + // ReadSchedulable + return true + } +} + // HasFreeWriteClaims determines if there are any free write claims available func (v *CSIVolume) HasFreeWriteClaims() bool { switch v.AccessMode { @@ -527,6 +547,10 @@ func (v *CSIVolume) claimRead(claim *CSIVolumeClaim, alloc *Allocation) error { return ErrCSIVolumeUnschedulable } + if !v.HasFreeReadClaims() { + return ErrCSIVolumeMaxClaims + } + // Allocations are copy on write, so we want to keep the id but don't need the // pointer. We'll get it from the db in denormalize. v.ReadAllocs[claim.AllocationID] = nil