Skip to content

Commit 712960c

Browse files
addressed review comments
1 parent 6ad77f1 commit 712960c

File tree

8 files changed

+660
-373
lines changed

8 files changed

+660
-373
lines changed

pkg/util/cns.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,26 @@ type ControllerID struct {
1818
BusNumber int32
1919
}
2020

21+
var (
22+
// MaxSCSISlotsByType is the maximum number of devices per SCSI controller
23+
// type.
24+
// Note: The controller itself occupies one slot.
25+
MaxSCSISlotsByType = map[vmopv1.SCSIControllerType]int32{
26+
vmopv1.SCSIControllerTypeParaVirtualSCSI: 63, // 64 targets - 1 for controller
27+
vmopv1.SCSIControllerTypeBusLogic: 15, // 16 targets - 1 for controller
28+
vmopv1.SCSIControllerTypeLsiLogic: 15, // 16 targets - 1 for controller
29+
vmopv1.SCSIControllerTypeLsiLogicSAS: 15, // 16 targets - 1 for controller
30+
}
31+
32+
// MaxSCSIControllersPerVM is the maximum number of SCSI controllers
33+
// allowed per VM. (4 controllers, indexed 0-3).
34+
MaxSCSIControllersPerVM = int32(4)
35+
36+
// SCSIControllerUnitNumber is the unit number reserved for SCSI controller
37+
// on its own bus.
38+
SCSIControllerUnitNumber = int32(7)
39+
)
40+
2141
// CNSAttachmentNameForVolume returns the name of the CnsNodeVmAttachment based
2242
// on the VM and Volume name.
2343
// This matches the naming used in previous code but there are situations where
@@ -57,3 +77,64 @@ func SanitizeCNSErrorMessage(msg string) string {
5777

5878
return msg
5979
}
80+
81+
// MaxSlotsForControllerType returns the maximum number of slots for a
82+
// controller type.
83+
// If the controller type is unknown, it defaults to ParaVirtual.
84+
//
85+
// PVSCSI supports 64 devices per controller starting
86+
// vSphere 6.7+. Since min supported vSphere version is >=
87+
// 8.0, this is a safe assumption.
88+
//
89+
// For all these sub-types, the max slots is 1 less than the capacity
90+
// since SCSI slot 7 is reserved for the controller itself.
91+
func MaxSlotsForControllerType(ctrlType vmopv1.SCSIControllerType) int32 {
92+
if _, ok := MaxSCSISlotsByType[ctrlType]; !ok {
93+
// Unknown controller type, default to ParaVirtual
94+
return MaxSCSISlotsByType[vmopv1.SCSIControllerTypeParaVirtualSCSI]
95+
}
96+
97+
return MaxSCSISlotsByType[ctrlType]
98+
}
99+
100+
// ControllerHasAvailableSlots checks if a controller has available slots for
101+
// new devices.
102+
func ControllerHasAvailableSlots(
103+
controller *vmopv1.SCSIControllerSpec,
104+
busNumber int32,
105+
statusDeviceCounts, volumeAssignments map[int32]int32,
106+
) bool {
107+
// Get max slots for this controller type
108+
maxSlots := MaxSlotsForControllerType(controller.Type)
109+
110+
// Get current device count from status
111+
currentDevices := statusDeviceCounts[busNumber]
112+
113+
// Get number of volumes already assigned to this controller in this mutation
114+
assignedVolumes := volumeAssignments[busNumber]
115+
116+
// Check if adding one more volume would exceed capacity
117+
return (currentDevices + assignedVolumes + 1) <= maxSlots
118+
}
119+
120+
// FindControllerWithSharing finds a controller with the specified sharing mode
121+
// and has available slots.
122+
// Returns the controller if found, nil otherwise.
123+
func FindControllerWithSharing(
124+
sharingMode vmopv1.VirtualControllerSharingMode,
125+
controllers map[int32]*vmopv1.SCSIControllerSpec,
126+
statusDeviceCounts, volumeAssignments map[int32]int32,
127+
) *vmopv1.SCSIControllerSpec {
128+
129+
for busNum := range MaxSCSIControllersPerVM {
130+
if controller, exists := controllers[busNum]; exists {
131+
if controller.SharingMode == sharingMode &&
132+
ControllerHasAvailableSlots(controller, busNum,
133+
statusDeviceCounts, volumeAssignments) {
134+
return controller
135+
}
136+
}
137+
}
138+
139+
return nil
140+
}

0 commit comments

Comments
 (0)