This file is indexed.

/usr/share/gocode/src/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go is in golang-github-opencontainers-runc-dev 1.0.0~rc4+dfsg1-6.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// +build linux

package rootless

import (
	"fmt"

	"github.com/opencontainers/runc/libcontainer/cgroups"
	"github.com/opencontainers/runc/libcontainer/cgroups/fs"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/opencontainers/runc/libcontainer/configs/validate"
)

// TODO: This is copied from libcontainer/cgroups/fs, which duplicates this code
//       needlessly. We should probably export this list.

var subsystems = []subsystem{
	&fs.CpusetGroup{},
	&fs.DevicesGroup{},
	&fs.MemoryGroup{},
	&fs.CpuGroup{},
	&fs.CpuacctGroup{},
	&fs.PidsGroup{},
	&fs.BlkioGroup{},
	&fs.HugetlbGroup{},
	&fs.NetClsGroup{},
	&fs.NetPrioGroup{},
	&fs.PerfEventGroup{},
	&fs.FreezerGroup{},
	&fs.NameGroup{GroupName: "name=systemd"},
}

type subsystem interface {
	// Name returns the name of the subsystem.
	Name() string

	// Returns the stats, as 'stats', corresponding to the cgroup under 'path'.
	GetStats(path string, stats *cgroups.Stats) error
}

// The noop cgroup manager is used for rootless containers, because we currently
// cannot manage cgroups if we are in a rootless setup. This manager is chosen
// by factory if we are in rootless mode. We error out if any cgroup options are
// set in the config -- this may change in the future with upcoming kernel features
// like the cgroup namespace.

type Manager struct {
	Cgroups *configs.Cgroup
	Paths   map[string]string
}

func (m *Manager) Apply(pid int) error {
	// If there are no cgroup settings, there's nothing to do.
	if m.Cgroups == nil {
		return nil
	}

	// We can't set paths.
	// TODO(cyphar): Implement the case where the runner of a rootless container
	//               owns their own cgroup, which would allow us to set up a
	//               cgroup for each path.
	if m.Cgroups.Paths != nil {
		return fmt.Errorf("cannot change cgroup path in rootless container")
	}

	// We load the paths into the manager.
	paths := make(map[string]string)
	for _, sys := range subsystems {
		name := sys.Name()

		path, err := cgroups.GetOwnCgroupPath(name)
		if err != nil {
			// Ignore paths we couldn't resolve.
			continue
		}

		paths[name] = path
	}

	m.Paths = paths
	return nil
}

func (m *Manager) GetPaths() map[string]string {
	return m.Paths
}

func (m *Manager) Set(container *configs.Config) error {
	// We have to re-do the validation here, since someone might decide to
	// update a rootless container.
	return validate.New().Validate(container)
}

func (m *Manager) GetPids() ([]int, error) {
	dir, err := cgroups.GetOwnCgroupPath("devices")
	if err != nil {
		return nil, err
	}
	return cgroups.GetPids(dir)
}

func (m *Manager) GetAllPids() ([]int, error) {
	dir, err := cgroups.GetOwnCgroupPath("devices")
	if err != nil {
		return nil, err
	}
	return cgroups.GetAllPids(dir)
}

func (m *Manager) GetStats() (*cgroups.Stats, error) {
	// TODO(cyphar): We can make this work if we figure out a way to allow usage
	//               of cgroups with a rootless container. While this doesn't
	//               actually require write access to a cgroup directory, the
	//               statistics are not useful if they can be affected by
	//               non-container processes.
	return nil, fmt.Errorf("cannot get cgroup stats in rootless container")
}

func (m *Manager) Freeze(state configs.FreezerState) error {
	// TODO(cyphar): We can make this work if we figure out a way to allow usage
	//               of cgroups with a rootless container.
	return fmt.Errorf("cannot use freezer cgroup in rootless container")
}

func (m *Manager) Destroy() error {
	// We don't have to do anything here because we didn't do any setup.
	return nil
}