github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/cgroup/common/path.go (about)

     1  /*
     2  Copyright 2022 The Katalyst 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 common
    18  
    19  import (
    20  	"fmt"
    21  	"path"
    22  	"path/filepath"
    23  	"sync"
    24  
    25  	utilerrors "k8s.io/apimachinery/pkg/util/errors"
    26  	"k8s.io/apimachinery/pkg/util/sets"
    27  
    28  	"github.com/kubewharf/katalyst-core/pkg/util/general"
    29  )
    30  
    31  // k8sCgroupPathList is used to record cgroup-path related configurations,
    32  // and it will be set as SystemdRootPath (along with kubernetes levels) as default.
    33  var (
    34  	k8sCgroupPathLock sync.RWMutex
    35  	k8sCgroupPathList = sets.NewString(
    36  		CgroupFsRootPath,
    37  		CgroupFsRootPathBestEffort,
    38  		CgroupFsRootPathBurstable,
    39  	)
    40  )
    41  
    42  var k8sCgroupPathSettingOnce = sync.Once{}
    43  
    44  // InitKubernetesCGroupPath can only be called once to init dynamic cgroup path configurations.
    45  // additionalCGroupPath is set because we may have legacy cgroup path settings,
    46  // so it will be used as an adaptive logic.
    47  func InitKubernetesCGroupPath(cgroupType CgroupType, additionalK8SCGroupPath []string) {
    48  	k8sCgroupPathSettingOnce.Do(func() {
    49  		if cgroupType == CgroupTypeSystemd {
    50  			k8sCgroupPathLock.Lock()
    51  			defer k8sCgroupPathLock.Unlock()
    52  			k8sCgroupPathList = sets.NewString(
    53  				SystemdRootPath,
    54  				SystemdRootPathBestEffort,
    55  				SystemdRootPathBurstable,
    56  			)
    57  		}
    58  
    59  		k8sCgroupPathList.Insert(additionalK8SCGroupPath...)
    60  	})
    61  }
    62  
    63  // GetCgroupRootPath get cgroupfs root path compatible with v1 and v2
    64  func GetCgroupRootPath(subsys string) string {
    65  	if CheckCgroup2UnifiedMode() {
    66  		return CgroupFSMountPoint
    67  	}
    68  
    69  	return filepath.Join(CgroupFSMountPoint, subsys)
    70  }
    71  
    72  // GetAbsCgroupPath get absolute cgroup path for relative cgroup path
    73  func GetAbsCgroupPath(subsys, suffix string) string {
    74  	return filepath.Join(GetCgroupRootPath(subsys), suffix)
    75  }
    76  
    77  // GetKubernetesCgroupRootPathWithSubSys returns all Cgroup paths to run container for
    78  // kubernetes, and the returned values are merged with subsys.
    79  func GetKubernetesCgroupRootPathWithSubSys(subsys string) []string {
    80  	k8sCgroupPathLock.RLock()
    81  	defer k8sCgroupPathLock.RUnlock()
    82  
    83  	var subsysCgroupPathList []string
    84  	for _, p := range k8sCgroupPathList.List() {
    85  		subsysCgroupPathList = append(subsysCgroupPathList,
    86  			GetKubernetesAbsCgroupPath(subsys, p))
    87  	}
    88  	return subsysCgroupPathList
    89  }
    90  
    91  // GetKubernetesAbsCgroupPath returns absolute cgroup path for kubernetes with the given
    92  // suffix without considering whether the path exists or not.
    93  func GetKubernetesAbsCgroupPath(subsys, suffix string) string {
    94  	if subsys == "" {
    95  		subsys = DefaultSelectedSubsys
    96  	}
    97  
    98  	return GetAbsCgroupPath(subsys, suffix)
    99  }
   100  
   101  // GetKubernetesAnyExistAbsCgroupPath returns any absolute cgroup path that exists for kubernetes
   102  func GetKubernetesAnyExistAbsCgroupPath(subsys, suffix string) (string, error) {
   103  	var errs []error
   104  
   105  	k8sCgroupPathLock.RLock()
   106  	defer k8sCgroupPathLock.RUnlock()
   107  
   108  	for _, cgPath := range k8sCgroupPathList.List() {
   109  		p := GetKubernetesAbsCgroupPath(subsys, path.Join(cgPath, suffix))
   110  		if general.IsPathExists(p) {
   111  			return p, nil
   112  		}
   113  	}
   114  
   115  	return "", fmt.Errorf("failed to find absolute path of suffix: %s, error: %v", suffix, utilerrors.NewAggregate(errs))
   116  }
   117  
   118  // GetKubernetesAnyExistRelativeCgroupPath returns any relative cgroup path that exists for kubernetes
   119  func GetKubernetesAnyExistRelativeCgroupPath(suffix string) (string, error) {
   120  	var errs []error
   121  
   122  	k8sCgroupPathLock.RLock()
   123  	defer k8sCgroupPathLock.RUnlock()
   124  
   125  	for _, cgPath := range k8sCgroupPathList.List() {
   126  		relativePath := path.Join(cgPath, suffix)
   127  		for _, defaultSelectedSubsys := range defaultSelectedSubsysList {
   128  			p := GetKubernetesAbsCgroupPath(defaultSelectedSubsys, relativePath)
   129  			if general.IsPathExists(p) {
   130  				return relativePath, nil
   131  			}
   132  		}
   133  	}
   134  
   135  	return "", fmt.Errorf("failed to find relative path of suffix: %s, error: %v", suffix, utilerrors.NewAggregate(errs))
   136  }
   137  
   138  // GetPodAbsCgroupPath returns absolute cgroup path for pod level
   139  func GetPodAbsCgroupPath(subsys, podUID string) (string, error) {
   140  	return GetKubernetesAnyExistAbsCgroupPath(subsys, fmt.Sprintf("%s%s", PodCgroupPathPrefix, podUID))
   141  }
   142  
   143  // GetContainerAbsCgroupPath returns absolute cgroup path for container level
   144  func GetContainerAbsCgroupPath(subsys, podUID, containerId string) (string, error) {
   145  	return GetKubernetesAnyExistAbsCgroupPath(subsys, path.Join(fmt.Sprintf("%s%s", PodCgroupPathPrefix, podUID), containerId))
   146  }
   147  
   148  // GetContainerRelativeCgroupPath returns relative cgroup path for container level
   149  func GetContainerRelativeCgroupPath(podUID, containerId string) (string, error) {
   150  	return GetKubernetesAnyExistRelativeCgroupPath(path.Join(fmt.Sprintf("%s%s", PodCgroupPathPrefix, podUID), containerId))
   151  }
   152  
   153  func IsContainerCgroupExist(podUID, containerID string) (bool, error) {
   154  	containerAbsCGPath, err := GetContainerAbsCgroupPath("", podUID, containerID)
   155  	if err != nil {
   156  		return false, fmt.Errorf("GetContainerAbsCgroupPath failed, err: %v", err)
   157  	}
   158  
   159  	return general.IsPathExists(containerAbsCGPath), nil
   160  }