mirror of
				https://github.com/containers/podman.git
				synced 2025-11-04 08:56:05 +08:00 
			
		
		
		
	We can use this constant from the already existing sys/unix package instead of defining it by our own. Signed-off-by: Sascha Grunert <sgrunert@suse.com>
		
			
				
	
	
		
			91 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build linux
 | 
						|
 | 
						|
package cgroups
 | 
						|
 | 
						|
import (
 | 
						|
	"bufio"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"strings"
 | 
						|
	"sync"
 | 
						|
	"syscall"
 | 
						|
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"golang.org/x/sys/unix"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	isUnifiedOnce sync.Once
 | 
						|
	isUnified     bool
 | 
						|
	isUnifiedErr  error
 | 
						|
)
 | 
						|
 | 
						|
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
 | 
						|
func IsCgroup2UnifiedMode() (bool, error) {
 | 
						|
	isUnifiedOnce.Do(func() {
 | 
						|
		var st syscall.Statfs_t
 | 
						|
		if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
 | 
						|
			isUnified, isUnifiedErr = false, err
 | 
						|
		} else {
 | 
						|
			isUnified, isUnifiedErr = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
 | 
						|
		}
 | 
						|
	})
 | 
						|
	return isUnified, isUnifiedErr
 | 
						|
}
 | 
						|
 | 
						|
// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
 | 
						|
// current cgroup.
 | 
						|
func UserOwnsCurrentSystemdCgroup() (bool, error) {
 | 
						|
	uid := os.Geteuid()
 | 
						|
 | 
						|
	cgroup2, err := IsCgroup2UnifiedMode()
 | 
						|
	if err != nil {
 | 
						|
		return false, err
 | 
						|
	}
 | 
						|
 | 
						|
	f, err := os.Open("/proc/self/cgroup")
 | 
						|
	if err != nil {
 | 
						|
		return false, errors.Wrapf(err, "open file /proc/self/cgroup")
 | 
						|
	}
 | 
						|
	defer f.Close()
 | 
						|
 | 
						|
	scanner := bufio.NewScanner(f)
 | 
						|
	for scanner.Scan() {
 | 
						|
		line := scanner.Text()
 | 
						|
		parts := strings.SplitN(line, ":", 3)
 | 
						|
 | 
						|
		if len(parts) < 3 {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		var cgroupPath string
 | 
						|
 | 
						|
		if cgroup2 {
 | 
						|
			cgroupPath = filepath.Join(cgroupRoot, parts[2])
 | 
						|
		} else {
 | 
						|
			if parts[1] != "name=systemd" {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2])
 | 
						|
		}
 | 
						|
 | 
						|
		st, err := os.Stat(cgroupPath)
 | 
						|
		if err != nil {
 | 
						|
			return false, err
 | 
						|
		}
 | 
						|
		s := st.Sys()
 | 
						|
		if s == nil {
 | 
						|
			return false, fmt.Errorf("error stat cgroup path %s", cgroupPath)
 | 
						|
		}
 | 
						|
 | 
						|
		if int(s.(*syscall.Stat_t).Uid) != uid {
 | 
						|
			return false, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if err := scanner.Err(); err != nil {
 | 
						|
		return false, errors.Wrapf(err, "parsing file /proc/self/cgroup")
 | 
						|
	}
 | 
						|
	return true, nil
 | 
						|
}
 |