Skip to content

Commit e6e983c

Browse files
committed
WIP
Signed-off-by: Niclas Schad <niclas.schad@stackit.cloud>
1 parent 101b731 commit e6e983c

4 files changed

Lines changed: 58 additions & 31 deletions

File tree

pkg/csi/blockstorage/nodeserver.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -302,26 +302,24 @@ func (ns *nodeServer) NodeGetInfo(ctx context.Context, _ *csi.NodeGetInfoRequest
302302
return nil, status.Errorf(codes.Internal, "[NodeGetInfo] unable to retrieve instance id of node %v", err)
303303
}
304304

305-
flavor, err := ns.Metadata.GetFlavor(ctx)
306-
if err != nil {
307-
return nil, status.Errorf(codes.Internal, "[NodeGetInfo] unable to retrieve flavor of node %v", err)
308-
}
309-
310-
maxVolumesPerNode := DetermineMaxVolumesByFlavor(flavor)
305+
//flavor, err := ns.Metadata.GetFlavor(ctx)
306+
//if err != nil {
307+
// return nil, status.Errorf(codes.Internal, "[NodeGetInfo] unable to retrieve flavor of node %v", err)
308+
//}
311309

312310
// Subtract already mounted Volumes
313-
emptyPCIeRootPorts, err := mount.CountNonVirtioBlockDevices()
311+
emptyPCIeRootPorts, err := mount.CountFreePCIeSlots()
314312
if err != nil {
315313
klog.Errorf("[NodeGetInfo] unable to retrieve PCIe root ports %v", err)
316314
emptyPCIeRootPorts = 0
317315
}
318316

319-
maxVolumesPerNode -= emptyPCIeRootPorts
320-
klog.V(4).Infof("Determined %d PCIe ports occupied by non virtio block devices", emptyPCIeRootPorts)
321-
klog.V(4).Infof("Determined node to support %d volumes", maxVolumesPerNode)
317+
vols, err := mount.CountLocalCSIVolumes(driverName)
318+
if err != nil {
319+
klog.Errorf("[NodeGetInfo] unable to retrieve volume count %v", err)
320+
}
322321

323-
// always subtract one for every SKE node, because they always have a root partition
324-
maxVolumesPerNode -= 1
322+
maxVolumesPerNode := emptyPCIeRootPorts + vols
325323

326324
nodeInfo := &csi.NodeGetInfoResponse{
327325
NodeId: nodeID,

pkg/csi/blockstorage/utils.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ func DetermineMaxVolumesByFlavor(flavor string) int64 {
9090
// The following numbers were specified by the IaaS team. They are based on actual tests.
9191
switch {
9292
case strings.HasPrefix(flavor, "n"):
93-
// Flavors starting with 'n' are nvidia GPU flavors, all GPU VM's can only mount 10 volumes
94-
return 10
93+
// Flavors starting with 'n' are nvidia GPU flavors
94+
return 13
9595
case strings.HasSuffix(flavorParts[0], "2a"):
9696
// AMD 2nd Gen
9797
return 159

pkg/csi/util/mount/mount_darwin.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ func newDeviceStats(statfs *unix.Statfs_t) *DeviceStats {
1818
}
1919
}
2020

21-
func CountNonVirtioBlockDevices() (int64, error) {
21+
func CountLocalCSIVolumes(_ string) (int64, error) {
2222
// not implemented
2323
return 0, nil
2424
}
25+
26+
func CountFreePCIeSlots() (int64, error) {
27+
return 0, nil
28+
}

pkg/csi/util/mount/mount_linux.go

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"path/filepath"
99
"regexp"
10+
"slices"
1011
"strings"
1112

1213
"golang.org/x/sys/unix"
@@ -36,10 +37,9 @@ func newDeviceStats(statfs *unix.Statfs_t) *DeviceStats {
3637
}
3738
}
3839

39-
// CountNonVirtioBlockDevices returns the number of PCIe Root ports who
40-
// are currently occupied by anything else than an VIRTIO 1.0 Block Device
41-
// returns zero when something went wrong
42-
func CountNonVirtioBlockDevices() (int64, error) {
40+
// CountFreePCIeSlots returns the number of PCIe Root ports who
41+
// are currently not occupied by anything.
42+
func CountFreePCIeSlots() (int64, error) {
4343
const pciPath = "/sys/bus/pci/devices"
4444

4545
// Get all PCI devices
@@ -48,7 +48,7 @@ func CountNonVirtioBlockDevices() (int64, error) {
4848
return 0, fmt.Errorf("failed to read PCI bus: %w", err)
4949
}
5050

51-
pcieSlotsOccupiedByNonBlockDevice := 0
51+
freePCIeSlots := 0
5252

5353
for _, dev := range devices {
5454
devPath := filepath.Join(pciPath, dev.Name())
@@ -71,23 +71,48 @@ func CountNonVirtioBlockDevices() (int64, error) {
7171
if err2 != nil {
7272
klog.Errorf("failed to read dir %s : %v", devPath, err2)
7373
}
74-
for _, file := range files {
75-
// Ignore PCI bus directories such as pci001 pci002 and pci010
76-
// Devices must follow <domain:bus:device.function> format
77-
if pciAddressRegex.MatchString(file.Name()) {
78-
isNonBlockDevice := IsNonBlockDevice(devPath, file)
79-
if isNonBlockDevice {
80-
pcieSlotsOccupiedByNonBlockDevice++
81-
}
82-
break
83-
}
74+
hasDownStreamFolder := slices.ContainsFunc(files, func(s os.DirEntry) bool {
75+
return pciAddressRegex.MatchString(s.Name())
76+
})
77+
if !hasDownStreamFolder {
78+
freePCIeSlots += 1
8479
}
8580
} else {
8681
klog.V(4).Infof("skipping class %s: path: %s", class, devPath)
8782
}
8883
}
8984

90-
return int64(pcieSlotsOccupiedByNonBlockDevice), nil
85+
return int64(freePCIeSlots), nil
86+
}
87+
88+
// CountLocalCSIVolumes tries to count how many volumes are mounted for a given driverName.
89+
func CountLocalCSIVolumes(driverName string) (int64, error) {
90+
const kubeletDir = "/var/lib/kubelet"
91+
volumeCount := 0
92+
// The path where Kubelet mounts global tracking directories for a specific CSI driver
93+
targetDir := filepath.Join(kubeletDir, "plugins", "kubernetes.io", "csi", driverName)
94+
95+
if _, err := os.Stat(targetDir); os.IsNotExist(err) {
96+
return 0, nil
97+
} else if err != nil {
98+
return 0, fmt.Errorf("failed to check directory: %w", err)
99+
}
100+
101+
volumes, err := os.ReadDir(targetDir)
102+
if err != nil {
103+
return 0, fmt.Errorf("failed to read dir %s: %w", targetDir, err)
104+
}
105+
for _, vol := range volumes {
106+
// Check if volume has a "globalmount" dir to determine if it's mounted correctly
107+
globalMountPath := filepath.Join(vol.Name(), "globalmount")
108+
if _, err := os.Stat(globalMountPath); os.IsNotExist(err) {
109+
continue
110+
}
111+
112+
volumeCount++
113+
}
114+
115+
return int64(volumeCount), nil
91116
}
92117

93118
func IsNonBlockDevice(devPath string, file os.DirEntry) bool {

0 commit comments

Comments
 (0)