github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/cgroups/fs/cpu.go (about)

     1  // +build linux
     2  
     3  package fs
     4  
     5  import (
     6  	"bufio"
     7  	"os"
     8  	"path/filepath"
     9  	"strconv"
    10  
    11  	"github.com/opencontainers/runc/libcontainer/cgroups"
    12  	"github.com/opencontainers/runc/libcontainer/configs"
    13  )
    14  
    15  type CpuGroup struct {
    16  }
    17  
    18  func (s *CpuGroup) Name() string {
    19  	return "cpu"
    20  }
    21  
    22  func (s *CpuGroup) Apply(d *cgroupData) error {
    23  	// We always want to join the cpu group, to allow fair cpu scheduling
    24  	// on a container basis
    25  	path, err := d.path("cpu")
    26  	if err != nil && !cgroups.IsNotFound(err) {
    27  		return err
    28  	}
    29  	return s.ApplyDir(path, d.config, d.pid)
    30  }
    31  
    32  func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error {
    33  	// This might happen if we have no cpu cgroup mounted.
    34  	// Just do nothing and don't fail.
    35  	if path == "" {
    36  		return nil
    37  	}
    38  	if err := os.MkdirAll(path, 0755); err != nil {
    39  		return err
    40  	}
    41  	// We should set the real-Time group scheduling settings before moving
    42  	// in the process because if the process is already in SCHED_RR mode
    43  	// and no RT bandwidth is set, adding it will fail.
    44  	if err := s.SetRtSched(path, cgroup); err != nil {
    45  		return err
    46  	}
    47  	// because we are not using d.join we need to place the pid into the procs file
    48  	// unlike the other subsystems
    49  	if err := cgroups.WriteCgroupProc(path, pid); err != nil {
    50  		return err
    51  	}
    52  
    53  	return nil
    54  }
    55  
    56  func (s *CpuGroup) SetRtSched(path string, cgroup *configs.Cgroup) error {
    57  	if cgroup.Resources.CpuRtPeriod != 0 {
    58  		if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.Resources.CpuRtPeriod, 10)); err != nil {
    59  			return err
    60  		}
    61  	}
    62  	if cgroup.Resources.CpuRtRuntime != 0 {
    63  		if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
    64  			return err
    65  		}
    66  	}
    67  	return nil
    68  }
    69  
    70  func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
    71  	if cgroup.Resources.CpuShares != 0 {
    72  		if err := writeFile(path, "cpu.shares", strconv.FormatInt(cgroup.Resources.CpuShares, 10)); err != nil {
    73  			return err
    74  		}
    75  	}
    76  	if cgroup.Resources.CpuPeriod != 0 {
    77  		if err := writeFile(path, "cpu.cfs_period_us", strconv.FormatInt(cgroup.Resources.CpuPeriod, 10)); err != nil {
    78  			return err
    79  		}
    80  	}
    81  	if cgroup.Resources.CpuQuota != 0 {
    82  		if err := writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(cgroup.Resources.CpuQuota, 10)); err != nil {
    83  			return err
    84  		}
    85  	}
    86  	if err := s.SetRtSched(path, cgroup); err != nil {
    87  		return err
    88  	}
    89  
    90  	return nil
    91  }
    92  
    93  func (s *CpuGroup) Remove(d *cgroupData) error {
    94  	return removePath(d.path("cpu"))
    95  }
    96  
    97  func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
    98  	f, err := os.Open(filepath.Join(path, "cpu.stat"))
    99  	if err != nil {
   100  		if os.IsNotExist(err) {
   101  			return nil
   102  		}
   103  		return err
   104  	}
   105  	defer f.Close()
   106  
   107  	sc := bufio.NewScanner(f)
   108  	for sc.Scan() {
   109  		t, v, err := getCgroupParamKeyValue(sc.Text())
   110  		if err != nil {
   111  			return err
   112  		}
   113  		switch t {
   114  		case "nr_periods":
   115  			stats.CpuStats.ThrottlingData.Periods = v
   116  
   117  		case "nr_throttled":
   118  			stats.CpuStats.ThrottlingData.ThrottledPeriods = v
   119  
   120  		case "throttled_time":
   121  			stats.CpuStats.ThrottlingData.ThrottledTime = v
   122  		}
   123  	}
   124  	return nil
   125  }