Documentation ¶
Overview ¶
Package quota defines state structures for resource quota groups for snaps.
Index ¶
- func ResolveCrossReferences(grps map[string]*Group) error
- type Group
- func (grp *Group) CurrentMemoryUsage() (quantity.Size, error)
- func (grp *Group) CurrentTaskUsage() (int, error)
- func (grp *Group) GetCPUSetQuota() []int
- func (grp *Group) GetLocalCPUQuota() (int, int)
- func (grp *Group) GetLocalCPUSetQuota() []int
- func (grp *Group) GetQuotaResources() Resources
- func (grp *Group) JournalConfFileName() string
- func (grp *Group) JournalNamespaceName() string
- func (grp *Group) JournalQuotaSet() bool
- func (grp *Group) JournalServiceDropInDir() string
- func (grp *Group) JournalServiceDropInFile() string
- func (grp *Group) JournalServiceName() string
- func (grp *Group) NewSubGroup(name string, resourceLimits Resources) (*Group, error)
- func (grp *Group) ServiceMap() map[string]*Group
- func (grp *Group) SliceFileName() string
- func (grp *Group) UpdateQuotaLimits(resourceLimits Resources) error
- func (grp *Group) ValidateNestingAndSnaps() error
- type GroupQuotaCPU
- type GroupQuotaJournal
- type QuotaGroupSet
- type ResourceCPU
- type ResourceCPUSet
- type ResourceJournal
- type ResourceJournalRate
- type ResourceJournalSize
- type ResourceMemory
- type ResourceThreads
- type Resources
- type ResourcesBuilder
- func (rb *ResourcesBuilder) Build() Resources
- func (rb *ResourcesBuilder) WithCPUCount(count int) *ResourcesBuilder
- func (rb *ResourcesBuilder) WithCPUPercentage(percentage int) *ResourcesBuilder
- func (rb *ResourcesBuilder) WithCPUSet(cpuSet []int) *ResourcesBuilder
- func (rb *ResourcesBuilder) WithJournalNamespace() *ResourcesBuilder
- func (rb *ResourcesBuilder) WithJournalRate(count int, period time.Duration) *ResourcesBuilder
- func (rb *ResourcesBuilder) WithJournalSize(limit quantity.Size) *ResourcesBuilder
- func (rb *ResourcesBuilder) WithMemoryLimit(limit quantity.Size) *ResourcesBuilder
- func (rb *ResourcesBuilder) WithThreadLimit(limit int) *ResourcesBuilder
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ResolveCrossReferences ¶
ResolveCrossReferences takes a set of deserialized groups and sets all cross references amongst them using the unexported fields which are not serialized.
Types ¶
type Group ¶
type Group struct { // Name is the name of the quota group. This name is used the // name of the systemd slice underlying the quota group. // Certain names are reserved for future use: system, snapd, root, user. // Otherwise names following the same rules as snap names can be used. Name string `json:"name,omitempty"` // SubGroups is the set of sub-groups that are subject to this quota. // Sub-groups have their own limits, subject to the requirement that the // highest quota for a sub-group is that of the parent group. SubGroups []string `json:"sub-groups,omitempty"` // MemoryLimit is the limit of memory available to the processes in the // group where if the total used memory of all the processes exceeds the // limit, oom-killer is invoked which will start killing processes. The // specific behavior of which processes are killed is subject to the // ExhaustionBehavior. MemoryLimit is expressed in bytes. MemoryLimit quantity.Size `json:"memory-limit,omitempty"` // CPULimit is the quotas for the cpu and consists of a couple of nubs. // It is possible to control the percentage of the cpu available for the group // and which cores (requires cgroupsv2) are allowed to be used. CPULimit *GroupQuotaCPU `json:"cpu-limit,omitempty"` // ThreadLimit is the limit of threads/processes that can be active at once in // the group. Once the limit is reached, further forks() or clones() will be blocked // for processes in the group. ThreadLimit int `json:"task-limit,omitempty"` // JournalLimit is the limits that apply to the journal for this quota group. When // this limit is present, then the quota group will be assigned a log namespace for // journald. JournalLimit *GroupQuotaJournal `json:"journal-limit,omitempty"` // ParentGroup is the the parent group that this group is a child of. If it // is empty, then this is a "root" quota group. ParentGroup string `json:"parent-group,omitempty"` // Snaps is the set of snaps that is part of this quota group. If both this // and Services is empty then the underlying slice may not exist on the system. Snaps []string `json:"snaps,omitempty"` // Services is the set of snap services that is part of this quota group. The entries here // are in the format of snap-name.service-name, and the snap-name will refer to a snap in a // parent quota group. If both this and Snaps is empty then the underlying slice may not // exist on the system. Services []string `json:"services,omitempty"` // contains filtered or unexported fields }
Group is a quota group of snaps, services or sub-groups that are all subject to specific resource quotas. The only quota resource types currently supported is memory, but this can be expanded in the future.
func (*Group) CurrentMemoryUsage ¶
CurrentMemoryUsage returns the current memory usage of the quota group. For quota groups which do not yet have a backing systemd slice on the system ( i.e. quota groups without any snaps in them), the memory usage is reported as 0.
func (*Group) CurrentTaskUsage ¶
CurrentTaskUsage returns the current task (processes, threads) usage of the quota group. For quota groups which do not yet have a backing systemd slice on the system ( i.e. quota groups without any snaps in them), the task usage is reported as 0
func (*Group) GetCPUSetQuota ¶
GetCPUSetQuota returns the currently active CPU set quota for this group, which includes the case where the CPU set is inherited from a parent group.
func (*Group) GetLocalCPUQuota ¶
GetLocalCPUQuota returns the final calculated count and percentage of the current CPU quota for the group. This does not return any inherited CPU quota, but it does take any inherited CPU set into account to adjust in the case of a relative usage percentage. If the CPU count is set to 0, then it is expected that it returns CPULimit.Percentage times the number of all allowed cores. This is either the full amount of cores present on the system, or it is the number of cores allowed for this group. Otherwise this command should return the actual count and percentage set by the group.
func (*Group) GetLocalCPUSetQuota ¶
GetLocalCPUSetQuota returns the current CPU set quota for the group. This does not return any inheritted CPU set quota.
func (*Group) GetQuotaResources ¶
func (*Group) JournalConfFileName ¶
JournalConfFileName returns the name of the journal configuration file that should be used for this quota group. As an example, a group named "foo" will return a name of journald@snap-foo.conf
func (*Group) JournalNamespaceName ¶
JournalNamespaceName returns the snap formatted name of the log namespace, corresponding to the namespace of the journal quota affecting this group. If this group is a service group, this returns the journal namespace name for the parent group instead.
func (*Group) JournalQuotaSet ¶
JournalQuotaSet returns true if the group is subject to a journal quota. This should only be used in cases where the caller is interested in knowing if a quota group is affected by a journal quota, and not in the case where the caller needs to know if the group itself has a journal quota set. For service groups this depends on their parent quota group.
func (*Group) JournalServiceDropInDir ¶
JournalServiceFile returns the directory specific to this quota group for its journal service unit drop-in.
func (*Group) JournalServiceDropInFile ¶
JournalServiceDropInFile returns the full path to the journal service unit drop-in file for the quota group.
func (*Group) JournalServiceName ¶
JournalServiceName returns the systemd service name for the quota group.
func (*Group) NewSubGroup ¶
NewSubGroup creates a new sub group under the current group.
func (*Group) ServiceMap ¶
ServiceMap calculates a map of services to quota groups. If a group contains service sub-groups, this will map each service in those sub-groups to their sub-groups. If a root group contains a snap foo and service subgroup bar, with service svc1 in bar, then this will return a map with entry foo.svc1=bar
func (*Group) SliceFileName ¶
SliceFileName returns the name of the slice file that should be used for this quota group. This name will include all of the group's parents in the name. For example, a group named "bar" that is a child of the "foo" group will have a systemd slice name as "snap.foo-bar.slice". Note that the slice name may differ from the snapd friendly group name, mainly in the case that the group is a sub group.
func (*Group) UpdateQuotaLimits ¶
UpdateQuotaLimits updates all the quota limits set for the group to the new limits given. The limits will be validated against the group's parent group's limits, to verify that they fit. For instance, if the parent group has a memory limit of 1GB, and the new limit given here is 2GB, then the new limit will be rejected.
func (*Group) ValidateNestingAndSnaps ¶
ValidateNestingAndSnaps takes a group and verifies that it satisfies the following conditions:
- That if any parent is mixed (has both snaps and sub-groups), it must be the immediate parent group.
- If the group itself is mixed, that it has only one level of sub-grouping.
type GroupQuotaCPU ¶
type GroupQuotaCPU struct { // Count is the multiplier that is used in combination with the // percentage parameter to determine the final CPU resource constraint value. // The value is a positive integer or 0. A value of 0 will be treated as 1. Count int `json:"count,omitempty"` // Percentage is a positive integer between 0 and 100. It is used to together with // the Count parameter to determine the final CPU resource constraint value. The value // written to the systemd slice will be Count*Percentage. A value of 0 means that the limit // in Percentage and Count is ignored. Percentage int `json:"percentage,omitempty"` // CPUSet is a list of CPU core indices that are allowed to be used by the group. Each value // in the list refers to the CPU core number. If the list is empty, all CPU cores are allowed. CPUSet []int `json:"allowed-cpus,omitempty"` }
GroupQuotaCPU contains the different knobs that can be tuned for cpu quota limits. The allowed CPU percentage to use is split across two limits to better support a inituitive way of setting the limits.
type GroupQuotaJournal ¶
type GroupQuotaJournal struct { // Size is the maximum allowed size of the journal for the group. // If the size is set below current usage, systemd will automatically treat // the current usage of the journald namespace as the minimum limit and // render whatever set here ineffective. The maximum allowed size for // journald namespaces is 4GB. A value of 0 here means no limit is present. Size quantity.Size `json:"size,omitempty"` // RateEnabled tells us whether or not the values provided in RateCount and // RatePeriod should be written. RateEnabled bool `json:"rate-enabled,omitempty"` // RateCount is the number of messages allowed each RatePeriod. A zero value // in this field will disable the rate-limit. RateCount int `json:"rate-count,omitempty"` // RatePeriod is the time-period for when the rate resets. Each RatePeriod, // RateCount number of messages is allowed. A zero value in this field will // disable the rate-limit. RatePeriod time.Duration `json:"rate-period,omitempty"` }
GroupQuotaJournal contains the supported limits for journald. Any limit set here applies only to the quota group itself. Journal limits will not be inherited by the sub-groups as this behaviour is not supported by systemd.
type QuotaGroupSet ¶
type QuotaGroupSet struct {
// contains filtered or unexported fields
}
QuotaGroupSet is a set of quota groups, it is used for tracking a set of necessary quota groups using AddAllNecessaryGroups to add groups (and their implicit dependencies), and AllQuotaGroups to enumerate all the quota groups in the set.
func (*QuotaGroupSet) AddAllNecessaryGroups ¶
func (s *QuotaGroupSet) AddAllNecessaryGroups(grp *Group) error
AddAllNecessaryGroups adds all groups that are required for the specified group to be effective to the set. This means all sub-groups of this group, all parent groups of this group, and all sub-trees of any parent groups. This set is the set of quota groups that must exist for this quota group to be fully realized on a system, since all sub-branches of the full tree must exist since this group may share some quota resources with the other branches. There is no support for manipulating group trees while accumulating to a QuotaGroupSet using this.
func (*QuotaGroupSet) AllQuotaGroups ¶
func (s *QuotaGroupSet) AllQuotaGroups() []*Group
AllQuotaGroups returns a flattend list of all quota groups and necessary quota groups that have been added to the set.
type ResourceCPU ¶
type ResourceCPUSet ¶
type ResourceCPUSet struct {
CPUs []int `json:"cpus"`
}
type ResourceJournal ¶
type ResourceJournal struct { Size *ResourceJournalSize `json:"size,omitempty"` Rate *ResourceJournalRate `json:"rate,omitempty"` }
ResourceJournal represents the available journal quotas. It's structured a bit different compared to the other resources to support namespace only cases, where the existence of != nil ResourceJournal with empty values indicates that the namespace only is wanted.
type ResourceJournalRate ¶
type ResourceJournalSize ¶
type ResourceMemory ¶
type ResourceThreads ¶
type ResourceThreads struct {
Limit int `json:"limit"`
}
type Resources ¶
type Resources struct { Memory *ResourceMemory `json:"memory,omitempty"` CPU *ResourceCPU `json:"cpu,omitempty"` CPUSet *ResourceCPUSet `json:"cpu-set,omitempty"` Threads *ResourceThreads `json:"thread,omitempty"` Journal *ResourceJournal `json:"journal,omitempty"` }
Resources are built up of multiple quota limits. Each quota limit is a pointer value to indicate that their presence may be optional, and because we want to detect whenever someone changes a limit to '0' explicitly.
func (*Resources) Change ¶
Change updates the current quota limits with the new limits. Additional verification logic exists for this operation compared to when setting initial limits. Some changes of limits are not allowed.
func (*Resources) CheckFeatureRequirements ¶
CheckFeatureRequirements checks if the current system meets the requirements for the given resource request.
E.g. a CPUSet only only be set set on systems with cgroup v2.
func (*Resources) Validate ¶
Validate performs basic validation of the provided quota resources for a group. The restrictions imposed are that at least one limit should be set, and each of the imposed limits are not zero.
Note that before applying the quota to the system CheckFeatureRequirements() should be called.
func (*Resources) ValidateChange ¶
ValidateChange performs validation of new quota limits against the current limits. We do this validation each time a new group/subgroup is created or updated. This is to catch issues where we want to guard against lowering limits where not supported or to make sure that certain/all limits are not removed. We also require memory limits are above 640kB.
type ResourcesBuilder ¶
type ResourcesBuilder struct { MemoryLimit quantity.Size MemoryLimitSet bool CPUCount int CPUCountSet bool CPUPercentage int CPUPercentageSet bool CPUSet []int CPUSetSet bool ThreadLimit int ThreadLimitSet bool JournalNamespaceSet bool JournalSizeLimit quantity.Size JournalSizeLimitSet bool JournalRateCountLimit int JournalRatePeriodLimit time.Duration JournalRateSet bool }
func NewResourcesBuilder ¶
func NewResourcesBuilder() *ResourcesBuilder
func (*ResourcesBuilder) Build ¶
func (rb *ResourcesBuilder) Build() Resources
func (*ResourcesBuilder) WithCPUCount ¶
func (rb *ResourcesBuilder) WithCPUCount(count int) *ResourcesBuilder
func (*ResourcesBuilder) WithCPUPercentage ¶
func (rb *ResourcesBuilder) WithCPUPercentage(percentage int) *ResourcesBuilder
func (*ResourcesBuilder) WithCPUSet ¶
func (rb *ResourcesBuilder) WithCPUSet(cpuSet []int) *ResourcesBuilder
func (*ResourcesBuilder) WithJournalNamespace ¶
func (rb *ResourcesBuilder) WithJournalNamespace() *ResourcesBuilder
func (*ResourcesBuilder) WithJournalRate ¶
func (rb *ResourcesBuilder) WithJournalRate(count int, period time.Duration) *ResourcesBuilder
func (*ResourcesBuilder) WithJournalSize ¶
func (rb *ResourcesBuilder) WithJournalSize(limit quantity.Size) *ResourcesBuilder
func (*ResourcesBuilder) WithMemoryLimit ¶
func (rb *ResourcesBuilder) WithMemoryLimit(limit quantity.Size) *ResourcesBuilder
func (*ResourcesBuilder) WithThreadLimit ¶
func (rb *ResourcesBuilder) WithThreadLimit(limit int) *ResourcesBuilder