diff options
Diffstat (limited to 'sd_login/cgroup_generic.go')
-rw-r--r-- | sd_login/cgroup_generic.go | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/sd_login/cgroup_generic.go b/sd_login/cgroup_generic.go deleted file mode 100644 index 3842c64..0000000 --- a/sd_login/cgroup_generic.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (C) 2016-2017 Luke Shumaker <lukeshu@sbcglobal.net> -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sd_login - -import ( - "bufio" - "fmt" - "io" - "os" - "strings" - - "golang.org/x/sys/unix" -) - -type _Cgroup string - -var cgVersion_cache uint - -func cgVersion() uint { - if cgVersion_cache == 0 { - fs, err := statfs("/sys/fs/cgroup/") - if err != nil { - return 0 - } - if fs.Type == magic_CGROUP2_SUPER { - cgVersion_cache = 2 - } else if fs.Type == magic_TMPFS { - // XXX: systemd-specific cgroup v1 logic - fs, err = statfs("/sys/fs/cgroup/systemd/") - if err != nil { - return 0 - } - if fs.Type == magic_CGROUP2_SUPER { - cgVersion_cache = 2 - } else { - cgVersion_cache = 1 - } - } - } - return cgVersion_cache -} - -// getCgroup returns the cgroup path of the process, relative to the -// root of the cgroup hierarchy. -// -// In cgroup v2, there is a only one cgroup hierarchy, so the behavior -// is obvious. -// -// However, in cgroup v1, there were multiple cgroup hierarchies, so -// this function must decide which hierarchy to use. We chooses the -// first hierarchy with either the "name=systemd" controller or the -// "name=elogind" controller attached to it[1]. If no such hierarchy -// exists, then an error is returned. -// -// However, it is possible to generally use cgroup v1, but use a -// single (named) v2 hierarchy alongside many v1 hierarchies. In this -// case, we use the v2 hierarchy iff it is named "systemd", otherwise -// we use the cgroup v1 behavior. -// -// [1]: The "first" in that sentence is worrying; shouldn't the choice -// of hierarchy not depend on the undefined order that controllers are -// listed in? Well, a controller may be attached to only one -// hierarchy at a time. So there is only an ambiguity for "first" to -// come in if both "name=systemd" and "name=elogind" controllers -// exist. Systemd and elogind cannot be used together, so this isn't -// a concern. -// -// BUG(lukeshu): PID.getCgroup: Has systemd-specific logic. However, -// it is only for "legacy" cgroup v1 compatibility; the cgroup v2 -// logic is totally implementation-agnostic. Unfortunately(?), no -// distro seems to be using cgroup v2 (introduced in Linux 4.5) yet by -// default. -func (pid PID) getCgroup() (_Cgroup, error) { - cgVer := cgVersion() - - var cgroupFilename string - if pid == 0 { - cgroupFilename = "/proc/self/cgroup" - } else { - cgroupFilename = fmt.Sprintf("/proc/%d/cgroup", pid) - } - - f, err := os.Open(cgroupFilename) - if err != nil { - return "", err - } - defer f.Close() - - bf := bufio.NewReader(f) - - for { - line, err := bf.ReadString('\n') - if err == io.EOF { - break - } - if err != nil { - return "", err - } - line = strings.TrimSuffix(line, "\n") - - parts := strings.SplitN(line, ":", 3) - if len(parts) != 3 { - continue - } - - hierarchy := parts[0] - controllers := parts[1] - path := _Cgroup(parts[2]) - - switch cgVer { - case 1: - for _, controller := range strings.Split(controllers, ",") { - if controller == "name=systemd" || controller == "name=elogind" { - return path, nil - } - } - case 2: - if hierarchy != "0" { - continue - } - return path, nil - } - } - return "", unix.ENODATA -} - -// cgGetRootPath determines the cgroup that all other cgroups belong -// to. The common case is just "/", but it could be something else if -// we are inside of a container, but have a view of the entier cgroup -// hierarchy. -// -// BUG(lukeshu): cgGetRootPath: works correctly on systemd and -// elogind, but I'm not sure it's general. -func cgGetRootPath() (_Cgroup, error) { - cgpath, err := PID(1).getCgroup() - if err != nil { - return "/", err - } - - cgpath = _Cgroup(trimOneSuffix(string(cgpath), - "/init.scope", // modern systemd - "/system.slice", // legacy systemd - "/system", // even more legacy systemd - )) - - return cgpath, nil -} - -func cgUnescape(s string) string { - return strings.TrimPrefix(s, "_") -} |