reason: update license to Mulan PSL v2 Signed-off-by: taleintervenor <taleintervenor@aliyun.com>
177 lines
4.8 KiB
Go
177 lines
4.8 KiB
Go
// Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
|
// syscontainer-tools is licensed under the Mulan PSL v2.
|
|
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
// You may obtain a copy of Mulan PSL v2 at:
|
|
// http://license.coscl.org.cn/MulanPSL2
|
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
// PURPOSE.
|
|
// See the Mulan PSL v2 for more details.
|
|
// Description: cgroup operation for container
|
|
// Author: zhangwei
|
|
// Create: 2018-01-18
|
|
|
|
package libdevice
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
"isula.org/syscontainer-tools/types"
|
|
)
|
|
|
|
var (
|
|
cgroupNamePrefix = "name="
|
|
)
|
|
|
|
// GetCgroupDir returns the cgorup mount directory from pid
|
|
func GetCgroupDir(pid, subsystem string) (string, error) {
|
|
path := filepath.Join("/proc", pid, "cgroup")
|
|
cgroupmap, err := cgroups.ParseCgroupFile(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if path, ok := cgroupmap[subsystem]; ok {
|
|
return path, nil
|
|
}
|
|
if path, ok := cgroupmap[cgroupNamePrefix+subsystem]; ok {
|
|
return path, nil
|
|
}
|
|
return "", fmt.Errorf("Error: ControllerPath of %s is not found", subsystem)
|
|
}
|
|
|
|
// FindCgroupPath will search the subsystem cgroup path for target process
|
|
func FindCgroupPath(pid, subsystem, innerPath string) (string, error) {
|
|
cgroupRoot, err := cgroups.FindCgroupMountpointDir()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
mnt, root, err := cgroups.FindCgroupMountpointAndRoot(subsystem)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if filepath.IsAbs(innerPath) {
|
|
return filepath.Join(cgroupRoot, filepath.Base(mnt), innerPath), nil
|
|
}
|
|
initPath, err := GetCgroupDir(pid, subsystem)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// This is needed for nested containers, because in /proc/pid/cgroup we
|
|
// see pathes from host, which don't exist in container.
|
|
relDir, err := filepath.Rel(root, initPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return filepath.Join(mnt, relDir), nil
|
|
}
|
|
|
|
// UpdateCgroupPermission will update the cgroup permissions for specified device
|
|
func UpdateCgroupPermission(CgroupBase string, device *types.Device, isAddDevice bool) error {
|
|
var path string
|
|
|
|
if isAddDevice {
|
|
path = filepath.Join(CgroupBase, "devices.allow")
|
|
} else {
|
|
path = filepath.Join(CgroupBase, "devices.deny")
|
|
}
|
|
value := device.CgroupString()
|
|
if err := ioutil.WriteFile(path, []byte(value), 0600); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateCgroupDeviceReadIOPS updates the read device iops for container/pid
|
|
func UpdateCgroupDeviceReadIOPS(pid, innerPath, value string) error {
|
|
if pid == "0" {
|
|
return nil
|
|
}
|
|
|
|
cgroupPath, err := FindCgroupPath(pid, "blkio", innerPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
path := filepath.Join(cgroupPath, "blkio.throttle.read_iops_device")
|
|
if err := ioutil.WriteFile(path, []byte(value), 0600); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateCgroupDeviceWriteIOPS updates the write device iops for container/pid
|
|
func UpdateCgroupDeviceWriteIOPS(pid, innerPath, value string) error {
|
|
if pid == "0" {
|
|
return nil
|
|
}
|
|
|
|
cgroupPath, err := FindCgroupPath(pid, "blkio", innerPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
path := filepath.Join(cgroupPath, "blkio.throttle.write_iops_device")
|
|
if err := ioutil.WriteFile(path, []byte(value), 0600); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateCgroupDeviceReadBps updates the read device bps for container/pid
|
|
func UpdateCgroupDeviceReadBps(pid, innerPath, value string) error {
|
|
if pid == "0" {
|
|
return nil
|
|
}
|
|
|
|
cgroupPath, err := FindCgroupPath(pid, "blkio", innerPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
path := filepath.Join(cgroupPath, "blkio.throttle.read_bps_device")
|
|
if err := ioutil.WriteFile(path, []byte(value), 0600); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateCgroupDeviceWriteBps updates the write device bps for container/pid
|
|
func UpdateCgroupDeviceWriteBps(pid, innerPath, value string) error {
|
|
if pid == "0" {
|
|
return nil
|
|
}
|
|
|
|
cgroupPath, err := FindCgroupPath(pid, "blkio", innerPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
path := filepath.Join(cgroupPath, "blkio.throttle.write_bps_device")
|
|
if err := ioutil.WriteFile(path, []byte(value), 0600); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateCgroupDeviceWeight updates the write device weight for container/pid
|
|
func UpdateCgroupDeviceWeight(pid, innerPath, value string) error {
|
|
if pid == "0" {
|
|
return nil
|
|
}
|
|
|
|
cgroupPath, err := FindCgroupPath(pid, "blkio", innerPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
path := filepath.Join(cgroupPath, "blkio.weight_device")
|
|
if err := ioutil.WriteFile(path, []byte(value), 0600); err != nil {
|
|
return fmt.Errorf("%s, please check whether current OS support blkio weight device configuration for bfq scheduler", err)
|
|
}
|
|
return nil
|
|
}
|