gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

cgroups.go (3891B)


      1 // Copyright (c) 2017 Uber Technologies, Inc.
      2 //
      3 // Permission is hereby granted, free of charge, to any person obtaining a copy
      4 // of this software and associated documentation files (the "Software"), to deal
      5 // in the Software without restriction, including without limitation the rights
      6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      7 // copies of the Software, and to permit persons to whom the Software is
      8 // furnished to do so, subject to the following conditions:
      9 //
     10 // The above copyright notice and this permission notice shall be included in
     11 // all copies or substantial portions of the Software.
     12 //
     13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     19 // THE SOFTWARE.
     20 
     21 //go:build linux
     22 // +build linux
     23 
     24 package cgroups
     25 
     26 const (
     27 	// _cgroupFSType is the Linux CGroup file system type used in
     28 	// `/proc/$PID/mountinfo`.
     29 	_cgroupFSType = "cgroup"
     30 	// _cgroupSubsysCPU is the CPU CGroup subsystem.
     31 	_cgroupSubsysCPU = "cpu"
     32 	// _cgroupSubsysCPUAcct is the CPU accounting CGroup subsystem.
     33 	_cgroupSubsysCPUAcct = "cpuacct"
     34 	// _cgroupSubsysCPUSet is the CPUSet CGroup subsystem.
     35 	_cgroupSubsysCPUSet = "cpuset"
     36 	// _cgroupSubsysMemory is the Memory CGroup subsystem.
     37 	_cgroupSubsysMemory = "memory"
     38 
     39 	// _cgroupCPUCFSQuotaUsParam is the file name for the CGroup CFS quota
     40 	// parameter.
     41 	_cgroupCPUCFSQuotaUsParam = "cpu.cfs_quota_us"
     42 	// _cgroupCPUCFSPeriodUsParam is the file name for the CGroup CFS period
     43 	// parameter.
     44 	_cgroupCPUCFSPeriodUsParam = "cpu.cfs_period_us"
     45 )
     46 
     47 const (
     48 	_procPathCGroup    = "/proc/self/cgroup"
     49 	_procPathMountInfo = "/proc/self/mountinfo"
     50 )
     51 
     52 // CGroups is a map that associates each CGroup with its subsystem name.
     53 type CGroups map[string]*CGroup
     54 
     55 // NewCGroups returns a new *CGroups from given `mountinfo` and `cgroup` files
     56 // under for some process under `/proc` file system (see also proc(5) for more
     57 // information).
     58 func NewCGroups(procPathMountInfo, procPathCGroup string) (CGroups, error) {
     59 	cgroupSubsystems, err := parseCGroupSubsystems(procPathCGroup)
     60 	if err != nil {
     61 		return nil, err
     62 	}
     63 
     64 	cgroups := make(CGroups)
     65 	newMountPoint := func(mp *MountPoint) error {
     66 		if mp.FSType != _cgroupFSType {
     67 			return nil
     68 		}
     69 
     70 		for _, opt := range mp.SuperOptions {
     71 			subsys, exists := cgroupSubsystems[opt]
     72 			if !exists {
     73 				continue
     74 			}
     75 
     76 			cgroupPath, err := mp.Translate(subsys.Name)
     77 			if err != nil {
     78 				return err
     79 			}
     80 			cgroups[opt] = NewCGroup(cgroupPath)
     81 		}
     82 
     83 		return nil
     84 	}
     85 
     86 	if err := parseMountInfo(procPathMountInfo, newMountPoint); err != nil {
     87 		return nil, err
     88 	}
     89 	return cgroups, nil
     90 }
     91 
     92 // NewCGroupsForCurrentProcess returns a new *CGroups instance for the current
     93 // process.
     94 func NewCGroupsForCurrentProcess() (CGroups, error) {
     95 	return NewCGroups(_procPathMountInfo, _procPathCGroup)
     96 }
     97 
     98 // CPUQuota returns the CPU quota applied with the CPU cgroup controller.
     99 // It is a result of `cpu.cfs_quota_us / cpu.cfs_period_us`. If the value of
    100 // `cpu.cfs_quota_us` was not set (-1), the method returns `(-1, nil)`.
    101 func (cg CGroups) CPUQuota() (float64, bool, error) {
    102 	cpuCGroup, exists := cg[_cgroupSubsysCPU]
    103 	if !exists {
    104 		return -1, false, nil
    105 	}
    106 
    107 	cfsQuotaUs, err := cpuCGroup.readInt(_cgroupCPUCFSQuotaUsParam)
    108 	if defined := cfsQuotaUs > 0; err != nil || !defined {
    109 		return -1, defined, err
    110 	}
    111 
    112 	cfsPeriodUs, err := cpuCGroup.readInt(_cgroupCPUCFSPeriodUsParam)
    113 	if err != nil {
    114 		return -1, false, err
    115 	}
    116 
    117 	return float64(cfsQuotaUs) / float64(cfsPeriodUs), true, nil
    118 }