summaryrefslogtreecommitdiff
path: root/pkg/specgen/utils_linux.go
diff options
context:
space:
mode:
authorCharlie Doern <cdoern@redhat.com>2022-08-09 09:25:03 -0400
committerCharlie Doern <cdoern@redhat.com>2022-09-01 13:02:01 -0400
commit050f3291b9ef8788510b78c543055638275eb20f (patch)
tree327a081bd2243ffcbdf786a940b1dc82d041bea5 /pkg/specgen/utils_linux.go
parent0085fbb488eec30e71e6cced6a06dbdb134e32a6 (diff)
downloadpodman-050f3291b9ef8788510b78c543055638275eb20f.tar.gz
podman-050f3291b9ef8788510b78c543055638275eb20f.tar.bz2
podman-050f3291b9ef8788510b78c543055638275eb20f.zip
implement podman update
podman update allows users to change the cgroup configuration of an existing container using the already defined resource limits flags from podman create/run. The supported flags in crun are: this command is also now supported in the libpod api via the /libpod/containers/<CID>/update endpoint where the resource limits are passed inthe request body and follow the OCI resource spec format –memory –cpus –cpuset-cpus –cpuset-mems –memory-swap –memory-reservation –cpu-shares –cpu-quota –cpu-period –blkio-weight –cpu-rt-period –cpu-rt-runtime -device-read-bps -device-write-bps -device-read-iops -device-write-iops -memory-swappiness -blkio-weight-device resolves #15067 Signed-off-by: Charlie Doern <cdoern@redhat.com>
Diffstat (limited to 'pkg/specgen/utils_linux.go')
-rw-r--r--pkg/specgen/utils_linux.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/pkg/specgen/utils_linux.go b/pkg/specgen/utils_linux.go
new file mode 100644
index 000000000..d8e4cbae3
--- /dev/null
+++ b/pkg/specgen/utils_linux.go
@@ -0,0 +1,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
+}