Commit Graph

659 Commits

Author SHA1 Message Date
Kir Kolyshkin 2d1645d2e5 libct/cg/fscommon: drop go 1.13 compatibility
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-27 01:41:47 -07:00
Kir Kolyshkin a71102624d libct/cg/sd: add TestPodSkipDevicesUpdate
TestPodSkipDevicesUpdate checks that updating a pod having SkipDevices: true
does not result in spurious "permission denied" errors in a container
running under the pod. The test is somewhat similar in nature to the
@test "update devices [minimal transition rules]" in tests/integration,
but uses a pod.

This tests the validity of freezeBeforeSet in v1.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-15 00:07:22 -07:00
Kir Kolyshkin 52dd96db6b libct/cg/sd: TestFreezePodCgroup: rm explicit freeze
This was initially added by commit 3e5c199708 because Set (with
r.Freezer = Frozen) was not able to freeze a container.

Now (see a few previous commits) Set can do the freeze, so the explicit
Freeze is no longer needed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-15 00:07:19 -07:00
Kir Kolyshkin f2db87986c libct/cg/sd/v1: Set: avoid unnecessary freeze/thaw
Introduce freezeBeforeSet, which contains the logic of figuring out
whether we need to freeze/thaw around setting systemd unit properties.

In particular, if SkipDevices is set, and the current unit properties
allow all devices, there is no need to freeze and thaw, as systemd
won't write any device rules in this case.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-15 00:07:10 -07:00
Kir Kolyshkin 67cfd3d400 libct/cg/sd/v1: Set: don't overwrite r.Freezer
m.Freeze method changes m.cgroups.Resources.Freezer field, which should
not be done while we're temporarily freezing the cgroup in Set. If this
field is changed, and r == m.cgroups.Resources (as it often happens),
this results in inability to freeze the container using Set().

To fix, add and use a method which does not change r.Freezer field.

A test case for the bug will be added separately.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-14 23:42:35 -07:00
Aleksa Sarai 57e3c54182 cgroupv2: ebpf: ignore inaccessible existing programs
This is necessary in order for runc to be able to configure device
cgroups with --systemd-cgroup on distributions that have very strict
SELinux policies such as openSUSE MicroOS[1].

The core issue here is that systemd is adding its own BPF policy that
has an SELinux label such that runc cannot interact with it. In order to
work around this, we can just ignore the policy -- in theory this
behaviour is not correct but given that the most obvious case
(--systemd-cgroup) will still handle updates correctly, this logic is
reasonable.

[1]: https://bugzilla.suse.com/show_bug.cgi?id=1182428

Fixes: d0f2c25f52 ("cgroup2: devices: replace all existing filters when attaching")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-07-14 11:17:19 +10:00
Aleksa Sarai 2c01cec8ac merge branch 'pr-3067'
Odin Ugedal (2):
  libct/cg/sd: Don't freeze cgroup on cgroup v2 Set
  Update device update tests

LGTMs: kolyshkin mrunalp cyphar
Closes #3067
2021-07-13 12:59:29 +10:00
Mrunal Patel dc3236f957 Merge pull request #3070 from kolyshkin/unconvert
ci: enable unconvert linter, fix its warnings
2021-07-12 16:47:14 -04:00
Odin Ugedal 3e5c199708 libct/cg/sd: Add freezer tests
This test the issues fixed by the two preceding commits.

Co-Authored-By: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Odin Ugedal <odin@uged.al>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-08 19:32:39 -07:00
Odin Ugedal 294c4866ea libct/cg/fs/freezer.GetState: report current cgroup state
If a control group is frozen, all its descendants will report FROZEN
in freezer.state cgroup file.

OTOH cgroup v2 cgroup.freeze is not reporting the cgroup as frozen
unless it is frozen directly (i.e. not via an ancestor).

Fix the discrepancy between v1 and v2 drivers behavior by
looking into freezer.self_freezing cgroup file, which, according
to kernel documentation, will show 1 iff the cgroup was frozen directly.

Co-authored-by: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Odin Ugedal <odin@uged.al>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-08 19:32:08 -07:00
Odin Ugedal f33be7cc98 libct/cg/sd: Don't freeze cgroup on cgroup v2 Set
Since device updates in cgroup v2 are atomic for systemd, there is no
need to freeze the processes before running the updates.

Signed-off-by: Odin Ugedal <odin@uged.al>
2021-07-07 22:44:08 +02:00
Kir Kolyshkin be1d5f83c0 ci: enable unconvert linter, fix its warnings
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-07-07 10:42:48 -07:00
Kir Kolyshkin a7cfb23b88 *: stop using pkg/errors
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin b60e2edf75 libct/cg: stop using pkg/errors
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin a6cc36a836 libct/cg/ebpf: stop using pkg/errors
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin f137aaa2c8 libct/cg/devices: stop using pkg/errors
Use Go native errors wrapping.

Introduce wrapErr helper to minimise the patch size.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin 56e478046a *: ignore errorlint warnings about unix.* errors
Errors from unix.* are always bare and thus can be used directly.

Add //nolint:errorlint annotation to ignore errors such as these:

libcontainer/system/xattrs_linux.go:18:7: comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error (errorlint)
	case errno == unix.ERANGE:
	     ^
libcontainer/container_linux.go:1259:9: comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error (errorlint)
					if e != unix.EINVAL {
					   ^
libcontainer/rootfs_linux.go:919:7: comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error (errorlint)
			if err != unix.EINVAL && err != unix.EPERM {
			   ^
libcontainer/rootfs_linux.go:1002:4: switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors (errorlint)
			switch err {
			^

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin f6a0899b7f *: use errors.As and errors.Is
Do this for all errors except one from unix.*.

This fixes a bunch of errorlint warnings, like these

libcontainer/generic_error.go:25:15: type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors (errorlint)
	if le, ok := err.(Error); ok {
	             ^
libcontainer/factory_linux_test.go:145:14: type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors (errorlint)
	lerr, ok := err.(Error)
	            ^
libcontainer/state_linux_test.go:28:11: type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors (errorlint)
	_, ok := err.(*stateTransitionError)
	         ^
libcontainer/seccomp/patchbpf/enosys_linux.go:88:4: switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors (errorlint)
			switch err {
			^

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin adbac31d88 libct: fix errorlint warning about strconv.NumError
This one is tough as errorlint insists on using errors.Is, and the
latter is known to not work for Go 1.13 which we still support.

So, add a nolint annotation to suppress the warning, and a TODO to
address it later.

For intelrdt, we can do the same, but it is easier to reuse the very
same function from fscommon (note we can't use fscommon for other stuff
as it expects cgroupfs).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin 7be93a66b9 *: fmt.Errorf: use %w when appropriate
This should result in no change when the error is printed, but make the
errors returned unwrappable, meaning errors.As and errors.Is will work.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 16:09:47 -07:00
Kir Kolyshkin 825335b2b7 libct/cg/fs2: fix/unify parsing errors
This builds on top of recently introduced fscommon.ParseError.

Errors returned from parsers (mostly ones used by GetStats()) are all
different, and many are incomplete. For example, in many cases errors
from strconv.ParseUint are returned as is, meaning there is no context
telling which file we were reading. Similarly, errors from
fscommon.ParseKeyValue should be wrapped to add more context.
Same is true for scanner.Err().

OTOH, errors from fscommon.GetCgroup* do have enough context and there
is no need to wrap them.

Fix all the above.

While at it, add missing scanner.Err() checks.

[v2: use parseError, not ParseError]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 12:00:54 -07:00
Kir Kolyshkin 5a186d390f libct/cg/fs: fix/unify parsing errors
This builds on top of recently introduced fscommon.ParseError.

Errors returned from parsers (mostly ones used by GetStats()) are all
different, and many are incomplete. For example, in many cases errors
from strconv.ParseUint are returned as is, meaning there is no context
telling which file we were reading. Similarly, errors from
fscommon.ParseKeyValue should be wrapped to add more context.
Same is true for scanner.Err().

One special case that repeats a few times is "malformed line: xxx".
Add and use a helper for that to simplify things.

OTOH, errors from fscommon.GetCgroup* do have enough context and there
is no need to wrap them.

Fix all the above.

While at it, add a missing scanner.Err() check.

[v2: use parseError not ParseError]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:59:54 -07:00
Kir Kolyshkin f813174d5e libct/cg/fscommon: introduce and use ParseError
1. Introduce ParseError type as a way to unify error messages related to
   file parsing. Use it from GetCgroup* functions.

2. Do not discard the error from strconv.Parse{Int,Uint} -- it contains
   the value being parsed, and the details about the error.

2. As the error above already contains the value, drop it from format.

[v2: use path.Join in Error]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:52:26 -07:00
Kir Kolyshkin adcd3b4451 libct/cg/fs[2]: simplify getting pid stats
1. Do not wrap errors returned from fscommon.GetCgroupParamUint -- those
   errors already have enough context.

2. Instead of parsing "max" ourselves, use GetCgroupParamUint which does
   it, and then convert MaxUint64 to 0 (we do it historically since
   commit 087b953dc5, and while using MaxUint64 as is seems fine,
   there may be some existing users who rely on the old behavior).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:44:31 -07:00
Kir Kolyshkin 4e33094277 libct/cg/fs/stats_util_test: fix errors
1. No \n needed in t.Errorf/t.Fatalf.

2. Some cosmetic changes.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:44:12 -07:00
Kir Kolyshkin 3fee59f9da libct/cg/fs/*_test: simplify errors
The error from fscommon.GetCgroup* already contains the file name and so
on, so there's no need to wrap it.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:43:24 -07:00
Kir Kolyshkin fdf4e90e89 libct/cg/fscommon.ParseKeyValue: no need to wrap err
The error returned from strconv.ParseUint is already pretty descriptive,
something like:

	strconv.ParseUint: parsing "000d": invalid syntax

So, there is no need to add more context to it.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:42:59 -07:00
Kir Kolyshkin 627a06ad92 Replace fmt.Errorf w/o %-style to errors.New
Using fmt.Errorf for errors that do not have %-style formatting
directives is an overkill. Switch to errors.New.

Found by

	git grep fmt.Errorf | grep -v ^vendor | grep -v '%'

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:42:07 -07:00
Kir Kolyshkin 242b3283fd libct/cg/fscommon: rm unused var
It is not used since commit 494f900e91

Fixes: 494f900e91
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-22 11:42:00 -07:00
Kir Kolyshkin 1036f3f995 libct/cg/fs2: set per-device io weight if available
Per-device weight is supported since kernel v5.4 (kernel commit
795fe54c2a8), so let's set those if supplied.

[v2: implement a more relaxed check in bfqDeviceWeightSupported]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-16 04:51:19 -07:00
Kir Kolyshkin 30d83d4d2f libct/cg/fs/blkio: do not set weight == 0
For per-device weight, you can set weight and/or leaf weight.
The problem is, with the recent fix to use BFQ on cgroup v1,
if per-device weights are set, the code tries to set device
weight to blkio.bfq.weight, and the leaf weight to
blkio.leaf_weight_device. The latter file does not exist on
kernels v5.0, meaning one can not set any per-device weights
at all.

The fix is to only set weights if they are non-zero (i.e. set).

The test case will come in a following commit.

Fixes: 6339d8a0dd
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-14 12:52:30 -07:00
Kir Kolyshkin d7fc302860 libct/cg/fs*: mark {Open,Read,Write}File as deprecated
... and switch to using the ones from cgroups.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-13 17:17:48 -07:00
Kir Kolyshkin 8f1b4d4a6f libct/cg: mv fscommon.{Open,Read,Write}File to cgroups
This is a better place as cgroups itself is using these.
Should help with moving more stuff common in between fs and fs2 to
fscommon.

Looks big, but this is just moving the code around:

 fscommon/{fscommon,open}.go -> cgroups/file.go
 fscommon/fscommon_test.go   -> cgroups/file_test.go

and fixes for TestMode moved to a different package.

There's no functional change.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-13 12:38:21 -07:00
Mrunal Patel 93a01cd4d0 Merge pull request #3009 from AkihiroSuda/update-ebpf-wrap
update cilium/ebpf to fix haveBpfProgReplace() check
2021-06-11 15:38:01 -04:00
Kir Kolyshkin 0ca4cdad35 Merge pull request #3010 from askervin/5D6_blkio_bfq_weight
libcontainer/cgroups/fs/blkio: support BFQ weight[_device]
2021-06-11 11:30:05 -07:00
Akihiro Suda 46940ed80c update cilium/ebpf to fix haveBpfProgReplace() check
The `errors.Is(err, unix.EINVAL)` check in `haveBpfProgReplace()` was
broken because the `cilium/ebpf` library did not "wrap" errors.
https://github.com/cilium/ebpf/blob/v0.6.0/link/program.go#L72

So the eBPF support of runc was broken for kernel prior to 5.6.

This commit bumps up cilium/ebpf to contain cilium/ebpf PR 320.

Fix opencontainers/runc issue 3008

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2021-06-12 02:12:25 +09:00
Antti Kervinen 6339d8a0dd libcontainer/cgroups/fs/blkio: support BFQ weight[_device]
- Update the blkio cgroup to support the BFQ I/O Scheduler, that has
  replaced CFQ in the Linux kernel.
- BFQ is controlled through blkio.bfq.weight[_device] instead of
  CFQ's blkio.weight[_device] in cgroups v1.
- BFQ does not support blkio.leaf_weight[_device], so that behavior
  remains untouched.
- Do not change behavior on legacy CFQ systems.
- Enable using blkio weights on BFQ systems.

Signed-off-by: Antti Kervinen <antti.kervinen@intel.com>
2021-06-11 11:11:06 +03:00
Kir Kolyshkin bd8e070109 libct/cg/sd: fix "SkipDevices" handling
1. The meaning of SkipDevices is what it is -- do not set any
   device-related options.

2. Reverts the part of commit 108ee85b82 which skipped the freeze
   when the SkipDevices is set. Apparently, the freeze is needed on
   update even if no Device* properties are being set.

3. Add "runc update" to "runc run [device cgroup deny]" test.

Fixes: 752e7a8249
Fixes: 108ee85b82
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-10 12:01:21 -07:00
Aleksa Sarai dcdf6b631d merge branch 'pr-3006'
Kir Kolyshkin (1):
  libct/cg/sd/dbus: fix NewDbusConnManager

LGTMs: AkihiroSuda cyphar
Closes #3006
2021-06-09 20:09:00 +10:00
Kir Kolyshkin 9573e4b68e libct/cg/fs: don't forget to close a file
Fixes: 7fe0a98e79
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-08 21:04:41 -07:00
Aleksa Sarai 9ebc573a38 cgroupv2: ebpf: debug info when detaching programs in fallback mode
It seems that we are triggering the mutli-attach fallback in the fedora
CI, but we don't have enough debugging information to really know what's
going on, so add some. Unfortunately the amount of information we have
available with eBPF programs in general is fairly limited (we can't get
their bytecode for instance).

We also demote the "more than one filter" warning to an info message
because it happens very often under the systemd cgroup driver (likely
when systemd configures the cgroup it isn't deleting our old program, so
when our apply code runs after the systemd one there are two running
programs).

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-06-08 13:23:59 +10:00
Aleksa Sarai a3ca7b47fc cgroupv2: ebpf: check for BPF_F_REPLACE support and degrade gracefully
It turns out that the cilium eBPF library doesn't degrade gracefully if
BPF_F_REPLACE is not supported, so we need to work around it by treating
that case as we treat the more-than-one program case.

It also turns out that we weren't passing BPF_F_REPLACE explicitly, but
this is required by the cilium library (causing EINVALs).

Fixes: d0f2c25f52 ("cgroup2: devices: replace all existing filters when attaching")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-06-08 13:23:56 +10:00
Kir Kolyshkin d06bda60c5 libct/cg/sd/dbus: fix NewDbusConnManager
Noticed that the check of trying to use both rootful and rootless
in NewDbusConnManager never worked, as we never set dbusInited to true.

Do that. While at it, protect this with the mutex (against the
case of two goroutines simultaneously calling NewDbusConnManager).
This is a rare call, so taking read-only then read-write mutex does not
make sense.

Fixes: c7f847ed3a

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-07 12:23:01 -07:00
Kir Kolyshkin b2d28c5df2 libct/cg/sd: fix dbus error handling
This fixes isDbusError function, introduced by commit bacfc2c. Due to a
type error it was not working at all.

This also fixes the whole "retry on dbus disconnect" logic.

This also fixes a regression in startUnit (and cgroupManager.Apply()),
which should never return "unit already exists" error but it did.

Fixes: bacfc2c
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-03 12:40:41 -07:00
Aleksa Sarai 13acae7376 merge branch 'pr-2992'
Kir Kolyshkin (3):
  libct/cg/fs/stats_util_test: use t.Helper
  libct/cg/fs/memory_test: fix formatting
  libct/int/testPids: logging nits

LGTMs: AkihiroSuda cyphar
Closes #2992
2021-06-03 21:05:42 +10:00
Aleksa Sarai a77d031114 merge branch 'pr-2991'
Kir Kolyshkin (2):
  vendor: willf/bitset@v1.1.11 -> bits-and-blooms/bitset@v1.2.0
  Bump selinux to v1.8.2

LGTMs: AkihiroSuda cyphar
Closes #2991
2021-06-03 21:03:55 +10:00
Kir Kolyshkin c3831d646d libct/cg/fs/stats_util_test: use t.Helper
These functions are called from multiple places,
and if t.Helper() is not used, the context is not clear.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-02 17:43:02 -07:00
Kir Kolyshkin 9eb0371bab libct/cg/fs/memory_test: fix formatting
Make it more readable.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-02 17:42:19 -07:00
Kir Kolyshkin a5bd78ef52 vendor: willf/bitset@v1.1.11 -> bits-and-blooms/bitset@v1.2.0
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-06-02 16:28:38 -07:00
Sebastiaan van Stijn 1fb56f9f1f libcontainer/cgroups/devices: if block ends with a return statement
libcontainer/cgroups/devices/devices_emulator.go:261:9: `if` block ends with a `return` statement, so drop this `else` and outdent its block (golint)
    	} else {
    	       ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-06-02 17:46:32 +02:00