GetProcessStartTime was deprecated over three Years ago in
439eaa3584, so we may as well remove
it now.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
errors.Wrap(err, "some error") returns nil if err is nil, so it's
slightly clearer to just return early than to set the error to nil
and call errors.Wrap(). This is also somewhat defensive in case
we decide to replace `errors.Wrap()` for golang's native `%w`
wrapping.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This is a function to convert huge page sizes (obtained by reading
/sys/kernel/mm/hugepages directory entries) to strings user for hugetlb
cgroup controller resource files. Those strings are when used to get the
hugetlb resource statistics.
This function used external library, floating point numbers, and can
(theoretically) produce invalid values, since the kernel only uses KB,
MB, and GB suffixes.
Rewrite it to produce the same strings as used in the kernel (see [1]).
As a result, it's also faster, more future-proof (entries that do not
start with "hugepages-" and/or incorrect suffix are skipped), and does
more input sanity checks. As a side effect, libcontainer no longer
depends on docker/go-units.
While at it, add more test cases.
Before:
BenchmarkGetHugePageSize-8 187452 6265 ns/op
BenchmarkGetHugePageSizeImpl-8 396769 2998 ns/op
After:
BenchmarkGetHugePageSize-8 222898 4554 ns/op
BenchmarkGetHugePageSizeImpl-8 4738924 241 ns/op
NOTE on removing HugePageSizeUnitList -- this was added by commit
6f77e35da and was used by kubernetes code in [2], which was later
superceded by [3], so there are (hopefully) no external users.
If there are any, they should not be doing that.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/hugetlb_cgroup.c?id=eff48ddeab782e35e58ccc8853f7386bbae9dec4#n574
[2] https://github.com/kubernetes/kubernetes/pull/78495
[3] https://github.com/kubernetes/kubernetes/pull/84154
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
When we call terminate(), we kill the process, and wait
returns the error indicating the process was killed.
This is exactly what we expect here, so there is no reason
to treat it as an error.
Before this patch, when a container with invalid cgroup parameters is
started:
> WARN[0000] unable to terminate initProcess error="signal: killed"
> ERRO[0000] container_linux.go:366: starting container process caused: process_linux.go:495: container init caused: process_linux.go:458: setting cgroup config for procHooks process caused: failed to write "555": open /sys/fs/cgroup/blkio/user.slice/xx33/blkio.weight: permission denied
After:
> ERRO[0000] container_linux.go:366: starting container process caused: process_linux.go:495: container init caused: process_linux.go:458: setting cgroup config for procHooks process caused: failed to write "555": open /sys/fs/cgroup/blkio/user.slice/xx33/blkio.weight: permission denied
I.e. the useless warning is gone.
NOTE this breaks a couple of integration test cases, since they were
expecting a particular message in the second line, and now due to
"signal: killed" removed it's in the first line. Fix those, too.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In case cgroup configuration is invalid (some parameters can't be set
etc.), p.manager.Set fails, the error is returned, and then we try to
remove cgroups (by calling p.manager.Destroy) in a defer.
The problem is, the container init is not yet killed (as it is killed in
the caller, i.e. (*linuxContainer).start), so cgroup removal fails like
this:
> time="2020-09-26T07:46:25Z" level=warning msg="Failed to remove cgroup (will retry)" error="rmdir /sys/fs/cgroup/net_cls,net_prio/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod28ce6e74_694c_4b77_a953_dc01e182ac76.slice/crio-f6984c5eeb6c6b49ff3f036bdcb9ded317b3d0b2469ebbb35705442a2afd98c2.scope: device or resource busy"
> ...
> time="2020-09-26T07:46:27Z" level=error msg="Failed to remove cgroup" error="rmdir /sys/fs/cgroup/net_cls,net_prio/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod28ce6e74_694c_4b77_a953_dc01e182ac76.slice/crio-f6984c5eeb6c6b49ff3f036bdcb9ded317b3d0b2469ebbb35705442a2afd98c2.scope: device or resource busy"
The above is repeated for every controller, and looks quite scary.
To fix, move the init termination to the abovementioned defer.
Do the same for (*setnsProcess).start() for uniformity.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
It is not a good practice to have the name `err` for the error returned
by a function. Switch to `retErr`.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In case it takes more than 1 second for systemd to create a unit,
startUnit() times out with a warning and then runc proceeds
(to create cgroups using fs manager and so on).
Now runc and systemd are racing, and multiple scenarios are possible.
In one such scenario, by the time runc calls systemd manager's Apply()
the unit is not yet created, the dbusConnection.SetUnitProperties()
call fails with "unit xxx.scope not found", and the whole container
start also fails.
To eliminate the race, we need to return an error in case the timeout is
hit.
To reduce the chance to fail, increase the timeout from 1 to 30 seconds,
to not error out too early on a busy/slow system (and times like 3-5
seconds are not unrealistic).
While at it, as the timeout is quite long now, make sure to not leave
a stray timer.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Use GetCgroupParamString as the initial part of both functions are
the same and we can reuse it. This also gives us whatever security
measures GetCgroupParamString has (see previous commit).
2. Fix the error wrapping to not add the value, as it is already a part
of the error returned by ParseUint.
3. Improve docstring.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Use own ReadFile wrapper instead of ioutils.ReadFile.
This makes it use the security measures of ReadFile.
2. Improve doc.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2. Fix wrapping the error to not have the value as it's already
part of the error returned from ParseUint.
3. Fix/improve doc.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Don't wrap the error from fscommon.GetCgroupParamUint as it already
contains the file name.
2. Don't put file name when wrapping the error from ioutil.ReadFile
since it already has it.
3. Don't reconstruct file name, use existing one since it's available.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The names of these templates overlapped with some local
variables, which made reading the code somewhat confusing.
Changing them to a const, given that these were not updated anywere.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It might be a tad slower but it surely more correct and well maintained,
so it's better to use it than rely on a custom implementation which is
kind of hard to get entirely right.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
ioutil.ReadFile does a stat() on every entry and returns a slice of
os.Stat structures. What we need here is just a file name.
This change both simplifies and speeds up the code a bit.
Before:
BenchmarkGetHugePageSize-8 115213 9400 ns/op
After:
BenchmarkGetHugePageSize-8 190326 6187 ns/op
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
On my laptop, I get
BenchmarkGetHugePageSize
BenchmarkGetHugePageSize-8 115213 9400 ns/op
BenchmarkGetHugePageSizeImpl
BenchmarkGetHugePageSizeImpl-8 397873 2971 ns/op
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This was a workaround for RHEL6 (2.6.xx) kernels, which have not
been supported by container runtimes for a long time, so should
be safe to remove this workaround.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
runc already tells CRIU to restore into an existing network or PID
namespace if there is a path to a namespace specified in config.json.
PID and network have special handling in CRIU using CRIU's inherit_fd
interface.
For UTS, IPC and MOUNT namespaces CRIU can join those existing
namespaces using CRIU's join_ns interface.
This is especially interesting for environments where containers are
running in a pod which already has running containers (pause for
example) with namespaces configured and the restored container needs to
join these namespaces.
CRIU has no support to join an existing CGROUP namespace (yet?) why
restoring a container with a path specified to a CGROUP namespace will
be aborted by runc.
CRIU would have support to restore a container into an existing time
namespace, but runc does not yet seem to support time namespaces.
Signed-off-by: Adrian Reber <areber@redhat.com>
As the underlying error message from iotuils.WriteFile already contains
file name, there's no need to put it, otherwise we end up with something
like:
failed to write "val" to "/sys/fs/cgroup/.../file": open /sys/fs/cgroup/.../file: permission denied
With this patch, the error will be
failed to write "val": open /sys/fs/cgroup/.../file: permission denied
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
If the procRun state has been synced and the runc-create process has
been killed for some reason, the runc-init[2:stage] process will be
leaky. And the runc command also fails to parse root directory because
the container doesn't have state.json.
In order to make it possible to clean the leaky runc-init[2:stage]
process , we should store the status before sync procRun.
```before
current workflow:
[ child ] <-> [ parent ]
procHooks --> [run hooks]
<-- procResume
procReady --> [final setup]
<-- procRun
( killed for some reason)
( store state.json )
```
```expected
expected workflow:
[ child ] <-> [ parent ]
procHooks --> [run hooks]
<-- procResume
procReady --> [final setup]
store state.json
<-- procRun
```
Signed-off-by: Wei Fu <fuweid89@gmail.com>
It's expect that signalAllProcesses is invoked when container shares
pid namespace. share pid ns contains the following conditions:
{
// no specify pid ns
}
{
"type": "pid",
"path": "/proc/${num}/ns/pid"
}
Signed-off-by: Shukui Yang <jryangshukui@jd.com>
Signed-off-by: Shukui Yang <keloyangsk@gmail.com>
In all these cases, getSubsystemPath() was already called, and its
result stored in m.paths map. It makes no sense to not reuse it.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>