Documentation
¶
Index ¶
- Constants
- func NewContext(ctx context.Context) context.Context
- func UnifiedPath() string
- func ValidBlkioWeight(s string) error
- func ValidCPUQuota(s string) error
- func ValidCPUs(s string) error
- func ValidMemOOMControl(s string) error
- func ValidMemSwappiness(s string) error
- func ValidPidsMax(s string) error
- func ValidSize(s string) error
- type CPUQuota
- type Config
- func (c Config) Apply() error
- func (c *Config) ApplyOnce() (bool, error)
- func (c Config) ApplyProc(pid int) (created bool, errs error)
- func (c *Config) Clean() (bool, error)
- func (c Config) Delegated(d Delegation) *Config
- func (c Config) Delete() (bool, error)
- func (c Config) Path() string
- func (c Config) String() string
- func (c Config) Uncapped() Config
- func (c *Config) WithLogger(l *plog.Logger) *Config
- type Delegation
- type Mgr
Constants ¶
const DefaultValue = "default"
DefaultValue is the pg_* keyword value asking for the capping it names to be put back where a node that never capped anything leaves it.
Removing a keyword leaves the capping alone, on purpose: what om wrote stays, and so does what anything else wrote. That leaves no way of lifting a cap, which this value is. It is a value and not a command because the configuration is what every node of the cluster converges to: a node provisioned tomorrow, or a peer taking the object over, has to arrive at the same capping as the node the reset was asked on.
Variables ¶
This section is empty.
Functions ¶
func UnifiedPath ¶
func UnifiedPath() string
func ValidBlkioWeight ¶
ValidBlkioWeight says whether s is a pg_blkio_weight value: a weight the kernel takes, between 1 and 10000 on the unified hierarchy, where the v1 one takes 10 to 1000.
func ValidCPUQuota ¶
ValidCPUQuota says whether s is a pg_cpu_quota or pg_cpu_burst value: a percentage of cpus, as 50%, 50%@all or 10%@2.
func ValidCPUs ¶
ValidCPUs says whether s is a pg_cpus or pg_mems value: a list of numbers and ranges of numbers, as 0-2,4.
func ValidMemOOMControl ¶
ValidMemOOMControl says whether s is a pg_mem_oom_control value: a flag.
It has no DefaultValue, for the reason ValidMemSwappiness has none.
func ValidMemSwappiness ¶
ValidMemSwappiness says whether s is a pg_mem_swappiness value: a percentage.
It has no DefaultValue: the capping is of the v1 hierarchy, which the reset is not written for. The keyword removed leaves the kernel value alone.
func ValidPidsMax ¶
ValidPidsMax says whether s is a pg_pids_max value: a count of processes.
Types ¶
type CPUQuota ¶
type CPUQuota string
func (CPUQuota) Convert ¶
Convert returns the cpu.max quota of a pg_cpu_quota expression, for the period it is given.
The percentage is of the cpus the expression names, one when it names none, so for a 100000 period on a node having 4 cpu threads:
100%@all => 400000, the four of them 50% => 50000, half of one 10%@2 => 20000, a tenth of two
type Config ¶
type Config struct {
ID string
CPUs string
Mems string
CPUQuota string
CPUBurst string
MemOOMControl string
MemLimit string
MemHigh string
PidsMax string
VMemLimit string
MemSwappiness string
BlockIOWeight string
// Delegation, when set, places the group under a subtree of the
// hierarchy delegated to an unprivileged user, rather than at the
// root. The ID stays the one the configuration gives: it is what
// orders the groups and what a reset is scoped by, and it is the
// same group of the same object wherever it lives.
Delegation *Delegation
// contains filtered or unexported fields
}
func (Config) Apply ¶
Apply is a convenience method for compatibility. Use (*Config).Apply() for state-tracking apply.
func (*Config) ApplyOnce ¶
ApplyOnce applies the pg configuration if it hasn't been applied already. Returns true if the config was applied, false if it was already applied.
func (Config) ApplyProc ¶
ApplyProc creates the cgroup, set caps, and add the specified process
On the unified hierarchy every value is written where the kernel keeps it, and the manager is asked only to make the cgroup and to delegate the controllers to it. It converts an oci runtime spec, whose weights are of the v1 hierarchy, and rescales them: a cpu weight of 1024 reached the kernel as 39, and a block io weight went to io.bfq.weight, a file only a kernel running the bfq scheduler has. It also cannot say a reset: it skips an empty cpuset, which is what clearing one is, and writes a memory limit as a number, where lifting one is the word "max".
The v1 hierarchy still goes through it, which is what it was written for.
Which of the two a node holds is read from the mode of its cgroup mounts, not from the unified manager failing. Falling back on a failure confused a node having no unified hierarchy with a write that went wrong on one, and the second sent the apply down a v1 path that could only fail differently: that is how a missing io.bfq.weight was reported as a missing v1 mountpoint.
func (Config) Delegated ¶
func (c Config) Delegated(d Delegation) *Config
Delegated returns the same group, placed under a delegated subtree.
func (Config) Path ¶
Path is where the group lives in the unified hierarchy: its ID, under the delegated subtree when there is one.
func (Config) String ¶
String is what an applied group logs, so it names the cappings that were applied and not the ones this node has no file for.
func (Config) Uncapped ¶
Clean removes the pg configuration if it was applied. Uncapped returns the same group, with every capping the unified hierarchy has a file for asked to go back where the kernel leaves it.
It is what "pg reset" applies. The keywords a configuration carries are not read: the point of the command is to lift cappings the configuration does not know about, left by an older agent, by systemd, or by hand.
type Delegation ¶
type Delegation struct {
// Root is the delegated subtree, relative to the unified mount,
// as /user.slice/user-1001.slice/user@1001.service.
Root string
// UID and GID own the groups made under Root.
UID int
GID int
}
Delegation is a subtree of the unified hierarchy delegated to an unprivileged user, the way systemd delegates user@<uid>.service to the systemd instance of that user.
A group made under it is owned by that user, so an engine running as them can create its own groups inside it: that is what lets a rootless container be placed in the group om caps. The cappings themselves are written by om, in files the user is not given, so they hold against the user as they hold against the container.
type Mgr ¶
type Mgr struct {
// contains filtered or unexported fields
}
func FromContext ¶
func (*Mgr) Ancestors ¶
Ancestors returns the registered groups id is nested in, parents first.
It is what a group moved under a delegated subtree carries along: the cappings of the namespace and the object are written on their groups, and a group placed elsewhere is only capped by them if they are made above it there too.
func (*Mgr) ApplyConfigs ¶
ApplyConfigs applies all registered pg configs in order (base to leaf). Each config is applied only if not already applied.
func (*Mgr) Register ¶
Register adds a group to those an action applies, keyed by where it lives: the same group delegated to a user is another group of the hierarchy, and is made and capped on its own.
func (*Mgr) ResetConfigs ¶
ResetConfigs lifts the capping of the registered groups at and under the reset root, base to leaf, each one once.
The order matters the same way it does when capping: a parent has to be uncapped before a child, or the child stays capped by what the parent still holds. Sorting the ids gives that order, a parent being a prefix of its children.
It is called once per resource of the walk, as applying is, and lifts on each call only what the calls before it did not: a resource registers its group and the groups registered so far are already lifted.
func (*Mgr) SetResetRoot ¶
SetResetRoot says which of the registered groups an action may lift the capping of: that one, and the ones under it.
It is what keeps an object from uncapping what it does not own. The groups registered by an action reach above the object, up to the slice of the namespace and the slice holding every object of the node, because a child cannot be capped before its parents exist. Those are the namespace's to lift, not this object's.