...

Source file src/github.com/containerd/cgroups/cpu.go

Documentation: github.com/containerd/cgroups

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package cgroups
    18  
    19  import (
    20  	"bufio"
    21  	"os"
    22  	"path/filepath"
    23  	"strconv"
    24  
    25  	v1 "github.com/containerd/cgroups/stats/v1"
    26  	specs "github.com/opencontainers/runtime-spec/specs-go"
    27  )
    28  
    29  func NewCpu(root string) *cpuController {
    30  	return &cpuController{
    31  		root: filepath.Join(root, string(Cpu)),
    32  	}
    33  }
    34  
    35  type cpuController struct {
    36  	root string
    37  }
    38  
    39  func (c *cpuController) Name() Name {
    40  	return Cpu
    41  }
    42  
    43  func (c *cpuController) Path(path string) string {
    44  	return filepath.Join(c.root, path)
    45  }
    46  
    47  func (c *cpuController) Create(path string, resources *specs.LinuxResources) error {
    48  	if err := os.MkdirAll(c.Path(path), defaultDirPerm); err != nil {
    49  		return err
    50  	}
    51  	if cpu := resources.CPU; cpu != nil {
    52  		for _, t := range []struct {
    53  			name   string
    54  			ivalue *int64
    55  			uvalue *uint64
    56  		}{
    57  			{
    58  				name:   "rt_period_us",
    59  				uvalue: cpu.RealtimePeriod,
    60  			},
    61  			{
    62  				name:   "rt_runtime_us",
    63  				ivalue: cpu.RealtimeRuntime,
    64  			},
    65  			{
    66  				name:   "shares",
    67  				uvalue: cpu.Shares,
    68  			},
    69  			{
    70  				name:   "cfs_period_us",
    71  				uvalue: cpu.Period,
    72  			},
    73  			{
    74  				name:   "cfs_quota_us",
    75  				ivalue: cpu.Quota,
    76  			},
    77  		} {
    78  			var value []byte
    79  			if t.uvalue != nil {
    80  				value = []byte(strconv.FormatUint(*t.uvalue, 10))
    81  			} else if t.ivalue != nil {
    82  				value = []byte(strconv.FormatInt(*t.ivalue, 10))
    83  			}
    84  			if value != nil {
    85  				if err := retryingWriteFile(
    86  					filepath.Join(c.Path(path), "cpu."+t.name),
    87  					value,
    88  					defaultFilePerm,
    89  				); err != nil {
    90  					return err
    91  				}
    92  			}
    93  		}
    94  	}
    95  	return nil
    96  }
    97  
    98  func (c *cpuController) Update(path string, resources *specs.LinuxResources) error {
    99  	return c.Create(path, resources)
   100  }
   101  
   102  func (c *cpuController) Stat(path string, stats *v1.Metrics) error {
   103  	f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat"))
   104  	if err != nil {
   105  		return err
   106  	}
   107  	defer f.Close()
   108  	// get or create the cpu field because cpuacct can also set values on this struct
   109  	sc := bufio.NewScanner(f)
   110  	for sc.Scan() {
   111  		key, v, err := parseKV(sc.Text())
   112  		if err != nil {
   113  			return err
   114  		}
   115  		switch key {
   116  		case "nr_periods":
   117  			stats.CPU.Throttling.Periods = v
   118  		case "nr_throttled":
   119  			stats.CPU.Throttling.ThrottledPeriods = v
   120  		case "throttled_time":
   121  			stats.CPU.Throttling.ThrottledTime = v
   122  		}
   123  	}
   124  	return sc.Err()
   125  }
   126  

View as plain text