README

cgroups

Build Status codecov GoDoc Go Report Card

Go package for creating, managing, inspecting, and destroying cgroups. The resources format for settings on the cgroup uses the OCI runtime-spec found here.

Examples

Create a new cgroup

This creates a new cgroup using a static path for all subsystems under /test.

  • /sys/fs/cgroup/cpu/test
  • /sys/fs/cgroup/memory/test
  • etc....

It uses a single hierarchy and specifies cpu shares as a resource constraint and uses the v1 implementation of cgroups.

shares := uint64(100)
control, err := cgroups.New(cgroups.V1, cgroups.StaticPath("/test"), &specs.LinuxResources{
    CPU: &specs.CPU{
        Shares: &shares,
    },
})
defer control.Delete()
Create with systemd slice support
control, err := cgroups.New(cgroups.Systemd, cgroups.Slice("system.slice", "runc-test"), &specs.LinuxResources{
    CPU: &specs.CPU{
        Shares: &shares,
    },
})

Load an existing cgroup
control, err = cgroups.Load(cgroups.V1, cgroups.StaticPath("/test"))
Add a process to the cgroup
if err := control.Add(cgroups.Process{Pid:1234}); err != nil {
}
Update the cgroup

To update the resources applied in the cgroup

shares = uint64(200)
if err := control.Update(&specs.LinuxResources{
    CPU: &specs.LinuxCPU{
        Shares: &shares,
    },
}); err != nil {
}
Freeze and Thaw the cgroup
if err := control.Freeze(); err != nil {
}
if err := control.Thaw(); err != nil {
}
List all processes in the cgroup or recursively
processes, err := control.Processes(cgroups.Devices, recursive)
Get Stats on the cgroup
stats, err := control.Stat()

By adding cgroups.IgnoreNotExist all non-existent files will be ignored, e.g. swap memory stats without swap enabled

stats, err := control.Stat(cgroups.IgnoreNotExist)
Move process across cgroups

This allows you to take processes from one cgroup and move them to another.

err := control.MoveTo(destination)
Create subcgroup
subCgroup, err := control.New("child", resources)
Registering for memory events

This allows you to get notified by an eventfd for v1 memory cgroups events.

event := cgroups.MemoryThresholdEvent(50 * 1024 * 1024, false)
efd, err := control.RegisterMemoryEvent(event)
event := cgroups.MemoryPressureEvent(cgroups.MediumPressure, cgroups.DefaultMode)
efd, err := control.RegisterMemoryEvent(event)
efd, err := control.OOMEventFD()
// or by using RegisterMemoryEvent
event := cgroups.OOMEvent()
efd, err := control.RegisterMemoryEvent(event)
Attention

All static path should not include /sys/fs/cgroup/ prefix, it should start with your own cgroups name

Project details

Cgroups is a containerd sub-project, licensed under the Apache 2.0 license. As a containerd sub-project, you will find the:

information in our containerd/project repository.

Expand ▾ Collapse ▴

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidPid               = errors.New("cgroups: pid must be greater than 0")
	ErrMountPointNotExist       = errors.New("cgroups: cgroup mountpoint does not exist")
	ErrInvalidFormat            = errors.New("cgroups: parsing file with invalid format failed")
	ErrFreezerNotSupported      = errors.New("cgroups: freezer cgroup not supported on this system")
	ErrMemoryNotSupported       = errors.New("cgroups: memory cgroup not supported on this system")
	ErrCgroupDeleted            = errors.New("cgroups: cgroup deleted")
	ErrNoCgroupMountDestination = errors.New("cgroups: cannot find cgroup mount destination")
)
View Source
var (
	// ErrIgnoreSubsystem allows the specific subsystem to be skipped
	ErrIgnoreSubsystem = errors.New("skip subsystem")
	// ErrDevicesRequired is returned when the devices subsystem is required but
	// does not exist or is not active
	ErrDevicesRequired = errors.New("devices subsystem is required")
)
View Source
var ErrControllerNotActive = errors.New("controller is not supported")

    ErrControllerNotActive is returned when a controller is not supported or enabled

    Functions

    func AllowAny

    func AllowAny(_ Subsystem, _ Path, _ error) error

      AllowAny allows any subsystem errors to be skipped

      func IgnoreModules

      func IgnoreModules(names ...string) func(*memoryController)

        IgnoreModules configure the memory controller to not read memory metrics for some module names (e.g. passing "memsw" would avoid all the memory.memsw.* entries)

        func IgnoreNotExist

        func IgnoreNotExist(err error) error

          IgnoreNotExist ignores any errors that are for not existing files

          func NewBlkio

          func NewBlkio(root string, options ...func(controller *blkioController)) *blkioController

            NewBlkio returns a Blkio controller given the root folder of cgroups. It may optionally accept other configuration options, such as ProcRoot(path)

            func NewCpu

            func NewCpu(root string) *cpuController

            func NewCpuacct

            func NewCpuacct(root string) *cpuacctController

            func NewCpuset

            func NewCpuset(root string) *cpusetController

            func NewDevices

            func NewDevices(root string) *devicesController

            func NewFreezer

            func NewFreezer(root string) *freezerController

            func NewHugetlb

            func NewHugetlb(root string) (*hugetlbController, error)

            func NewMemory

            func NewMemory(root string, options ...func(*memoryController)) *memoryController

              NewMemory returns a Memory controller given the root folder of cgroups. It may optionally accept other configuration options, such as IgnoreModules(...)

              func NewNamed

              func NewNamed(root string, name Name) *namedController

              func NewNetCls

              func NewNetCls(root string) *netclsController

              func NewNetPrio

              func NewNetPrio(root string) *netprioController

              func NewPids

              func NewPids(root string) *pidsController

              func NewRdma

              func NewRdma(root string) *rdmaController

              func OptionalSwap

              func OptionalSwap() func(*memoryController)

                OptionalSwap allows the memory controller to not fail if cgroups is not accounting Swap memory (there are no memory.memsw.* entries)

                func ProcRoot

                func ProcRoot(path string) func(controller *blkioController)

                  ProcRoot overrides the default location of the "/proc" filesystem

                  func RequireDevices

                  func RequireDevices(s Subsystem, _ Path, _ error) error

                    RequireDevices requires the device subsystem but no others

                    func RootPath

                    func RootPath(subsystem Name) (string, error)

                    func RunningInUserNS

                    func RunningInUserNS() bool

                      RunningInUserNS detects whether we are currently running in a user namespace. Copied from github.com/lxc/lxd/shared/util.go

                      Types

                      type CGMode

                      type CGMode int

                        CGMode is the cgroups mode of the host system

                        const (
                        	// Unavailable cgroup mountpoint
                        	Unavailable CGMode = iota
                        	// Legacy cgroups v1
                        	Legacy
                        	// Hybrid with cgroups v1 and v2 controllers mounted
                        	Hybrid
                        	// Unified with only cgroups v2 mounted
                        	Unified
                        )

                        func Mode

                        func Mode() CGMode

                          Mode returns the cgroups mode running on the host

                          type Cgroup

                          type Cgroup interface {
                          	// New creates a new cgroup under the calling cgroup
                          	New(string, *specs.LinuxResources) (Cgroup, error)
                          	// Add adds a process to the cgroup (cgroup.procs)
                          	Add(Process) error
                          	// AddTask adds a process to the cgroup (tasks)
                          	AddTask(Process) error
                          	// Delete removes the cgroup as a whole
                          	Delete() error
                          	// MoveTo moves all the processes under the calling cgroup to the provided one
                          	// subsystems are moved one at a time
                          	MoveTo(Cgroup) error
                          	// Stat returns the stats for all subsystems in the cgroup
                          	Stat(...ErrorHandler) (*v1.Metrics, error)
                          	// Update updates all the subsystems with the provided resource changes
                          	Update(resources *specs.LinuxResources) error
                          	// Processes returns all the processes in a select subsystem for the cgroup
                          	Processes(Name, bool) ([]Process, error)
                          	// Tasks returns all the tasks in a select subsystem for the cgroup
                          	Tasks(Name, bool) ([]Task, error)
                          	// Freeze freezes or pauses all processes inside the cgroup
                          	Freeze() error
                          	// Thaw thaw or resumes all processes inside the cgroup
                          	Thaw() error
                          	// OOMEventFD returns the memory subsystem's event fd for OOM events
                          	OOMEventFD() (uintptr, error)
                          	// RegisterMemoryEvent returns the memory subsystems event fd for whatever memory event was
                          	// registered for. Can alternatively register for the oom event with this method.
                          	RegisterMemoryEvent(MemoryEvent) (uintptr, error)
                          	// State returns the cgroups current state
                          	State() State
                          	// Subsystems returns all the subsystems in the cgroup
                          	Subsystems() []Subsystem
                          }

                            Cgroup handles interactions with the individual groups to perform actions on them as them main interface to this cgroup package

                            func Load

                            func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error)

                              Load will load an existing cgroup and allow it to be controlled All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name

                              func New

                              func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error)

                                New returns a new control via the cgroup cgroups interface

                                type ErrorHandler

                                type ErrorHandler func(err error) error

                                  ErrorHandler is a function that handles and acts on errors

                                  type EventNotificationMode

                                  type EventNotificationMode string

                                    EventNotificationMode corresponds to the notification modes for the memory cgroups pressure level notifications.

                                    const (
                                    	DefaultMode   EventNotificationMode = "default"
                                    	LocalMode     EventNotificationMode = "local"
                                    	HierarchyMode EventNotificationMode = "hierarchy"
                                    )

                                      There are three optional modes that specify different propagation behavior:

                                      - "default": this is the default behavior specified above. This mode is the
                                        same as omitting the optional mode parameter, preserved by backwards
                                        compatibility.
                                      - "hierarchy": events always propagate up to the root, similar to the default
                                        behavior, except that propagation continues regardless of whether there are
                                        event listeners at each level, with the "hierarchy" mode. In the above
                                        example, groups A, B, and C will receive notification of memory pressure.
                                      - "local": events are pass-through, i.e. they only receive notifications when
                                        memory pressure is experienced in the memcg for which the notification is
                                        registered. In the above example, group C will receive notification if
                                        registered for "local" notification and the group experiences memory
                                        pressure. However, group B will never receive notification, regardless if
                                        there is an event listener for group C or not, if group B is registered for
                                        local notification.
                                        "https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt" Section 11
                                      

                                      type Hierarchy

                                      type Hierarchy func() ([]Subsystem, error)

                                        Hierarchy enables both unified and split hierarchy for cgroups

                                        func SingleSubsystem

                                        func SingleSubsystem(baseHierarchy Hierarchy, subsystem Name) Hierarchy

                                          SingleSubsystem returns a single cgroup subsystem within the base Hierarchy

                                          type InitCheck

                                          type InitCheck func(Subsystem, Path, error) error

                                            InitCheck allows subsystems errors to be checked when initialized or loaded

                                            type InitConfig

                                            type InitConfig struct {
                                            	// InitCheck can be used to check initialization errors from the subsystem
                                            	InitCheck InitCheck
                                            }

                                              InitConfig provides configuration options for the creation or loading of a cgroup and its subsystems

                                              type InitOpts

                                              type InitOpts func(*InitConfig) error

                                                InitOpts allows configuration for the creation or loading of a cgroup

                                                type MemoryEvent

                                                type MemoryEvent interface {
                                                	Arg() string
                                                	EventFile() string
                                                }

                                                  MemoryEvent is an interface that V1 memory Cgroup notifications implement. Arg returns the file name whose fd should be written to "cgroups.event_control". EventFile returns the name of the file that supports the notification api e.g. "memory.usage_in_bytes".

                                                  func MemoryPressureEvent

                                                  func MemoryPressureEvent(pressureLevel MemoryPressureLevel, hierarchy EventNotificationMode) MemoryEvent

                                                    MemoryPressureEvent returns a new memory pressure event to be used with RegisterMemoryEvent.

                                                    func MemoryThresholdEvent

                                                    func MemoryThresholdEvent(threshold uint64, swap bool) MemoryEvent

                                                      MemoryThresholdEvent returns a new memory threshold event to be used with RegisterMemoryEvent. If swap is true, the event will be registered using memory.memsw.usage_in_bytes

                                                      func OOMEvent

                                                      func OOMEvent() MemoryEvent

                                                        OOMEvent returns a new oom event to be used with RegisterMemoryEvent.

                                                        type MemoryPressureLevel

                                                        type MemoryPressureLevel string

                                                          MemoryPressureLevel corresponds to the memory pressure levels defined for memory cgroups.

                                                          const (
                                                          	LowPressure      MemoryPressureLevel = "low"
                                                          	MediumPressure   MemoryPressureLevel = "medium"
                                                          	CriticalPressure MemoryPressureLevel = "critical"
                                                          )

                                                            The three memory pressure levels are as follows.

                                                            - The "low" level means that the system is reclaiming memory for new
                                                              allocations. Monitoring this reclaiming activity might be useful for
                                                              maintaining cache level. Upon notification, the program (typically
                                                              "Activity Manager") might analyze vmstat and act in advance (i.e.
                                                              prematurely shutdown unimportant services).
                                                            - The "medium" level means that the system is experiencing medium memory
                                                              pressure, the system might be making swap, paging out active file caches,
                                                              etc. Upon this event applications may decide to further analyze
                                                              vmstat/zoneinfo/memcg or internal memory usage statistics and free any
                                                              resources that can be easily reconstructed or re-read from a disk.
                                                            - The "critical" level means that the system is actively thrashing, it is
                                                              about to out of memory (OOM) or even the in-kernel OOM killer is on its
                                                              way to trigger. Applications should do whatever they can to help the
                                                              system. It might be too late to consult with vmstat or any other
                                                              statistics, so it is advisable to take an immediate action.
                                                              "https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt" Section 11
                                                            

                                                            type Name

                                                            type Name string

                                                              Name is a typed name for a cgroup subsystem

                                                              const (
                                                              	Devices   Name = "devices"
                                                              	Hugetlb   Name = "hugetlb"
                                                              	Freezer   Name = "freezer"
                                                              	Pids      Name = "pids"
                                                              	NetCLS    Name = "net_cls"
                                                              	NetPrio   Name = "net_prio"
                                                              	PerfEvent Name = "perf_event"
                                                              	Cpuset    Name = "cpuset"
                                                              	Cpu       Name = "cpu"
                                                              	Cpuacct   Name = "cpuacct"
                                                              	Memory    Name = "memory"
                                                              	Blkio     Name = "blkio"
                                                              	Rdma      Name = "rdma"
                                                              )
                                                              const (
                                                              	SystemdDbus Name = "systemd"
                                                              )

                                                              func Subsystems

                                                              func Subsystems() []Name

                                                                Subsystems returns a complete list of the default cgroups available on most linux systems

                                                                type Path

                                                                type Path func(subsystem Name) (string, error)

                                                                func NestedPath

                                                                func NestedPath(suffix string) Path

                                                                  NestedPath will nest the cgroups based on the calling processes cgroup placing its child processes inside its own path

                                                                  func PidPath

                                                                  func PidPath(pid int) Path

                                                                    PidPath will return the correct cgroup paths for an existing process running inside a cgroup This is commonly used for the Load function to restore an existing container

                                                                    func Slice

                                                                    func Slice(slice, name string) Path

                                                                    func StaticPath

                                                                    func StaticPath(path string) Path

                                                                      StaticPath returns a static path to use for all cgroups

                                                                      type PerfEventController

                                                                      type PerfEventController struct {
                                                                      	// contains filtered or unexported fields
                                                                      }

                                                                      func NewPerfEvent

                                                                      func NewPerfEvent(root string) *PerfEventController

                                                                      func (*PerfEventController) Name

                                                                      func (p *PerfEventController) Name() Name

                                                                      func (*PerfEventController) Path

                                                                      func (p *PerfEventController) Path(path string) string

                                                                      type Process

                                                                      type Process struct {
                                                                      	// Subsystem is the name of the subsystem that the process is in
                                                                      	Subsystem Name
                                                                      	// Pid is the process id of the process
                                                                      	Pid int
                                                                      	// Path is the full path of the subsystem and location that the process is in
                                                                      	Path string
                                                                      }

                                                                      type State

                                                                      type State string

                                                                        State is a type that represents the state of the current cgroup

                                                                        const (
                                                                        	Unknown  State = ""
                                                                        	Thawed   State = "thawed"
                                                                        	Frozen   State = "frozen"
                                                                        	Freezing State = "freezing"
                                                                        	Deleted  State = "deleted"
                                                                        )

                                                                        type Subsystem

                                                                        type Subsystem interface {
                                                                        	Name() Name
                                                                        }

                                                                        func Systemd

                                                                        func Systemd() ([]Subsystem, error)

                                                                        func V1

                                                                        func V1() ([]Subsystem, error)

                                                                          V1 returns all the groups in the default cgroups mountpoint in a single hierarchy

                                                                          type SystemdController

                                                                          type SystemdController struct {
                                                                          	// contains filtered or unexported fields
                                                                          }

                                                                          func NewSystemd

                                                                          func NewSystemd(root string) (*SystemdController, error)

                                                                          func (*SystemdController) Create

                                                                          func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error

                                                                          func (*SystemdController) Delete

                                                                          func (s *SystemdController) Delete(path string) error

                                                                          func (*SystemdController) Name

                                                                          func (s *SystemdController) Name() Name

                                                                          type Task

                                                                          type Task struct {
                                                                          	// Subsystem is the name of the subsystem that the task is in
                                                                          	Subsystem Name
                                                                          	// Pid is the process id of the task
                                                                          	Pid int
                                                                          	// Path is the full path of the subsystem and location that the task is in
                                                                          	Path string
                                                                          }

                                                                          Directories

                                                                          Path Synopsis
                                                                          cmd
                                                                          stats
                                                                          v1
                                                                          v2
                                                                          Devicefilter containes eBPF device filter program The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c Although ebpf.c is originally licensed under LGPL-3.0-or-later, the author (Giuseppe Scrivano) agreed to relicense the file in Apache License 2.0: https://github.com/opencontainers/runc/issues/2144#issuecomment-543116397 This particular Go implementation based on runc version https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
                                                                          Devicefilter containes eBPF device filter program The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c Although ebpf.c is originally licensed under LGPL-3.0-or-later, the author (Giuseppe Scrivano) agreed to relicense the file in Apache License 2.0: https://github.com/opencontainers/runc/issues/2144#issuecomment-543116397 This particular Go implementation based on runc version https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go