summaryrefslogtreecommitdiff
path: root/pkg/specgen/utils_linux.go
blob: d8e4cbae378caf9e45efcd6bc86ed46df2591bf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//go:build linux
// +build linux

package specgen

import (
	"fmt"

	spec "github.com/opencontainers/runtime-spec/specs-go"
	"golang.org/x/sys/unix"
)

// FinishThrottleDevices takes the temporary representation of the throttle
// devices in the specgen and looks up the major and major minors. it then
// sets the throttle devices proper in the specgen
func FinishThrottleDevices(s *SpecGenerator) error {
	if s.ResourceLimits == nil {
		s.ResourceLimits = &spec.LinuxResources{}
	}
	if bps := s.ThrottleReadBpsDevice; len(bps) > 0 {
		if s.ResourceLimits.BlockIO == nil {
			s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
		}
		for k, v := range bps {
			statT := unix.Stat_t{}
			if err := unix.Stat(k, &statT); err != nil {
				return fmt.Errorf("could not parse throttle device at %s: %w", k, err)
			}
			v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
			v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
			if s.ResourceLimits.BlockIO == nil {
				s.ResourceLimits.BlockIO = new(spec.LinuxBlockIO)
			}
			s.ResourceLimits.BlockIO.ThrottleReadBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleReadBpsDevice, v)
		}
	}
	if bps := s.ThrottleWriteBpsDevice; len(bps) > 0 {
		if s.ResourceLimits.BlockIO == nil {
			s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
		}
		for k, v := range bps {
			statT := unix.Stat_t{}
			if err := unix.Stat(k, &statT); err != nil {
				return fmt.Errorf("could not parse throttle device at %s: %w", k, err)
			}
			v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
			v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
			s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice, v)
		}
	}
	if iops := s.ThrottleReadIOPSDevice; len(iops) > 0 {
		if s.ResourceLimits.BlockIO == nil {
			s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
		}
		for k, v := range iops {
			statT := unix.Stat_t{}
			if err := unix.Stat(k, &statT); err != nil {
				return fmt.Errorf("could not parse throttle device at %s: %w", k, err)
			}
			v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
			v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
			s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice, v)
		}
	}
	if iops := s.ThrottleWriteIOPSDevice; len(iops) > 0 {
		if s.ResourceLimits.BlockIO == nil {
			s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
		}
		for k, v := range iops {
			statT := unix.Stat_t{}
			if err := unix.Stat(k, &statT); err != nil {
				return fmt.Errorf("could not parse throttle device at %s: %w", k, err)
			}
			v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
			v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
			s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice, v)
		}
	}
	return nil
}

func WeightDevices(specgen *SpecGenerator) error {
	devs := []spec.LinuxWeightDevice{}
	if specgen.ResourceLimits == nil {
		specgen.ResourceLimits = &spec.LinuxResources{}
	}
	for k, v := range specgen.WeightDevice {
		statT := unix.Stat_t{}
		if err := unix.Stat(k, &statT); err != nil {
			return fmt.Errorf("failed to inspect '%s' in --blkio-weight-device: %w", k, err)
		}
		dev := new(spec.LinuxWeightDevice)
		dev.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
		dev.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
		dev.Weight = v.Weight
		devs = append(devs, *dev)
		if specgen.ResourceLimits.BlockIO == nil {
			specgen.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
		}
		specgen.ResourceLimits.BlockIO.WeightDevice = devs
	}
	return nil
}