The default timeout is 360 minutes, which is way long for these jobs.
If the CI (or a test) has stuck, we'd better know about it earlier than
in 6 hours.
Set the timeouts for some [relatively] long running jobs conservatively:
- test and release jobs usually take ~10 minutes;
- lint job takes 1 minute (but can be a few times slower when we switch
Go or golangci-lint version);
- cross-386 job takes about 2 minutes;
- the rest is seconds (and I am lazy to set timeouts everywhere).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In the runc state JSON we always use snake_case. This is a no-op change,
but it will cause any existing container state files to be incorrectly
parsed. Luckily, commit fbf183c6f8 ("Add uid and gid mappings to
mounts") has never been in a runc release so we can change this before a
1.2.z release.
Fixes: fbf183c6f8 ("Add uid and gid mappings to mounts")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
The original implementation of cgroupns had additional synchronisation
to "ensure" that the process is in the correct cgroup before unsharing
the cgroupns. This behaviour was actually never necessary, and after
commit 5110bd2fc0 ("nsenter: remove cgroupns sync mechanism") there is
no synchronisation at all, meaning that CLONE_NEWCGROUP should not get
any special treatment.
Fixes: 5110bd2fc0 ("nsenter: remove cgroupns sync mechanism")
Fixes: df3fa115f9 ("Add support for cgroup namespace")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
The kernel ignores these arguments, and passing them can lead to
confusing error messages (the old source is irrelevant for MS_REMOUNT),
as well as causing issues for a future patch where we switch to
move_mount(2).
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
*os.File is correctly tracked by the garbage collector, and there's no
need to use raw file descriptors for this code.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This includes quite a few cleanups and improvements to the way we do
synchronisation. The core behaviour is unchanged, but switching to
embedding json.RawMessage into the synchronisation structure will allow
us to do more complicated synchronisation operations in future patches.
The file descriptor passing through the synchronisation system feature
will be used as part of the idmapped-mount and bind-mount-source
features when switching that code to use the new mount API outside of
nsexec.c.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The code in this function became quite complicated and not entirely
correct over time. As a result, if an error is returned from parseSync,
it might end up stuck waiting for the child to finish.
1. Let's not wait() for the child twice. We already do it in the
defer statement (call p.terminate()) when we are returning an error.
2. Remove sentResume and sentRun since we do not want to check if
these were sent or not. Instead, introduce and check seenProcReady, as
procReady is always expected from runc init.
3. Eliminate the possibility to wrap nil as an error.
4. Make sure we always call shutdown on the sync socket, and do not let
shutdown error shadow the ierr.
This fixes the issue of stuck `runc runc` with the optimization patch
(sending procSeccompDone earlier) applied.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
These are not exhaustive, but at least confirm that the feature is not
obviously broken (we correctly set the time offsets).
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Fix up a few things that were flagged in the review of the original
timens PR, namely around error handling and validation.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
The idea was to make them strict on dest path from the beginning for
idmap mounts, as runc would do that for all mounts in the future. But
that is causing too many problems.
For now, let's just allow relative paths for idmap mounts too. It just
seems safer.
Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
This reverts commit 881e92a3fd and adjust
the code so the idmap validations are strict.
We now only throw a warning and the container is started just fine.
Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
This commit does two things:
1. Consolidate StartInitialization calling logic into Init().
2. Fix init error handling logic.
The main issues at hand are:
- the "unable to convert _LIBCONTAINER_INITPIPE" error from
StartInitialization is never shown;
- errors from WriteSync and WriteJSON are never shown;
- the StartInit calling code is triplicated;
- using panic is questionable.
Generally, our goals are:
- if there's any error, do our best to show it;
- but only show each error once;
- simplify the code, unify init implementations.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Currently, logrus is used from the Go part of runc init, mostly for a
few debug messages (see setns_init_linux.go and standard_init_linux.go),
and a single warning (see rootfs_linux.go).
This means logrus is part of init implementation, and thus, its setup
belongs to StartInitialization().
Move the code there. As a nice side effect, now we don't have to convert
_LIBCONTAINER_LOGPIPE twice.
Note that since this initialization is now also called from libct/int
tests, which do not set _LIBCONTAINER_LOGLEVEL, let's make
_LIBCONTAINER_LOGLEVEL optional.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
With the new vm.memfd_noexec sysctl, we need to make sure we explicitly
request MFD_EXEC, otherwise an admin could inadvertently break
containers in a somewhat-annoying-to-debug fashion.
It should be noted that vm.memfd_noexec=2 is broken on Linux 6.4
(MFD_EXEC works even in the most restrictive mode) and the most severe
breakage is going to be fixed in Linux 6.6[1].
[1]: https://lore.kernel.org/20230705063315.3680666-2-jeffxu@google.com/
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
While the ro-bind-mount trick did eliminate the memory overhead of
copying the runc binary for each "runc init" invocation, on machines
with very significant container churn, creating a temporary mount
namespace on every container invocation can trigger severe lock
contention on namespace_sem that makes containers fail to spawn.
The only reason we added bindfd in commit 16612d74de ("nsenter:
cloned_binary: try to ro-bind /proc/self/exe before copying") was due to
a Kubernetes e2e test failure where they had a ridiculously small memory
limit. It seems incredibly unlikely that real workloads are running
without 10MB to spare for the very short time that runc is interacting
with the container.
In addition, since the original cloned_binary implementation, cgroupv2
is now almost universally used on modern systems. Unlike cgroupv1, the
cgroupv2 memcg implementation does not migrate memory usage when
processes change cgroups (even cgroupv1 only did this if you had
memory.move_charge_at_immigrate enabled). In addition, because we do the
/proc/self/exe clone before synchronising the bootstrap data read, we
are guaranteed to do the clone before "runc init" is moved into the
container cgroup -- meaning that the memory used by the /proc/self/exe
clone is charged against the root cgroup, and thus container workloads
should not be affected at all with memfd cloning.
The long-term fix for this problem is to block the /proc/self/exe
re-opening attack entirely in-kernel, which is something I'm working
on[1]. Though it should also be noted that because the memfd is
completely separate to the host binary, even attacks like Dirty COW
against the runc binary can be defended against with the memfd approach.
Of course, once we have in-kernel protection against the /proc/self/exe
re-opening attack, we won't have that protection anymore...
[1]: https://lwn.net/Articles/934460/
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
As we now log the log file name in logCriuErrors.
While at it, there is no need to use var.String() with %s as it is done
by the runtime.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
When criu fails, it does not give us much context to understand what
was the cause of an error -- for that, we need to take a look into its
log file.
This is somewhat complicated to do (as you can see in parts of
checkpoint.bats removed by this commit), and not very user-friendly.
Add a function to find and log errors from criu logs, together with some
preceding context, in case either checkpoint or restore has failed.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This test fails in CI sometimes with the following error:
> `testcontainer test_update stopped' failed
Give OOM killer some time to do its job.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
A few cases relied on the fact that systemd is used, and thus
/sys/fs/cgroup/user.slice is available.
Guess what, in case of "make unittest" it might not be.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Split the test into two -- for fs and systemd cgroup managers, and only
run the second one if systemd is available.
Prevents the following failure during `make unittest`:
> === RUN TestNilResources
> manager_test.go:27: systemd not running on this host, cannot use systemd cgroups manager
> --- FAIL: TestNilResources (0.22s)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
For "make integration", the tests are run inside a Docker/Podman
container. Problem is, if cgroup v2 is used, the in-container
/sys/fs/cgroup/cgroup.subtree_control is empty.
The added script, used as Docker entrypoint, moves the current process
into a sub-cgroup, and then adds all controllers in top-level
cgroup.subtree_control.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
"time" namespace was introduced in Linux v5.6
support new time namespace to set boottime and monotonic time offset
Example runtime spec
"timeOffsets": {
"monotonic": {
"secs": 172800,
"nanosecs": 0
},
"boottime": {
"secs": 604800,
"nanosecs": 0
}
}
Signed-off-by: Chethan Suresh <chethan.suresh@sony.com>
We can't call log.Fatalf() and defer functions, as the former doesn't
call any defers. Let's just move the code to a new function and call
os.Exit() only in main, when all defer executed.
Now that all the code is one function, we only print twice to stderr. It
is simpler to just print to stderr instead of logging and having also
the timestamp we don't really want.
Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
Let's just rely on the lookup performed to find the sleep binary.
This didn't cause any issues as far as I know, I just saw this while
doing other cleanups.
Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>