Skip to content

Commit

Permalink
libct/cg: mv fscommon.{Open,Read,Write}File to cgroups
Browse files Browse the repository at this point in the history
This is a better place as cgroups itself is using these.
Should help with moving more stuff common in between fs and fs2 to
fscommon.

Looks big, but this is just moving the code around:

 fscommon/{fscommon,open}.go -> cgroups/file.go
 fscommon/fscommon_test.go   -> cgroups/file_test.go

There's no functional change.

Signed-off-by: Kir Kolyshkin <[email protected]>
  • Loading branch information
kolyshkin committed Jun 11, 2021
1 parent 93a01cd commit 98a8545
Show file tree
Hide file tree
Showing 26 changed files with 136 additions and 146 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fscommon
package cgroups

import (
"bytes"
"os"
"strings"
"sync"
Expand All @@ -10,6 +11,54 @@ import (
"golang.org/x/sys/unix"
)

// OpenFile opens a cgroup file in a given dir with given flags.
// It is supposed to be used for cgroup files only.
func OpenFile(dir, file string, flags int) (*os.File, error) {
if dir == "" {
return nil, errors.Errorf("no directory specified for %s", file)
}
return openFile(dir, file, flags)
}

// ReadFile reads data from a cgroup file in dir.
// It is supposed to be used for cgroup files only.
func ReadFile(dir, file string) (string, error) {
fd, err := OpenFile(dir, file, unix.O_RDONLY)
if err != nil {
return "", err
}
defer fd.Close()
var buf bytes.Buffer

_, err = buf.ReadFrom(fd)
return buf.String(), err
}

// WriteFile writes data to a cgroup file in dir.
// It is supposed to be used for cgroup files only.
func WriteFile(dir, file, data string) error {
fd, err := OpenFile(dir, file, unix.O_WRONLY)
if err != nil {
return err
}
defer fd.Close()
if err := retryingWriteFile(fd, data); err != nil {
return errors.Wrapf(err, "failed to write %q", data)
}
return nil
}

func retryingWriteFile(fd *os.File, data string) error {
for {
_, err := fd.Write([]byte(data))
if errors.Is(err, unix.EINTR) {
logrus.Infof("interrupted while writing %s to %s", data, fd.Name())
continue
}
return err
}
}

const (
cgroupfsDir = "/sys/fs/cgroup"
cgroupfsPrefix = cgroupfsDir + "/"
Expand Down Expand Up @@ -60,10 +109,7 @@ func prepareOpenat2() error {

// OpenFile opens a cgroup file in a given dir with given flags.
// It is supposed to be used for cgroup files only.
func OpenFile(dir, file string, flags int) (*os.File, error) {
if dir == "" {
return nil, errors.Errorf("no directory specified for %s", file)
}
func openFile(dir, file string, flags int) (*os.File, error) {
mode := os.FileMode(0)
if TestMode && flags&os.O_WRONLY != 0 {
// "emulate" cgroup fs for unit tests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// +build linux

package fscommon
package cgroups

import (
"fmt"
Expand Down
19 changes: 9 additions & 10 deletions libcontainer/cgroups/fs/blkio.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"strings"

"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
)

Expand All @@ -31,41 +30,41 @@ func (s *BlkioGroup) Apply(path string, d *cgroupData) error {
func (s *BlkioGroup) Set(path string, r *configs.Resources) error {
s.detectWeightFilenames(path)
if r.BlkioWeight != 0 {
if err := fscommon.WriteFile(path, s.weightFilename, strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
if err := cgroups.WriteFile(path, s.weightFilename, strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
return err
}
}

if r.BlkioLeafWeight != 0 {
if err := fscommon.WriteFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(r.BlkioLeafWeight), 10)); err != nil {
if err := cgroups.WriteFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(r.BlkioLeafWeight), 10)); err != nil {
return err
}
}
for _, wd := range r.BlkioWeightDevice {
if err := fscommon.WriteFile(path, s.weightDeviceFilename, wd.WeightString()); err != nil {
if err := cgroups.WriteFile(path, s.weightDeviceFilename, wd.WeightString()); err != nil {
return err
}
if err := fscommon.WriteFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil {
if err := cgroups.WriteFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil {
return err
}
}
for _, td := range r.BlkioThrottleReadBpsDevice {
if err := fscommon.WriteFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil {
if err := cgroups.WriteFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil {
return err
}
}
for _, td := range r.BlkioThrottleWriteBpsDevice {
if err := fscommon.WriteFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil {
if err := cgroups.WriteFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil {
return err
}
}
for _, td := range r.BlkioThrottleReadIOPSDevice {
if err := fscommon.WriteFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil {
if err := cgroups.WriteFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil {
return err
}
}
for _, td := range r.BlkioThrottleWriteIOPSDevice {
if err := fscommon.WriteFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil {
if err := cgroups.WriteFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil {
return err
}
}
Expand Down Expand Up @@ -110,7 +109,7 @@ func splitBlkioStatLine(r rune) bool {

func getBlkioStat(dir, file string) ([]cgroups.BlkioStatEntry, error) {
var blkioStats []cgroups.BlkioStatEntry
f, err := fscommon.OpenFile(dir, file, os.O_RDONLY)
f, err := cgroups.OpenFile(dir, file, os.O_RDONLY)
if err != nil {
if os.IsNotExist(err) {
return blkioStats, nil
Expand Down
12 changes: 6 additions & 6 deletions libcontainer/cgroups/fs/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ func (s *CpuGroup) Apply(path string, d *cgroupData) error {

func (s *CpuGroup) SetRtSched(path string, r *configs.Resources) error {
if r.CpuRtPeriod != 0 {
if err := fscommon.WriteFile(path, "cpu.rt_period_us", strconv.FormatUint(r.CpuRtPeriod, 10)); err != nil {
if err := cgroups.WriteFile(path, "cpu.rt_period_us", strconv.FormatUint(r.CpuRtPeriod, 10)); err != nil {
return err
}
}
if r.CpuRtRuntime != 0 {
if err := fscommon.WriteFile(path, "cpu.rt_runtime_us", strconv.FormatInt(r.CpuRtRuntime, 10)); err != nil {
if err := cgroups.WriteFile(path, "cpu.rt_runtime_us", strconv.FormatInt(r.CpuRtRuntime, 10)); err != nil {
return err
}
}
Expand All @@ -56,7 +56,7 @@ func (s *CpuGroup) SetRtSched(path string, r *configs.Resources) error {
func (s *CpuGroup) Set(path string, r *configs.Resources) error {
if r.CpuShares != 0 {
shares := r.CpuShares
if err := fscommon.WriteFile(path, "cpu.shares", strconv.FormatUint(shares, 10)); err != nil {
if err := cgroups.WriteFile(path, "cpu.shares", strconv.FormatUint(shares, 10)); err != nil {
return err
}
// read it back
Expand All @@ -72,20 +72,20 @@ func (s *CpuGroup) Set(path string, r *configs.Resources) error {
}
}
if r.CpuPeriod != 0 {
if err := fscommon.WriteFile(path, "cpu.cfs_period_us", strconv.FormatUint(r.CpuPeriod, 10)); err != nil {
if err := cgroups.WriteFile(path, "cpu.cfs_period_us", strconv.FormatUint(r.CpuPeriod, 10)); err != nil {
return err
}
}
if r.CpuQuota != 0 {
if err := fscommon.WriteFile(path, "cpu.cfs_quota_us", strconv.FormatInt(r.CpuQuota, 10)); err != nil {
if err := cgroups.WriteFile(path, "cpu.cfs_quota_us", strconv.FormatInt(r.CpuQuota, 10)); err != nil {
return err
}
}
return s.SetRtSched(path, r)
}

func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
f, err := fscommon.OpenFile(path, "cpu.stat", os.O_RDONLY)
f, err := cgroups.OpenFile(path, "cpu.stat", os.O_RDONLY)
if err != nil {
if os.IsNotExist(err) {
return nil
Expand Down
6 changes: 3 additions & 3 deletions libcontainer/cgroups/fs/cpuacct.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) {
// Expected format:
// user <usage in ticks>
// system <usage in ticks>
data, err := fscommon.ReadFile(path, cgroupCpuacctStat)
data, err := cgroups.ReadFile(path, cgroupCpuacctStat)
if err != nil {
return 0, 0, err
}
Expand All @@ -116,7 +116,7 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) {

func getPercpuUsage(path string) ([]uint64, error) {
percpuUsage := []uint64{}
data, err := fscommon.ReadFile(path, "cpuacct.usage_percpu")
data, err := cgroups.ReadFile(path, "cpuacct.usage_percpu")
if err != nil {
return percpuUsage, err
}
Expand All @@ -134,7 +134,7 @@ func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) {
usageKernelMode := []uint64{}
usageUserMode := []uint64{}

file, err := fscommon.OpenFile(path, cgroupCpuacctUsageAll, os.O_RDONLY)
file, err := cgroups.OpenFile(path, cgroupCpuacctUsageAll, os.O_RDONLY)
if os.IsNotExist(err) {
return usageKernelMode, usageUserMode, nil
} else if err != nil {
Expand Down
12 changes: 6 additions & 6 deletions libcontainer/cgroups/fs/cpuset.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ func (s *CpusetGroup) Apply(path string, d *cgroupData) error {

func (s *CpusetGroup) Set(path string, r *configs.Resources) error {
if r.CpusetCpus != "" {
if err := fscommon.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil {
if err := cgroups.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil {
return err
}
}
if r.CpusetMems != "" {
if err := fscommon.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil {
if err := cgroups.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil {
return err
}
}
Expand Down Expand Up @@ -175,10 +175,10 @@ func (s *CpusetGroup) ApplyDir(dir string, r *configs.Resources, pid int) error
}

func getCpusetSubsystemSettings(parent string) (cpus, mems string, err error) {
if cpus, err = fscommon.ReadFile(parent, "cpuset.cpus"); err != nil {
if cpus, err = cgroups.ReadFile(parent, "cpuset.cpus"); err != nil {
return
}
if mems, err = fscommon.ReadFile(parent, "cpuset.mems"); err != nil {
if mems, err = cgroups.ReadFile(parent, "cpuset.mems"); err != nil {
return
}
return cpus, mems, nil
Expand Down Expand Up @@ -224,12 +224,12 @@ func cpusetCopyIfNeeded(current, parent string) error {
}

if isEmptyCpuset(currentCpus) {
if err := fscommon.WriteFile(current, "cpuset.cpus", string(parentCpus)); err != nil {
if err := cgroups.WriteFile(current, "cpuset.cpus", string(parentCpus)); err != nil {
return err
}
}
if isEmptyCpuset(currentMems) {
if err := fscommon.WriteFile(current, "cpuset.mems", string(parentMems)); err != nil {
if err := cgroups.WriteFile(current, "cpuset.mems", string(parentMems)); err != nil {
return err
}
}
Expand Down
5 changes: 2 additions & 3 deletions libcontainer/cgroups/fs/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/opencontainers/runc/libcontainer/cgroups"
cgroupdevices "github.com/opencontainers/runc/libcontainer/cgroups/devices"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices"
"github.com/opencontainers/runc/libcontainer/userns"
Expand All @@ -36,7 +35,7 @@ func (s *DevicesGroup) Apply(path string, d *cgroupData) error {
}

func loadEmulator(path string) (*cgroupdevices.Emulator, error) {
list, err := fscommon.ReadFile(path, "devices.list")
list, err := cgroups.ReadFile(path, "devices.list")
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -81,7 +80,7 @@ func (s *DevicesGroup) Set(path string, r *configs.Resources) error {
if rule.Allow {
file = "devices.allow"
}
if err := fscommon.WriteFile(path, file, rule.CgroupString()); err != nil {
if err := cgroups.WriteFile(path, file, rule.CgroupString()); err != nil {
return err
}
}
Expand Down
13 changes: 6 additions & 7 deletions libcontainer/cgroups/fs/freezer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"time"

"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
Expand All @@ -34,7 +33,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
// Freezing failed, and it is bad and dangerous
// to leave the cgroup in FROZEN or FREEZING
// state, so (try to) thaw it back.
_ = fscommon.WriteFile(path, "freezer.state", string(configs.Thawed))
_ = cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
}
}()

Expand Down Expand Up @@ -67,11 +66,11 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
// the chances to succeed in freezing
// in case new processes keep appearing
// in the cgroup.
_ = fscommon.WriteFile(path, "freezer.state", string(configs.Thawed))
_ = cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
time.Sleep(10 * time.Millisecond)
}

if err := fscommon.WriteFile(path, "freezer.state", string(configs.Frozen)); err != nil {
if err := cgroups.WriteFile(path, "freezer.state", string(configs.Frozen)); err != nil {
return err
}

Expand All @@ -82,7 +81,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
// system.
time.Sleep(10 * time.Microsecond)
}
state, err := fscommon.ReadFile(path, "freezer.state")
state, err := cgroups.ReadFile(path, "freezer.state")
if err != nil {
return err
}
Expand All @@ -103,7 +102,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
// Despite our best efforts, it got stuck in FREEZING.
return errors.New("unable to freeze")
case configs.Thawed:
return fscommon.WriteFile(path, "freezer.state", string(configs.Thawed))
return cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
case configs.Undefined:
return nil
default:
Expand All @@ -117,7 +116,7 @@ func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error {

func (s *FreezerGroup) GetState(path string) (configs.FreezerState, error) {
for {
state, err := fscommon.ReadFile(path, "freezer.state")
state, err := cgroups.ReadFile(path, "freezer.state")
if err != nil {
// If the kernel is too old, then we just treat the freezer as
// being in an "undefined" state.
Expand Down
2 changes: 1 addition & 1 deletion libcontainer/cgroups/fs/hugetlb.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (s *HugetlbGroup) Apply(path string, d *cgroupData) error {

func (s *HugetlbGroup) Set(path string, r *configs.Resources) error {
for _, hugetlb := range r.HugetlbLimit {
if err := fscommon.WriteFile(path, "hugetlb."+hugetlb.Pagesize+".limit_in_bytes", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
if err := cgroups.WriteFile(path, "hugetlb."+hugetlb.Pagesize+".limit_in_bytes", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
return err
}
}
Expand Down
Loading

0 comments on commit 98a8545

Please sign in to comment.