cgroup

package
v0.0.0-...-384d106 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2024 License: GPL-3.0 Imports: 25 Imported by: 130

Documentation

Index

Constants

View Source
const (
	// Separate block, because iota is fun
	Unknown = iota
	V1
	V2
)

Variables

View Source
var ErrCannotTrackProcess = errors.New("cannot track application process")
View Source
var FreezeSnapProcesses = func(ctx context.Context, snapName string) error {
	return errors.New("FreezeSnapProcesses not implemented")
}

FreezeSnapProcesses suspends execution of all the processes belonging to a given snap. Processes remain frozen until ThawSnapProcesses is called, care must be taken not to freezer processes indefinitely.

The freeze operation is not instant. Once commenced it proceeds asynchronously. Internally the function waits for the freezing to complete in at most maxFreezeTimeout or if the passed context is cancelled. If this time is insufficient then the processes are thawed and an error is returned.

A correct implementation is picked depending on cgroup v1 or v2 use in the system. When cgroup v1 is detected, the call will directly act on the freezer group created when a snap process was started, while with v2 the call will act on all tracking groups of a snap.

This operation can be mocked with MockFreezing

View Source
var KillSnapProcesses = func(ctx context.Context, snapName string) error {
	return errors.New("KillSnapProcesses not implemented")
}

KillSnapProcesses sends a signal to all the processes belonging to a given snap.

A correct implementation is picked depending on cgroup v1 or v2 use in the system. For both cgroup v1 and v2, the call will act on all tracking groups of a snap.

Note: Algorithms used for killing in cgroup v1 and v2 are slightly different.

  • cgroup v1: freeze/kill/thaw. This is to address multiple edge cases: (1) Hybrid v1/v2 cgroups with pids controller mounted only on v1 or v2 (Ubuntu 20.04) so we cannot guarantee having pids.max so we use the freezer cgroup instead. (2) Address a known bug on systemd v237 for non-root users where transient scopes are not created (e.g. on Ubuntu 18.04) so we use the freezer cgroup for tracking. This is only useful for killing apps or processes which do not have their lifecycle managed by external entities like systemd.
  • cgroup v2: stop forking through pids.max, kill processes until cgroup is drained. This is to address kernel versions without v2 freezer support so we use pids.max to prevent fork bombs from racing with snapd.
View Source
var ThawSnapProcesses = func(snapName string) error {
	return errors.New("ThawSnapProcesses not implemented")
}

ThawSnapProcesses resumes execution of all processes belonging to a given snap.

A correct implementation is picked depending on cgroup v1 or v2 use in the system. When cgroup v1 is detected, the call will directly act on the freezer group created when a snap process was started, while with v2 the call will act on all tracking groups of a snap.

This operation can be mocked with MockFreezing

Functions

func CheckMemoryCgroup

func CheckMemoryCgroup() error

CheckMemoryCgroup checks if the memory cgroup is enabled. It will return an error if not.

Since the control groups can be enabled/disabled without the kernel config the only way to identify the status of memory control groups is via /proc/cgroups "cat /proc/cgroups | grep memory" returns the active status of memory control group and the 3rd parameter is the status 0 => false => disabled 1 => true => enabled

func ConfirmSystemdAppTracking

func ConfirmSystemdAppTracking(securityTag string) error

ConfirmSystemdAppTracking checks if systemd tracks this process as a snap app.

If the application process is not tracked then ErrCannotTrackProcess is returned.

func ConfirmSystemdServiceTracking

func ConfirmSystemdServiceTracking(securityTag string) error

ConfirmSystemdServiceTracking checks if systemd tracks this process as a snap service.

Systemd is placing started services, both user and system, into appropriate tracking groups. Given a security tag we can confirm if the current process belongs to such tracking group and thus could be identified by snapd as belonging to a particular snap and application.

If the application process is not tracked then ErrCannotTrackProcess is returned.

func CreateTransientScopeForTracking

func CreateTransientScopeForTracking(securityTag string, opts *TrackingOptions) error

CreateTransientScopeForTracking puts the current process in a transient scope.

To quote systemd documentation about scope units:

>> Scopes units manage a set of system processes. Unlike service units, >> scope units manage externally created processes, and do not fork off >> processes on its own.

Scope names must be unique, a randomly generated UUID is appended to the security tag, further suffixed with the string ".scope".

func InstancePathsOfSnap

func InstancePathsOfSnap(snapInstanceName string, options InstancePathsOptions) ([]string, error)

func IsUnified

func IsUnified() bool

IsUnified returns true when a unified cgroup hierarchy is in use

func MockFreezing

func MockFreezing(freeze func(ctx context.Context, snapName string) error, thaw func(snapName string) error) (restore func())

MockFreezing replaces the real implementation of freeze and thaw.

func MockVersion

func MockVersion(mockVersion int, mockErr error) (restore func())

MockVersion sets the reported version of cgroup support. For use in testing only

func MonitorSnapEnded

func MonitorSnapEnded(snapName string, channel chan<- string) error

MonitorSnapEnded monitors the running instances of a snap. Once all instances of the snap have stopped, its name is pushed through the supplied channel. This allows the caller to use the same channel to monitor several snaps.

func PidsOfSnap

func PidsOfSnap(snapInstanceName string) (map[string][]int, error)

PidsOfSnap returns the association of security tags to PIDs.

NOTE: This function returns a reliable result only if the refresh-app-awareness feature was enabled before all processes related to the given snap were started. If the feature wasn't always enabled then only service process are correctly accounted for.

The return value is a snapshot of the pids for a given snap, grouped by security tag. The result may be immediately stale as processes fork and exit.

Importantly, if the per-snap lock is held while computing the set, then the following guarantee is true: if a security tag is not among the results then no such tag can come into existence while the lock is held.

This can be used to classify the activity of a given snap into activity classes, based on the nature of the security tags encountered.

func ProcGroup

func ProcGroup(pid int, matcher GroupMatcher) (string, error)

ProcGroup finds the path of a given cgroup controller for provided process id.

func ProcPidPath

func ProcPidPath(pid int) string

ProcPidPath returns the path to the cgroup file under /proc for the given process id.

func ProcessPathInTrackingCgroup

func ProcessPathInTrackingCgroup(pid int) (string, error)

ProcessPathInTrackingCgroup returns the path in the hierarchy of the tracking cgroup.

Tracking cgroup is whichever cgroup systemd uses for tracking processes. On modern systems this is the v2 cgroup. On older systems it is the controller-less name=systemd cgroup.

This function fails on systems where systemd is not used and subsequently cgroups are not mounted.

func SnapNameFromPid

func SnapNameFromPid(pid int) (string, error)

func Version

func Version() (int, error)

Version returns the detected cgroup version

Types

type GroupMatcher

type GroupMatcher interface {
	String() string
	// Match returns true when given tuple of hierarchy-ID and controllers is a match
	Match(id, maybeControllers string) bool
}

GroupMatcher attempts to match the cgroup entry

func MatchUnifiedHierarchy

func MatchUnifiedHierarchy() GroupMatcher

MatchUnifiedHierarchy provides matches for unified cgroup hierarchies

func MatchV1Controller

func MatchV1Controller(controller string) GroupMatcher

MatchV1Controller provides a matches for a given v1 controller

func MatchV1NamedHierarchy

func MatchV1NamedHierarchy(hierarchyName string) GroupMatcher

MatchV1NamedHierarchy provides a matcher for a given named v1 hierarchy

type InstancePathsOptions

type InstancePathsOptions struct {
	ReturnCGroupPath bool
}

type TrackingOptions

type TrackingOptions struct {
	// AllowSessionBus controls if CreateTransientScopeForTracking will
	// consider using the session bus for making the request.
	AllowSessionBus bool
}

TrackingOptions control how tracking, based on systemd transient scope, operates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL