mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: update replaced k8s.io modules to v0.33.0
Signed-off-by: Niels de Vos <ndevos@ibm.com>
This commit is contained in:
committed by
mergify[bot]
parent
dd77e72800
commit
107407b44b
e2e
go.modgo.sumgeneric.gomodules.txt
vendor
github.com
NYTimes
gziphandler
containerd
containerd
api
errdefs
ttrpc
typeurl
coreos
go-semver
go-systemd
cyphar
filepath-securejoin
golang
protobuf
google
btree
cadvisor
grpc-ecosystem
go-grpc-prometheus
opencontainers
cgroups
CODEOWNERSCONTRIBUTING.mdGOVERNANCE.mdLICENSEMAINTAINERSMAINTAINERS_GUIDE.mdREADME.mdRELEASES.mdcgroups.goconfig_blkio_device.goconfig_hugepages.goconfig_ifprio_map.goconfig_linux.goconfig_rdma.goconfig_unsupported.gofile.go
devices
config
fs
blkio.gocpu.gocpuacct.gocpuset.godevices.goerror.gofreezer.gofs.gohugetlb.gomemory.goname.gonet_cls.gonet_prio.gopaths.goperf_event.gopids.gordma.go
fs2
fscommon
getallpids.gointernal
path
manager
stats.gosystemd
utils.gov1_utils.goimage-spec
LICENSE
specs-go
runc
go.etcd.io
etcd
api
v3
client
pkg
v3
LICENSE
fileutil
dir_unix.godir_windows.godoc.gofilereader.gofileutil.golock.golock_flock.golock_linux.golock_plan9.golock_solaris.golock_unix.golock_windows.gopreallocate.gopreallocate_darwin.gopreallocate_unix.gopurge.goread_dir.gosync.gosync_darwin.gosync_linux.go
logutil
systemd
tlsutil
transport
doc.gokeepalive_listener.gokeepalive_listener_openbsd.gokeepalive_listener_unix.golimit_listen.golistener.golistener_opts.golistener_tls.gosockopt.gosockopt_solaris.gosockopt_unix.gosockopt_windows.gotimeout_conn.gotimeout_dialer.gotimeout_listener.gotimeout_transport.gotls.gotransport.gounix_listener.go
types
v3
go.opentelemetry.io
otel
semconv
go.uber.org
multierr
.codecov.yml.gitignoreCHANGELOG.mdLICENSE.txtMakefileREADME.mderror.goerror_post_go120.goerror_pre_go120.go
zap
.codecov.yml.gitignore.golangci.yml.readme.tmplCHANGELOG.mdCODE_OF_CONDUCT.mdCONTRIBUTING.mdFAQ.mdLICENSEMakefileREADME.mdarray.go
buffer
checklicense.shconfig.godoc.goencoder.goerror.gofield.goflag.goglide.yamlglobal.gohttp_handler.gointernal
level.gologger.gooptions.gosink.gosugar.gotime.gowriter.gozapcore
buffered_write_syncer.goclock.goconsole_encoder.gocore.godoc.goencoder.goentry.goerror.gofield.gohook.goincrease_level.gojson_encoder.golazy_with.golevel.golevel_strings.gomarshaler.gomemory_encoder.goreflected_encoder.gosampler.gotee.gowrite_syncer.go
zapgrpc
golang.org
x
crypto
cryptobyte
hkdf
nacl
secretbox
salsa20
google.golang.org
genproto
googleapis
grpc
resolver
manual
gopkg.in
natefinch
k8s.io
api
admission
admissionregistration
apidiscovery
apiserverinternal
v1alpha1
apps
v1
v1beta1
v1beta2
authentication
authorization
autoscaling
v1
v2
v2beta1
v2beta2
batch
certificates
v1
v1alpha1
v1beta1
coordination
v1
v1alpha2
v1beta1
core
v1
discovery
v1
v1beta1
events
extensions
v1beta1
flowcontrol
imagepolicy
v1alpha1
networking
v1
doc.gogenerated.pb.gogenerated.protoregister.gotypes.gotypes_swagger_doc_generated.gowell_known_labels.gozz_generated.deepcopy.gozz_generated.prerelease-lifecycle.go
v1alpha1
v1beta1
node
policy
v1
v1beta1
rbac
resource
v1alpha3
doc.gogenerated.pb.gogenerated.protoregister.gotypes.gotypes_swagger_doc_generated.gozz_generated.deepcopy.gozz_generated.prerelease-lifecycle.go
v1beta1
devicetaint.godoc.gogenerated.pb.gogenerated.prototypes.gotypes_swagger_doc_generated.gozz_generated.deepcopy.go
v1beta2
scheduling
storage
v1
v1alpha1
v1beta1
storagemigration
v1alpha1
apiextensions-apiserver
pkg
apimachinery
pkg
api
safe
validate
apis
asn1
util
apiserver
pkg
admission
plugin
authorizer
namespace
lifecycle
policy
generic
accessor.gointerfaces.goplugin.gopolicy_dispatcher.gopolicy_matcher.gopolicy_source.gopolicy_test_context.go
internal
matching
mutating
validating
webhook
validating
apis
apidiscovery
apiserver
validation
audit
flowcontrol
bootstrap
audit
authentication
authenticator
authenticatorfactory
cel
group
request
anonymous
bearertoken
headerrequest
union
websocket
x509
token
authorization
authorizerfactory
cel
path
union
cel
openapi
endpoints
OWNERS
deprecation
discovery
filterlatency
filters
OWNERSaudit.goaudit_init.goauthentication.goauthn_audit.goauthorization.gocachecontrol.godoc.goimpersonation.gometrics.gomux_discovery_complete.gorequest_deadline.gorequest_received_time.gorequestinfo.gostorageversion.gotraces.gowarning.gowebhook_duration.go
groupversion.gohandlers
create.godelete.godoc.go
installer.gofieldmanager
finisher
get.gohelpers.gometrics
namer.gonegotiation
patch.goresponse.goresponsewriters
rest.gotrace_util.goupdate.gowatch.gowarning
registry
server
config.goconfig_selfclient.godeleted_kinds.godeprecated_insecure_serving.go
dynamiccertificates
cert_key.goclient_ca.goconfigmap_cafile_content.godynamic_cafile_content.godynamic_serving_content.godynamic_sni_content.gointerfaces.gonamed_certificates.gostatic_content.gotlsconfig.gounion_content.goutil.go
filters
OWNERScontent_type.gocors.godoc.gogoaway.gohsts.golongrunning.gomaxinflight.gopriority-and-fairness.gotimeout.gowaitgroup.gowatch_termination.gowith_retry_after.gowrap.go
genericapiserver.gohandler.gohealthz.gohooks.golifecycle_signals.gomux
options
OWNERSadmission.goapi_enablement.goaudit.goauthentication.goauthentication_dynamic_request_header.goauthorization.gocoreapi.godoc.goegress_selector.go
plugins.goencryptionconfig
etcd.gofeature.gorecommended.goserver_run_options.goserving.goserving_unix.goserving_windows.goserving_with_loopback.gotracing.goresourceconfig
routes
secure_serving.gosignal.gosignal_windows.gostorage
storage_readiness_hook.gostorage
cacher
cache_watcher.gocacher.gocaching_object.godelegator.go
delegator
lister_watcher.gometrics
progress
ready.gostore.gostore_btree.gotime_budget.goutil.gowatch_cache.gowatch_cache_interval.goerrors
etcd3
OWNERScompact.gocorrupt_obj_deleter.godecoder.goerrors.goevent.gohealthcheck.golatency_tracker.golease_manager.gologger.go
metrics
store.gowatcher.gofeature
storagebackend
value
OWNERS
encrypt
metrics.gotransformer.gostorageversion
util
apihelpers
dryrun
flowcontrol
OWNERSapf_context.goapf_controller.goapf_controller_debug.goapf_filter.goconc_alloc.go
debug
dropped_requests_tracker.gofairqueuing
format
formatting.gomax_seats.gometrics
request
config.golist_work_estimator.gomutating_work_estimator.goobject_count_tracker.goseat_seconds.gowidth.go
rule.gowatch_tracker.goflushwriter
peerproxy
metrics
shufflesharding
validation
plugin
pkg
audit
authenticator
token
webhook
authorizer
webhook
client-go
applyconfigurations
OWNERS
apps
v1
v1beta1
v1beta2
autoscaling
certificates
coordination
core
discovery
doc.goextensions
internal
networking
v1
resource
v1alpha3
basicdevice.gocounter.gocounterset.godevicecounterconsumption.godevicerequest.godevicerequestallocationresult.godevicesubrequest.godevicetaint.godevicetaintrule.godevicetaintrulespec.godevicetaintselector.godevicetoleration.goresourceslicespec.go
v1beta1
basicdevice.gocounter.gocounterset.godevicecounterconsumption.godevicerequest.godevicerequestallocationresult.godevicesubrequest.godevicetaint.godevicetoleration.goresourceslicespec.go
v1beta2
allocateddevicestatus.goallocationresult.goceldeviceselector.gocounter.gocounterset.godevice.godeviceallocationconfiguration.godeviceallocationresult.godeviceattribute.godevicecapacity.godeviceclaim.godeviceclaimconfiguration.godeviceclass.godeviceclassconfiguration.godeviceclassspec.godeviceconfiguration.godeviceconstraint.godevicecounterconsumption.godevicerequest.godevicerequestallocationresult.godeviceselector.godevicesubrequest.godevicetaint.godevicetoleration.goexactdevicerequest.gonetworkdevicedata.goopaquedeviceconfiguration.goresourceclaim.goresourceclaimconsumerreference.goresourceclaimspec.goresourceclaimstatus.goresourceclaimtemplate.goresourceclaimtemplatespec.goresourcepool.goresourceslice.goresourceslicespec.go
storage
utils.godiscovery
dynamic
features
gentype
informers
admissionregistration
v1
mutatingwebhookconfiguration.govalidatingadmissionpolicy.govalidatingadmissionpolicybinding.govalidatingwebhookconfiguration.go
v1alpha1
mutatingadmissionpolicy.gomutatingadmissionpolicybinding.govalidatingadmissionpolicy.govalidatingadmissionpolicybinding.go
v1beta1
apiserverinternal
v1alpha1
apps
v1
v1beta1
v1beta2
autoscaling
v1
v2
v2beta1
v2beta2
batch
certificates
v1
v1alpha1
v1beta1
coordination
core
v1
discovery
doc.goevents
extensions
flowcontrol
v1
v1beta1
v1beta2
v1beta3
networking
v1
v1alpha1
v1beta1
node
policy
rbac
v1
v1alpha1
v1beta1
resource
interface.go
v1alpha3
deviceclass.godevicetaintrule.gointerface.goresourceclaim.goresourceclaimtemplate.goresourceslice.go
v1beta1
v1beta2
scheduling
storage
v1
v1alpha1
v1beta1
storagemigration
v1alpha1
kubernetes
clientset.godoc.go
fake
import.goscheme
typed
admissionregistration
v1
v1alpha1
v1beta1
apiserverinternal
v1alpha1
apps
authentication
authorization
autoscaling
v1
v2
v2beta1
v2beta2
batch
certificates
v1
v1alpha1
v1beta1
coordination
v1
v1alpha2
v1beta1
core
discovery
events
extensions
v1beta1
flowcontrol
v1
v1beta1
v1beta2
v1beta3
networking
node
policy
rbac
resource
scheduling
storage
storagemigration
v1alpha1
listers
pkg
rest
scale
doc.go
scheme
tools
cache
controller.godelta_fifo.godoc.gofifo.golisters.golistwatch.gomutation_cache.gomutation_detector.goreflector.goshared_informer.gothe_real_fifo.go
clientcmd
events
portforward
record
remotecommand
watch
transport
util
cert
consistencydetector
flowcontrol
workqueue
cloud-provider
CONTRIBUTING.mdOWNERSREADME.mdSECURITY_CONTACTScloud.gocode-of-conduct.mddoc.go
app
config
config
install
register.gotypes.gov1alpha1
conversion.godefaults.godoc.goregister.gotypes.gozz_generated.conversion.gozz_generated.deepcopy.gozz_generated.defaults.go
zz_generated.deepcopy.gocontrollers
node
config
service
names
options
plugins.gocomponent-base
config
options
metrics
zpages
controller-manager
config
options
pkg
clientbuilder
features
register
leadermigration
cri-api
pkg
apis
cri-client
dynamic-resource-allocation
api
cel
internal
queue
resourceclaim
resourceslice
tracker
structured
kms
apis
pkg
kube-openapi
pkg
builder
builder3
common
restfuladapter
handler
schemamutation
kube-scheduler
kubelet
pkg
apis
stats
v1alpha1
kubernetes
pkg
api
apis
apps
autoscaling
batch
core
doc.go
helper
types.gov1
conversion.godefaults.godoc.gozz_generated.conversion.gozz_generated.defaults.gozz_generated.validations.go
validation
zz_generated.deepcopy.goextensions
networking
scheduling
capabilities
cluster
controller
credentialprovider
features
fieldpath
kubelet
apis
cadvisor
cm
OWNERScgroup_manager_linux.gocgroup_v1_manager_linux.gocgroup_v2_manager_linux.gocontainer_manager.gocontainer_manager_linux.gocontainer_manager_stub.gocontainer_manager_windows.go
containermap
cpumanager
devicemanager
doc.godra
fake_container_manager.gohelpers_linux.gomemorymanager
pod_container_manager_linux.goqos_container_manager_linux.gotopologymanager
util
config
container
events
lifecycle
metrics
pluginmanager
qos
status
types
util
winstats
probe
scheduler
apis
config
backend
eventhandlers.goframework
events.gointerface.golisters.go
parallelize
plugins
defaultpreemption
dynamicresources
feature
imagelocality
interpodaffinity
nodeaffinity
nodeports
noderesources
nodeunschedulable
nodevolumelimits
podtopologyspread
registry.gotainttoleration
volumebinding
preemption
runtime
types.gometrics
profile
schedule_one.goscheduler.gosecuritycontext
util
volume
test
e2e
framework
storage
testing-manifests
dra
storage-csi
external-snapshotter
groupsnapshot.storage.k8s.io_volumegroupsnapshotclasses.yamlgroupsnapshot.storage.k8s.io_volumegroupsnapshotcontents.yamlgroupsnapshot.storage.k8s.io_volumegroupsnapshots.yaml
volume-group-snapshots
gce-pd
hostpath
mock
utils
image
utils
515
e2e/vendor/github.com/opencontainers/cgroups/systemd/v2.go
generated
vendored
Normal file
515
e2e/vendor/github.com/opencontainers/cgroups/systemd/v2.go
generated
vendored
Normal file
@ -0,0 +1,515 @@
|
||||
package systemd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
||||
securejoin "github.com/cyphar/filepath-securejoin"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/opencontainers/cgroups"
|
||||
"github.com/opencontainers/cgroups/fs2"
|
||||
)
|
||||
|
||||
const (
|
||||
cpuIdleSupportedVersion = 252
|
||||
)
|
||||
|
||||
type UnifiedManager struct {
|
||||
mu sync.Mutex
|
||||
cgroups *cgroups.Cgroup
|
||||
// path is like "/sys/fs/cgroup/user.slice/user-1001.slice/session-1.scope"
|
||||
path string
|
||||
dbus *dbusConnManager
|
||||
fsMgr cgroups.Manager
|
||||
}
|
||||
|
||||
func NewUnifiedManager(config *cgroups.Cgroup, path string) (*UnifiedManager, error) {
|
||||
m := &UnifiedManager{
|
||||
cgroups: config,
|
||||
path: path,
|
||||
dbus: newDbusConnManager(config.Rootless),
|
||||
}
|
||||
if err := m.initPath(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fsMgr, err := fs2.NewManager(config, m.path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.fsMgr = fsMgr
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func shouldSetCPUIdle(cm *dbusConnManager, v string) bool {
|
||||
// The only valid values for cpu.idle are 0 and 1. As it is
|
||||
// not possible to directly set cpu.idle to 0 via systemd,
|
||||
// ignore 0. Ignore other values as we'll error out later
|
||||
// in Set() while calling fsMgr.Set().
|
||||
return v == "1" && systemdVersion(cm) >= cpuIdleSupportedVersion
|
||||
}
|
||||
|
||||
// unifiedResToSystemdProps tries to convert from Cgroup.Resources.Unified
|
||||
// key/value map (where key is cgroupfs file name) to systemd unit properties.
|
||||
// This is on a best-effort basis, so the properties that are not known
|
||||
// (to this function and/or systemd) are ignored (but logged with "debug"
|
||||
// log level).
|
||||
//
|
||||
// For the list of keys, see https://www.kernel.org/doc/Documentation/cgroup-v2.txt
|
||||
//
|
||||
// For the list of systemd unit properties, see systemd.resource-control(5).
|
||||
func unifiedResToSystemdProps(cm *dbusConnManager, res map[string]string) (props []systemdDbus.Property, _ error) {
|
||||
var err error
|
||||
|
||||
for k, v := range res {
|
||||
if strings.Contains(k, "/") {
|
||||
return nil, fmt.Errorf("unified resource %q must be a file name (no slashes)", k)
|
||||
}
|
||||
if strings.IndexByte(k, '.') <= 0 {
|
||||
return nil, fmt.Errorf("unified resource %q must be in the form CONTROLLER.PARAMETER", k)
|
||||
}
|
||||
// Kernel is quite forgiving to extra whitespace
|
||||
// around the value, and so should we.
|
||||
v = strings.TrimSpace(v)
|
||||
// Please keep cases in alphabetical order.
|
||||
switch k {
|
||||
case "cpu.idle":
|
||||
if shouldSetCPUIdle(cm, v) {
|
||||
// Setting CPUWeight to 0 tells systemd
|
||||
// to set cpu.idle to 1.
|
||||
props = append(props,
|
||||
newProp("CPUWeight", uint64(0)))
|
||||
}
|
||||
|
||||
case "cpu.max":
|
||||
// value: quota [period]
|
||||
quota := int64(0) // 0 means "unlimited" for addCpuQuota, if period is set
|
||||
period := defCPUQuotaPeriod
|
||||
sv := strings.Fields(v)
|
||||
if len(sv) < 1 || len(sv) > 2 {
|
||||
return nil, fmt.Errorf("unified resource %q value invalid: %q", k, v)
|
||||
}
|
||||
// quota
|
||||
if sv[0] != "max" {
|
||||
quota, err = strconv.ParseInt(sv[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q period value conversion error: %w", k, err)
|
||||
}
|
||||
}
|
||||
// period
|
||||
if len(sv) == 2 {
|
||||
period, err = strconv.ParseUint(sv[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q quota value conversion error: %w", k, err)
|
||||
}
|
||||
}
|
||||
addCpuQuota(cm, &props, quota, period)
|
||||
|
||||
case "cpu.weight":
|
||||
if shouldSetCPUIdle(cm, strings.TrimSpace(res["cpu.idle"])) {
|
||||
// Do not add duplicate CPUWeight property
|
||||
// (see case "cpu.idle" above).
|
||||
logrus.Warn("unable to apply both cpu.weight and cpu.idle to systemd, ignoring cpu.weight")
|
||||
continue
|
||||
}
|
||||
num, err := strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err)
|
||||
}
|
||||
props = append(props,
|
||||
newProp("CPUWeight", num))
|
||||
|
||||
case "cpuset.cpus", "cpuset.mems":
|
||||
bits, err := RangeToBits(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q=%q conversion error: %w", k, v, err)
|
||||
}
|
||||
m := map[string]string{
|
||||
"cpuset.cpus": "AllowedCPUs",
|
||||
"cpuset.mems": "AllowedMemoryNodes",
|
||||
}
|
||||
// systemd only supports these properties since v244
|
||||
sdVer := systemdVersion(cm)
|
||||
if sdVer >= 244 {
|
||||
props = append(props,
|
||||
newProp(m[k], bits))
|
||||
} else {
|
||||
logrus.Debugf("systemd v%d is too old to support %s"+
|
||||
" (setting will still be applied to cgroupfs)",
|
||||
sdVer, m[k])
|
||||
}
|
||||
|
||||
case "memory.high", "memory.low", "memory.min", "memory.max", "memory.swap.max":
|
||||
num := uint64(math.MaxUint64)
|
||||
if v != "max" {
|
||||
num, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err)
|
||||
}
|
||||
}
|
||||
m := map[string]string{
|
||||
"memory.high": "MemoryHigh",
|
||||
"memory.low": "MemoryLow",
|
||||
"memory.min": "MemoryMin",
|
||||
"memory.max": "MemoryMax",
|
||||
"memory.swap.max": "MemorySwapMax",
|
||||
}
|
||||
props = append(props,
|
||||
newProp(m[k], num))
|
||||
|
||||
case "pids.max":
|
||||
num := uint64(math.MaxUint64)
|
||||
if v != "max" {
|
||||
var err error
|
||||
num, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err)
|
||||
}
|
||||
}
|
||||
props = append(props,
|
||||
newProp("TasksMax", num))
|
||||
|
||||
case "memory.oom.group":
|
||||
// Setting this to 1 is roughly equivalent to OOMPolicy=kill
|
||||
// (as per systemd.service(5) and
|
||||
// https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html),
|
||||
// but it's not clear what to do if it is unset or set
|
||||
// to 0 in runc update, as there are two other possible
|
||||
// values for OOMPolicy (continue/stop).
|
||||
fallthrough
|
||||
|
||||
default:
|
||||
// Ignore the unknown resource here -- will still be
|
||||
// applied in Set which calls fs2.Set.
|
||||
logrus.Debugf("don't know how to convert unified resource %q=%q to systemd unit property; skipping (will still be applied to cgroupfs)", k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return props, nil
|
||||
}
|
||||
|
||||
func genV2ResourcesProperties(dirPath string, r *cgroups.Resources, cm *dbusConnManager) ([]systemdDbus.Property, error) {
|
||||
// We need this check before setting systemd properties, otherwise
|
||||
// the container is OOM-killed and the systemd unit is removed
|
||||
// before we get to fsMgr.Set().
|
||||
if err := fs2.CheckMemoryUsage(dirPath, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var properties []systemdDbus.Property
|
||||
|
||||
// NOTE: This is of questionable correctness because we insert our own
|
||||
// devices eBPF program later. Two programs with identical rules
|
||||
// aren't the end of the world, but it is a bit concerning. However
|
||||
// it's unclear if systemd removes all eBPF programs attached when
|
||||
// doing SetUnitProperties...
|
||||
deviceProperties, err := generateDeviceProperties(r, cm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
properties = append(properties, deviceProperties...)
|
||||
|
||||
if r.Memory != 0 {
|
||||
properties = append(properties,
|
||||
newProp("MemoryMax", uint64(r.Memory)))
|
||||
}
|
||||
if r.MemoryReservation != 0 {
|
||||
properties = append(properties,
|
||||
newProp("MemoryLow", uint64(r.MemoryReservation)))
|
||||
}
|
||||
|
||||
swap, err := cgroups.ConvertMemorySwapToCgroupV2Value(r.MemorySwap, r.Memory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if swap != 0 {
|
||||
properties = append(properties,
|
||||
newProp("MemorySwapMax", uint64(swap)))
|
||||
}
|
||||
|
||||
idleSet := false
|
||||
// The logic here is the same as in shouldSetCPUIdle.
|
||||
if r.CPUIdle != nil && *r.CPUIdle == 1 && systemdVersion(cm) >= cpuIdleSupportedVersion {
|
||||
properties = append(properties,
|
||||
newProp("CPUWeight", uint64(0)))
|
||||
idleSet = true
|
||||
}
|
||||
if r.CpuWeight != 0 {
|
||||
if idleSet {
|
||||
// Ignore CpuWeight if CPUIdle is already set.
|
||||
logrus.Warn("unable to apply both CPUWeight and CpuIdle to systemd, ignoring CPUWeight")
|
||||
} else {
|
||||
properties = append(properties,
|
||||
newProp("CPUWeight", r.CpuWeight))
|
||||
}
|
||||
}
|
||||
|
||||
addCpuQuota(cm, &properties, r.CpuQuota, r.CpuPeriod)
|
||||
|
||||
if r.PidsLimit > 0 || r.PidsLimit == -1 {
|
||||
properties = append(properties,
|
||||
newProp("TasksMax", uint64(r.PidsLimit)))
|
||||
}
|
||||
|
||||
err = addCpuset(cm, &properties, r.CpusetCpus, r.CpusetMems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ignore r.KernelMemory
|
||||
|
||||
// convert Resources.Unified map to systemd properties
|
||||
if r.Unified != nil {
|
||||
unifiedProps, err := unifiedResToSystemdProps(cm, r.Unified)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
properties = append(properties, unifiedProps...)
|
||||
}
|
||||
|
||||
return properties, nil
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Apply(pid int) error {
|
||||
var (
|
||||
c = m.cgroups
|
||||
unitName = getUnitName(c)
|
||||
properties []systemdDbus.Property
|
||||
)
|
||||
|
||||
slice := "system.slice"
|
||||
if m.cgroups.Rootless {
|
||||
slice = "user.slice"
|
||||
}
|
||||
if c.Parent != "" {
|
||||
slice = c.Parent
|
||||
}
|
||||
|
||||
properties = append(properties, systemdDbus.PropDescription("libcontainer container "+c.Name))
|
||||
|
||||
if strings.HasSuffix(unitName, ".slice") {
|
||||
// If we create a slice, the parent is defined via a Wants=.
|
||||
properties = append(properties, systemdDbus.PropWants(slice))
|
||||
} else {
|
||||
// Otherwise it's a scope, which we put into a Slice=.
|
||||
properties = append(properties, systemdDbus.PropSlice(slice))
|
||||
// Assume scopes always support delegation (supported since systemd v218).
|
||||
properties = append(properties, newProp("Delegate", true))
|
||||
}
|
||||
|
||||
// only add pid if its valid, -1 is used w/ general slice creation.
|
||||
if pid != -1 {
|
||||
properties = append(properties, newProp("PIDs", []uint32{uint32(pid)}))
|
||||
}
|
||||
|
||||
// Always enable accounting, this gets us the same behaviour as the fs implementation,
|
||||
// plus the kernel has some problems with joining the memory cgroup at a later time.
|
||||
properties = append(properties,
|
||||
newProp("MemoryAccounting", true),
|
||||
newProp("CPUAccounting", true),
|
||||
newProp("IOAccounting", true),
|
||||
newProp("TasksAccounting", true),
|
||||
)
|
||||
|
||||
// Assume DefaultDependencies= will always work (the check for it was previously broken.)
|
||||
properties = append(properties,
|
||||
newProp("DefaultDependencies", false))
|
||||
|
||||
properties = append(properties, c.SystemdProps...)
|
||||
|
||||
if err := startUnit(m.dbus, unitName, properties, pid == -1); err != nil {
|
||||
return fmt.Errorf("unable to start unit %q (properties %+v): %w", unitName, properties, err)
|
||||
}
|
||||
|
||||
if err := fs2.CreateCgroupPath(m.path, m.cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.OwnerUID != nil {
|
||||
// The directory itself must be chowned.
|
||||
err := os.Chown(m.path, *c.OwnerUID, -1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filesToChown, err := cgroupFilesToChown()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range filesToChown {
|
||||
err := os.Chown(m.path+"/"+v, *c.OwnerUID, -1)
|
||||
// Some files might not be present.
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// The kernel exposes a list of files that should be chowned to the delegate
|
||||
// uid in /sys/kernel/cgroup/delegate. If the file is not present
|
||||
// (Linux < 4.15), use the initial values mentioned in cgroups(7).
|
||||
func cgroupFilesToChown() ([]string, error) {
|
||||
const cgroupDelegateFile = "/sys/kernel/cgroup/delegate"
|
||||
|
||||
f, err := os.Open(cgroupDelegateFile)
|
||||
if err != nil {
|
||||
return []string{"cgroup.procs", "cgroup.subtree_control", "cgroup.threads"}, nil
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
filesToChown := []string{}
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
filesToChown = append(filesToChown, scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %w", cgroupDelegateFile, err)
|
||||
}
|
||||
|
||||
return filesToChown, nil
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Destroy() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
unitName := getUnitName(m.cgroups)
|
||||
if err := stopUnit(m.dbus, unitName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// systemd 239 do not remove sub-cgroups.
|
||||
err := m.fsMgr.Destroy()
|
||||
// fsMgr.Destroy has handled ErrNotExist
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Path(_ string) string {
|
||||
return m.path
|
||||
}
|
||||
|
||||
// getSliceFull value is used in initPath.
|
||||
// The value is incompatible with systemdDbus.PropSlice.
|
||||
func (m *UnifiedManager) getSliceFull() (string, error) {
|
||||
c := m.cgroups
|
||||
slice := "system.slice"
|
||||
if c.Rootless {
|
||||
slice = "user.slice"
|
||||
}
|
||||
if c.Parent != "" {
|
||||
var err error
|
||||
slice, err = ExpandSlice(c.Parent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if c.Rootless {
|
||||
// managerCG is typically "/user.slice/user-${uid}.slice/user@${uid}.service".
|
||||
managerCG, err := getManagerProperty(m.dbus, "ControlGroup")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
slice = filepath.Join(managerCG, slice)
|
||||
}
|
||||
|
||||
// an example of the final slice in rootless: "/user.slice/user-1001.slice/user@1001.service/user.slice"
|
||||
// NOTE: systemdDbus.PropSlice requires the "/user.slice/user-1001.slice/user@1001.service/" prefix NOT to be specified.
|
||||
return slice, nil
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) initPath() error {
|
||||
if m.path != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
sliceFull, err := m.getSliceFull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c := m.cgroups
|
||||
path := filepath.Join(sliceFull, getUnitName(c))
|
||||
path, err = securejoin.SecureJoin(fs2.UnifiedMountpoint, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// an example of the final path in rootless:
|
||||
// "/sys/fs/cgroup/user.slice/user-1001.slice/user@1001.service/user.slice/libpod-132ff0d72245e6f13a3bbc6cdc5376886897b60ac59eaa8dea1df7ab959cbf1c.scope"
|
||||
m.path = path
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Freeze(state cgroups.FreezerState) error {
|
||||
return m.fsMgr.Freeze(state)
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) GetPids() ([]int, error) {
|
||||
return cgroups.GetPids(m.path)
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) GetAllPids() ([]int, error) {
|
||||
return cgroups.GetAllPids(m.path)
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) GetStats() (*cgroups.Stats, error) {
|
||||
return m.fsMgr.GetStats()
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Set(r *cgroups.Resources) error {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
properties, err := genV2ResourcesProperties(m.fsMgr.Path(""), r, m.dbus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := setUnitProperties(m.dbus, getUnitName(m.cgroups), properties...); err != nil {
|
||||
return fmt.Errorf("unable to set unit properties: %w", err)
|
||||
}
|
||||
|
||||
return m.fsMgr.Set(r)
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) GetPaths() map[string]string {
|
||||
paths := make(map[string]string, 1)
|
||||
paths[""] = m.path
|
||||
return paths
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) GetCgroups() (*cgroups.Cgroup, error) {
|
||||
return m.cgroups, nil
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) GetFreezerState() (cgroups.FreezerState, error) {
|
||||
return m.fsMgr.GetFreezerState()
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Exists() bool {
|
||||
return cgroups.PathExists(m.path)
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) OOMKillCount() (uint64, error) {
|
||||
return m.fsMgr.OOMKillCount()
|
||||
}
|
Reference in New Issue
Block a user