Kir Kolyshkin (6):
runc --debug: shorter caller info
libct/logs: do not show caller in nsexec logs
libct/logs: parse log level implicitly
libct/logs: test: make more robust
libct/logs: remove ConfigureLogging
init.go, main.go: don't use logs.ConfigureLogging
LGTMs: thaJeztah cyphar
Kir Kolyshkin (3):
libct/system: add I and P process states
libct/system.Stat: fix/improve/speedup
libct/system/proc_test: fix, improve, add benchmark
LGTMs: thaJeztah cyphar
Extend the SetupSeccomp tests by adding the following cases:
- Test nil config
- Test empty config
- Test bad action and architecture
- Test all possible actions
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
This commit implements support for the SCMP_ACT_NOTIFY action. It
requires libseccomp-2.5.0 to work but runc still works with older
libseccomp if the seccomp policy does not use the SCMP_ACT_NOTIFY
action.
A new synchronization step between runc[INIT] and runc run is introduced
to pass the seccomp fd. runc run fetches the seccomp fd with pidfd_get
from the runc[INIT] process and sends it to the seccomp agent using
SCM_RIGHTS.
As suggested by @kolyshkin, we also make writeSync() a wrapper of
writeSyncWithFd() and wrap the error there. To avoid pointless errors,
we made some existing code paths just return the error instead of
re-wrapping it. If we don't do it, error will look like:
writing syncT <act>: writing syncT: <err>
By adjusting the code path, now they just look like this
writing syncT <act>: <err>
Signed-off-by: Alban Crequy <alban@kinvolk.io>
Signed-off-by: Rodrigo Campos <rodrigo@kinvolk.io>
Co-authored-by: Rodrigo Campos <rodrigo@kinvolk.io>
SendFds is a helper function for sending a set of file descriptors and a message
over a unix domain socket.
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
if function returns error before WriteJSON defer, error will not be
printed out, so move this defer as early as possible and use logrus to
print out error if returns before it.
Signed-off-by: xiadanni <xiadanni1@huawei.com>
Commit 9f3d7534ea enabled logrus to show information about log
caller, if --debug is set. It is helpful in many scenarios, but does
not work very well when we are debugging runc init, for example:
# runc --debug run -d xx4557
DEBU[0000]libcontainer/logs/logs.go:45 github.com/opencontainers/runc/libcontainer/logs.processEntry() nsexec[279687]: logging set up
DEBU[0000]libcontainer/logs/logs.go:45 github.com/opencontainers/runc/libcontainer/logs.processEntry() nsexec[279687]: logging set up
DEBU[0000]libcontainer/logs/logs.go:45 github.com/opencontainers/runc/libcontainer/logs.processEntry() nsexec[279687]: => nsexec container setup
DEBU[0000]libcontainer/logs/logs.go:45 github.com/opencontainers/runc/libcontainer/logs.processEntry() nsexec[279687]: update /proc/self/oom_score_adj to '30'
As we're merely forwarding the logs here, printing out filename:line and
function is useless and clutters the logs a log.
To fix, create and use a copy of the standard logger with caller info
turned off.
With this in place, nsexec logs are sane again:
# runc --debug --log-format=text run -d xe34
DEBU[0000] nsexec[293595]: logging set up
DEBU[0000] nsexec[293595]: logging set up
DEBU[0000] nsexec[293595]: => nsexec container setup
DEBU[0000] nsexec[293595]: update /proc/self/oom_score_adj to '30'
This patch also changes Logf to Log in processEntry, as this is what it
should be.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
There's no need to call logrus.ParseLevel as logrus.Level already
implements encoding.TextUnmarshaler interface.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
When playing with the log forwarder, I broke it, but all the units tests
were still passing. This happened because test cases were merely looking
for a word (like "kitten") in the log output, which also happened to be
there in case of an error (as a part of an error message produced by log
forwarder).
Make the test a bit more robust by
- looking for a complete log message, not just part of it;
- also checking that log file does NOT contain errors.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
- add missing colons before error message;
- unify error messages after cmd.Start and cmd.Wait, so that they show
context and the error itself.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Instead of reading a single message, do read all the logs from the init,
and use DisallowUnknownFields for stricter checking.
While at it, use reapChildren to reap zombies (and add an extra check).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The test was not working since at least commit 64bb59f592
renamed pid to stage2_pid (or maybe even earlier), so the pid
was never received (i.e. pid.Pid was 0).
The problem was not caught because os.FindProcess never return an error
on Unix.
Factor out and fix pid decode function:
- use DisallowUnknownInput to get error if JSON will be changed;
- check pids to make sure they are valid
- and use unix.Wait4 to reap zombies.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Make sure we close all file descriptors at the end of the test.
2. Make sure we close child fds after the start.
3. Use newPipe for logs as well, for simplicity and uniformity.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Go 1.17 introduce this new (and better) way to specify build tags.
For more info, see https://golang.org/design/draft-gobuild.
As a way to seamlessly switch from old to new build tags, gofmt (and
gopls) from go 1.17 adds the new tags along with the old ones.
Later, when go < 1.17 is no longer supported, the old build tags
can be removed.
Now, as I started to use latest gopls (v0.7.1), it adds these tags
while I edit. Rather than to randomly add new build tags, I guess
it is better to do it once for all files.
Mind that previous commits removed some tags that were useless,
so this one only touches packages that can at least be built
on non-linux.
Brought to you by
go1.17 fmt ./...
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
These are not needed as these packages (libcontainer/cgroups,
libcontainer/cgroups/fs, and libcontainer/cgroups/systemd) can
not be built under non-linux anyway (for various reasons).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Only some libcontainer packages can be built on non-linux platforms
(not that it make sense, but at least go build succeeds). Let's call
these "good" packages.
For all other packages (i.e. ones that fail to build with GOOS other
than linux), it does not make sense to have linux build tag (as they
are broken already, and thus are not and can not be used on anything
other than Linux).
Remove linux build tag for all non-"good" packages.
This was mostly done by the following script, with just a few manual
fixes on top.
function list_good_pkgs() {
for pkg in $(find . -type d -print); do
GOOS=freebsd go build $pkg 2>/dev/null \
&& GOOS=solaris go build $pkg 2>/dev/null \
&& echo $pkg
done | sed -e 's|^./||' | tr '\n' '|' | sed -e 's/|$//'
}
function remove_tag() {
sed -i -e '\|^// +build linux$|d' $1
go fmt $1
}
SKIP="^("$(list_good_pkgs)")"
for f in $(git ls-files . | grep .go$); do
if echo $f | grep -qE "$SKIP"; then
echo skip $f
continue
fi
echo proc $f
remove_tag $f
done
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
For files that end with _linux.go or _linux_test.go, there is no need to
specify linux build tag, as it is assumed from the file name.
In addition, rename libcontainer/notify_linux_v2.go -> libcontainer/notify_v2_linux.go
for the file name to make sense.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
As reported in issue 3084, sometimes setting CPU quota period fails
when a new period is lower and a parent cgroup has CPU quota limit set.
This happens as in cgroup v1 the quota and the period can not be set
together (this is fixed in v2), and since the period is being set first,
new_limit = old_quota/new_period may be higher than the parent cgroup
limit.
The fix is to retry setting the period after the quota, to cover all
possible scenarios.
Add a test case to cover a regression caused by an earlier version of
this patch (ignoring a failure of setting invalid period when quota is
not set).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This reverts commit 814f3ae1d9. This
changed the on-disk state which breaks runc when it has to operate on
containers started with an older runc version. Working around this is
far more complicated than just reverting it.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
ConfigError was added by commit e918d02139, while removing runc own
error system, to preserve a way for a libcontainer user to distinguish
between a configuration error and something else.
The way ConfigError is implemented requires a different type of check
(compared to all other errors defined by error.go). An attempt was made
to rectify this, but the resulting code became even more complicated.
As no one is using this functionality (of differentiating a "bad config"
type of error from other errors), let's just drop the ConfigError type.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
All the errors returned from Validate should tell about a configuration
error. Some were lacking a context, so add it.
While at it, fix abusing fmt.Errorf and logrus.Warnf where the argument
do not contain %-style formatting.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Looking into data generated by setting
GODEBUG="inittrace=1"
I have noticed this line:
init github.com/opencontainers/runc/libcontainer/cgroups/devices @1.2 ms, 0.020 ms clock, 10512 bytes, 133 allocs
This is the leader for both bytes and allocs among the packages from
this repo, and all of it is caused by a single regex:
> var devicesListRegexp = regexp.MustCompile(`^([abc])\s+(\d+|\*):(\d+|\*)\s+([rwm]+)$`)
It seems that the same parsing can be done without relying on
a regular expression, no decrease in readability, and 2x faster
(according to the benchmark added), and also makes runc start
slightly faster and leaner.
Before:
BenchmarkParseLine-4 176240 6768 ns/op 6576 B/op 64 allocs/op
After:
BenchmarkParseLine-4 322441 3535 ns/op 5520 B/op 53 allocs/op
[v2: single split with SplitFunc; fix a typo in error message]
[v3: rebase after 3159 merge; re-ran benchmarks (results are similar)]
Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Previous commits removed all its users -- the only one left is package's
own unit tests.
Modify those unit tests to configure logrus directly, and remove
ConfigureLogging for good. The world is better without it.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Use the term "clos group" instead of "container_id group" as the group
that a container belongs to is not necessarily tied to its container id.
Signed-off-by: Markus Lehtonen <markus.lehtonen@intel.com>
Those states are available since Linux 4.14 (kernel commits
8ef9925b02c23e3838d5 and 06eb61844d841d003). Before this
patch, they were shown as unknown.
This is mostly cosmetical.
Note that I is described in /proc/pid/status as just "idle", although
elsewhere it says it's an idle kernel thread. Let's have it as "idle"
for brevity.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Remove PID field as it is useless.
2. Rewrite parseStat() to make it faster and more correct:
- do not use fmt.Scanf as it is very slow;
- avoid splitting data into 20+ fields, of which we only need 2;
- make sure to not panic on short lines and other bad input;
- add some bad input tests (some fail with old code);
- use LastIndexByte instead of LastIndex.
Benchmarks:
before (from the previous commit message):
> BenchmarkParseStat-4 116415 10804 ns/op
> BenchmarkParseRealStat-4 240 4781769 ns/op
after:
> BenchmarkParseStat-4 1164948 1068 ns/op
> BenchmarkParseRealStat-4 331 3458315 ns/op
We are seeing 10x speedup in a synthetic benchmark, and about 1.4x
speedup in a real world benchmark.
While at it, do not ignore any possible errors, and properly wrap those.
[v2: use pkg/errors more, remove t.Logf from test]
[v3: rebased; drop pkg/errors; gofumpt'ed]
[v4: rebased; improved description]
[v5: rebased; mention bad input tests, added second benchmark results]
[v6: remove PID field, do not use strings.Split, further speedup]
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Add a test case that tests parentheses in command.
2. Replace individual comparisons with reflect.DeepEqual.
This also fixes wrong %-style types in Fatalf statements.
3. Replace Fatalf with Errorf so we don't bail out on the first
failure, and do not check result on error.
4. Add two benchmarks. On my laptop, they show:
BenchmarkParseStat-4 116415 10804 ns/op
BenchmarkParseRealStat-4 240 4781769 ns/op
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
runc resolves symlink before doing bind mount. So
we should save original path while formatting CriuReq for
dump and restore.
"checkpoint: resolve symlink for external bind mount" is merged as
da22625f6986f0ef196eaa1f8bb6adce098f0fb7(PR 2902) previously. And reverted
in commit 70fdc0573dced3464e9c31d674559f77c1de3973(PR 3043) duo to behavior changes
caused by commit 0ca91f44f1664da834bc61115a849b56d22f595f(Fixes: CVE-2021-30465)
Signed-off-by: Liu Hua <weldonliu@tencent.com>
This is helpful to kubernetes in cases it knows for sure that the freeze
is not required (since it created the systemd unit with no device
restrictions).
As the code is trivial, no tests are required.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Add a test for freezeBeforeSet, checking various scenarios including
those that were failing before the fix in the previous commit.
[v2: add more cases, add a check before creating a unit.]
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This fixes the behavior intended to avoid freezing containers/control
groups without it being necessary. This is important for end users of
libcontainer who rely on the behavior of no freeze.
The previous implementation would always get error trying to get
DevicePolicy from the Unit via dbus, since the Unit interface doesn't
contain DevicePolicy.
Signed-off-by: Odin Ugedal <odin@uged.al>
The two exceptions I had to add to codespellrc are:
- CLOS (used by intelrtd);
- creat (syscall name used in tests/integration/testdata/seccomp_*.json).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>