...

Source file src/golang.conradwood.net/go-easyops/linux/std_cgroup.go

Documentation: golang.conradwood.net/go-easyops/linux

     1  package linux
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strconv"
     8  	"strings"
     9  	"sync"
    10  
    11  	"golang.conradwood.net/go-easyops/errors"
    12  	"golang.conradwood.net/go-easyops/utils"
    13  )
    14  
    15  var (
    16  	cgroup_check_lock sync.Mutex
    17  )
    18  
    19  func MyCgroup() (string, error) {
    20  	b, err := utils.ReadFile("/proc/self/cgroup")
    21  	if err != nil {
    22  		return "", errors.Wrap(err)
    23  	}
    24  	s := string(b)
    25  	idx := strings.Index(s, "/")
    26  	if idx == -1 {
    27  		return "", errors.Errorf("odd /proc/self/cgroup line: \"%s\"", s)
    28  	}
    29  	res := s[idx:]
    30  	return res, nil
    31  
    32  }
    33  
    34  // if caller is in cgroup "/LINUXCOM/ancestor/me", new cgrop will be "/LINUXCOM/ancestor/com_1"
    35  func CreateStandardAdjacentCgroup() (string, error) {
    36  	myc, err := MyCgroup()
    37  	if err != nil {
    38  		return "", err
    39  	}
    40  	ancestor := filepath.Dir(myc)
    41  	ctr := 0
    42  	cgroup_check_lock.Lock()
    43  	defer cgroup_check_lock.Unlock()
    44  	name := ""
    45  	for {
    46  		ctr++
    47  		name = fmt.Sprintf("/sys/fs/cgroup/%s/com_%d", ancestor, ctr)
    48  		_, err := os.Stat(name)
    49  		if err != nil {
    50  			//fmt.Printf("Stat for \"%s\" failed: %s\n", name, err)
    51  			break
    52  		}
    53  		//	fmt.Printf("Found cgroup: \"%s\" (%v)\n", name, st)
    54  	}
    55  	if name == "" {
    56  		return "", errors.Errorf("Unable to determine adjacent cgroup")
    57  	}
    58  	err = CreateStandardCgroup(name)
    59  	if err != nil {
    60  		return "", err
    61  	}
    62  	return name, nil
    63  }
    64  
    65  func CreateStandardCgroup(dir string) error {
    66  	if utils.FileExists(dir) {
    67  		return errors.Errorf("dir \"%s\" exists already", dir)
    68  	}
    69  	err := mkdir(dir)
    70  	if err != nil {
    71  		return errors.Errorf("failed to create parent cgroup (%s): %s", dir, err)
    72  	}
    73  	taskdir := dir + "/tasks"
    74  	err = mkdir(taskdir)
    75  	if err != nil {
    76  		return errors.Errorf("failed to create cgroup tasks (%s): %s", taskdir, err)
    77  	}
    78  	return nil
    79  }
    80  
    81  func get_pids_for_cgroup(cgroupdir string) ([]uint64, error) {
    82  	fname := cgroupdir + "/cgroup.procs"
    83  	if !utils.FileExists(fname) {
    84  		return nil, nil
    85  	}
    86  	b, err := utils.ReadFile(fname)
    87  	if err != nil {
    88  		return nil, errors.Wrap(err)
    89  	}
    90  	var res []uint64
    91  	for _, line := range strings.Split(string(b), "\n") {
    92  		if line == "" {
    93  			continue
    94  		}
    95  		pid, err := strconv.ParseUint(line, 10, 64)
    96  		if err != nil {
    97  			return nil, errors.Wrap(err)
    98  		}
    99  		res = append(res, pid)
   100  	}
   101  	return res, nil
   102  }
   103  
   104  // remove cgroup (and child cgroups)
   105  func remove_cgroup(cgroupdir string) error {
   106  	rmdir(cgroupdir + "/tasks")
   107  	rmdir(cgroupdir)
   108  	return nil
   109  }
   110  func rmdir(dir string) error {
   111  	err := os.Remove(dir)
   112  	if err != nil {
   113  		fmt.Printf("failed to remove dir: %s\n", err)
   114  	}
   115  	return err
   116  }
   117  

View as plain text