libcontainer/integration: fix cgroupv1 + systemd tests#2600
Conversation
|
This is interesting and need to be looked at (happens on CentOS 7) |
dbb459c to
a2412a8
Compare
|
pushed a half-finished PR to test intermediate commits |
6330351 to
63c36d0
Compare
|
@AkihiroSuda @mrunalp PTAL |
| if p.userns { | ||
| config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}} | ||
| config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}} | ||
| config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER}) | ||
| } else { |
There was a problem hiding this comment.
This function will be a long, long list of ifs if more options are added; wondering, would it be an idea to use functional arguments for this? newTemplateConfig(withRootfs(foo), withSystemd())?
There was a problem hiding this comment.
Frankly speaking I just don't like that paradigm much. I find it harder to read as you have to jump back and forth too much to read the code. It might be useful for APIs with external users, to make the code using it less ugly, but in this case these are internal tests, so the only user is runc.
Actually, let me try rewriting it with functional args, and let's see which one looks better...
There was a problem hiding this comment.
OK, I tried, but I am not sure how to handle "else" cases. Such as this one:
if p.userns {
config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER})
} else {
config.Mounts = append(config.Mounts, &configs.Mount{
Destination: "/sys/fs/cgroup",
Device: "cgroup",
Flags: defaultMountFlags | unix.MS_RDONLY,
})
}Surely I can add this mount unconditionally, and make withUserNS remove it, but it does not look perfect :-\
So, I'd rather let it stay as is for now.
There was a problem hiding this comment.
Feel free to code the alternative though if you like @thaJeztah
This comment has been minimized.
This comment has been minimized.
ce5f015 to
ce0cff4
Compare
...so we can add more fields later.
This commit is mostly courtesy of
sed -i 's/newTemplateConfig(rootfs)/newTemplateConfig(\&tParam{rootfs: rootfs})/g'
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
It seems that a few tests add a cgroup mount in case userns is not set. Let's do it inside newTemplateConfig() for all tests. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
... and properly set ScopePrefix, Name and Parent for a systemd case. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Commit a1d5398 ("Respect container's cgroup path") added a cgroupPath argument to FindCgroupMountpoint to make runc/libcontainer work in a custom multitenant environment with multiple cgroup mount points. It also added passing c.Path as an argument to FindCgroupMountpoint for systemd (v1) controller. This is wrong, because 1. systemd controller do not use c.Path at all (and c.Path is never set by specconv) -- instead, it uses Name and Parent. 2. c.Path, if set, is not absolute -- it is relative to /sys/fs/cgroup -- but it is used as an absolute path here. Since c.Path is never set, the change did not result in any breakage, so this code sit quietly for some time and the issue might not have been discovered -- until we started running libcontainer/integration tests in a CentOS 7 VM, which resulted in a following weird error: > FAIL: TestPidsSystemd: utils_test.go:55: exec_test.go:630: unexpected error: container_linux.go:353: starting container process caused: process_linux.go:326: applying cgroup configuration for process caused: mountpoint for devices not found The error was "fixed" in commit f57bb2f by changing the tests' cgroups Path to be "/sys/fs/cgroup/". This actually resulted in creation of cgroup directories like /sys/fs/cgroup/memory/sys/fs/cgroup, /sys/fs/cgroup/devices/sys/fs/cgroup and so on. The proper fix to the test case is implemented in the previous commit, which sets c.Name and c.Parent. This commit just removes the invalid use of c.Path, and tells the whole story. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Commit 27d3dd3 ("don't fail when subsystem not mounted") added ignoring "not found" error to enableKmem, and as a result the function now tries to call Mkdir with an empty path, which results in a weird error message. For example, this is a failure from a libcontainer/integration test: > === RUN TestRunWithKernelMemorySystemd > exec_test.go:704: runContainer failed with kernel memory limit: container_linux.go:370: starting container process caused: process_linux.go:327: applying cgroup configuration for process caused: mkdir : no such file or directory I am not entirely sure if it is a good idea to silently ignore set limits, but at least let's fix the error handling. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
ce0cff4 to
f0fdde7
Compare
|
Added two more commit fixing the underlying code issues found by tests and hidden by #2501. I find it quite interesting that bad tests revealed a couple of actual (albeit small) bugs. |
Commit f57bb2f set it to /sys/fs/cgroup which is somewhat confusing
as now tests create cgroups that look like this on the filesystem:
... etc.
but it worked!
It seems that some(?) tests were still not working properly with systemd because of invalid configuration.
Similar to what libcontainer/specconv does, add the functionality to set proper cgroup parameters for systemd.
This fixes all the tests.
Fixes: #2473
This PR also fixes the root cause of the breakage, which calls for
a separate story to be told. Gather around, kids, let me tell it to you.
Commit a1d5398 ("Respect container's cgroup path") added a
cgroupPathargument toFindCgroupMountpointto make runc/libcontainerwork in a custom multitenant environment with multiple cgroup mount
points.
It also added passing
c.Pathas an argument toFindCgroupMountpointfor systemd (v1) controller:
runc/libcontainer/cgroups/systemd/v1.go
Line 270 in 0a9af39
This change is wrong for two reasons:
systemd controller do not use
c.Pathat all (andc.Pathis never setby
specconv) -- instead, it usesNameandParentfields.c.Path, if set, is not absolute -- it is relative to/sys/fs/cgroup-- but it is used as an absolute path here.
Now, as
c.Pathis never set, the change did not result in any breakage,and this code sit quietly for some time. The issue might not have been
discovered -- until we started running libcontainer/integration tests
in a CentOS 7 VM, which resulted in a following weird error:
The error was "fixed" in commit f57bb2f by changing the tests'
cgroups Path to be "/sys/fs/cgroup/". This indeed fixed the issue, but
resulted in creation of cgroup directories like
/sys/fs/cgroup/memory/sys/fs/cgroup,/sys/fs/cgroup/devices/sys/fs/cgroupand so on.So, revert the change to avoid confusion.
A bonus story for you.
Commit 27d3dd3 ("don't fail when subsystem not mounted") added
ignoring "not found" error to enableKmem, and as a result the function
now tries to call Mkdir with an empty path, which results in a weird
error message. For example, this is a failure from a
libcontainer/integration test:
I am not entirely sure if it is a good idea to silently ignore set
limits, but at least let's fix the error handling.