Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libct/cgroups/utils: fix/separate cgroupv1 code #2411

Merged
merged 12 commits into from
Jun 17, 2020

Conversation

kolyshkin
Copy link
Contributor

@kolyshkin kolyshkin commented May 15, 2020

NOTE: this is based on and currently includes #2401. I'll rebase once that one is merged. Rebased

This tries to untangle the mess of code in libcontainers/cgroups/utils.go. There are multiple functions that do same or similar things, with multiple names, and it's not clear which ones should be used for cgroup v1, cgroup v2, or both.

Please review commit by commit.

Besides moving the code around, this PR reverts some attempts to make the functions work equally well for v1 and v2. The truth is, v2 is a very different beast and most of the functions that were v1-specific should stand that way.

The only real fix here is commit 775a5cb:

libct/criuApplyCgroups: don't set cgroup paths for v2

There is no need to have cgroupv1-specific controller paths on restore
in case of cgroupv2.

I think the above was the last use of unholy multiple v1 paths in v2 code. 🎉

"strings"
)

// Functions in this source file are specific to cgroupv1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we split pkg

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me try

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to do that. The problem, though, is all the existing users of runc need to adopt. I'm not sure how disruptive it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, forgot the tests :)

@kolyshkin kolyshkin force-pushed the v1-specific branch 2 times, most recently from 1259ffa to bc51452 Compare May 18, 2020 18:46
@AkihiroSuda
Copy link
Member

AkihiroSuda commented May 19, 2020

LGTM

Approved with PullApprove

@kolyshkin
Copy link
Contributor Author

So, I checked moby/moby and found these cgroupv1-only functions are used from the code:

daemon/daemon_unix.go:  mnt, root, err := cgroups.FindCgroupMountpointAndRoot("", "cpu")
daemon/oci_linux.go:                    initPath, err := cgroups.GetInitCgroup("cpu")
daemon/oci_linux.go:                    _, err = cgroups.GetOwnCgroup("cpu")
pkg/sysinfo/sysinfo_linux.go:   cgMounts, err := cgroups.GetCgroupMounts(false)
pkg/sysinfo/sysinfo_linux.go:   _, err := cgroups.FindCgroupMountpoint("", "pids")

so this PR will obviously break it.

The reason is, all this stuff is very cgroupv1 specific and it makes no sense to use it when cgroupv2 is used on the host. In case it is still used in such scenario it means the code is doing something wrong and is broken.

@thaJeztah please note the above (and I will be happy to help fix it in moby code).

@kolyshkin kolyshkin force-pushed the v1-specific branch 2 times, most recently from b88e242 to 5fa4cf9 Compare May 19, 2020 22:11
@kolyshkin

This comment has been minimized.

@kolyshkin

This comment has been minimized.

@kolyshkin
Copy link
Contributor Author

rebased to trigger CI

@kolyshkin
Copy link
Contributor Author

@thaJeztah please note the above (and I will be happy to help fix it in moby code).

update: looks like the place which needs fixing is WithCgroups in daemon/oci_linux.go. Indeed, this code is probably not working right for cgroupv2. Everything else is mostly s|cgroups|cgroups/cgroupv1|g.

@kolyshkin
Copy link
Contributor Author

kolyshkin commented May 20, 2020

hmm, a single failure from Fedora32 on Vagrant (logs here):

=== RUN   TestExecInTTY
    TestExecInTTY: execin_test.go:351: unexpected carriage-return in output
--- FAIL: TestExecInTTY (0.14s)

does not look like to be related. This comes from #1146. Hmm

Update: filed #2425

@kolyshkin
Copy link
Contributor Author

OK I think this one is ready. @opencontainers/runc-maintainers PTAL

@kolyshkin
Copy link
Contributor Author

rebased

@AkihiroSuda
Copy link
Member

AkihiroSuda commented May 20, 2020

LGTM

Approved with PullApprove

@kolyshkin
Copy link
Contributor Author

@thaJeztah PTAL. I looked through the moby/moby code and after moby/moby#41014 and moby/moby#41016 the changes to moby/moby should be trivial.

@kolyshkin
Copy link
Contributor Author

kolyshkin commented May 23, 2020

updated the patchset to not move GetAllSubsystems out of cgroup1 package (i.e. it can be used for both v1 and v2 code). No other changes.

@giuseppe
Copy link
Member

There is still a case where we would end up using v1 code in v2 in k8s upstream. @giuseppe I know you were looking at updating this into cadvisor. Do you have your latest tree?

get it to work into cAdvisor requires some substantial changes to how cAdvisor uses libcontainer, or recreate in cAdvisor the cgroupv1.Mount struct when running on cgroup v2. I am worried that there is not much time for introducing changes given that the Kubernetes code freeze for 1.19 is in 10 days.

@kolyshkin
Copy link
Contributor Author

So, what we can do now is commit everything except the last patch (so the v1 code is moved to a separate file but not (yet) to a separate package, leaving this last step for later time.

@mrunalp
Copy link
Contributor

mrunalp commented Jun 15, 2020

@kolyshkin Doing it in steps sounds good 👍

@kolyshkin
Copy link
Contributor Author

kolyshkin commented Jun 15, 2020

OK so what I did is removed two commits:

  1. one that moved code to a separate cgroupv1 package
  2. one that made type NotFoundError private

@giuseppe PTAL

@kolyshkin
Copy link
Contributor Author

Phase 2 (move v1 to a separate package) can be done once we made sure all the users are (or can be) converted.

This function is not used and were never used in any cgroupv2 code.

To have it stay that way, let it return error in case it's called
for v2.

Signed-off-by: Kir Kolyshkin <[email protected]>
@kolyshkin
Copy link
Contributor Author

rebased

Subsystems: availableControllers,
}
return []Mount{m}, nil
return nil, errUnified
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this change breaks the Kubelet and cAdvisor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

This function should not really be used for cgroupv2 code.
Currently it is used in kubernetes code, so we can't remove
the v2 case yet.

Add a TODO item to remove v2 code once kubernetes is converted
to not use it, and separate out v1 code.

Signed-off-by: Kir Kolyshkin <[email protected]>
It's bad and wrong to use these functions for any cgroupv2 code,
and there are no existing users (in runc, at least).

Make them return an error in such case.

Also, remove the cgroupv2-specific handling from
findCgroupMountpointAndRootFromReader().

Signed-off-by: Kir Kolyshkin <[email protected]>
Its value can be easily deduced from the request type.

While at it, simplify the call logic.

Signed-off-by: Kir Kolyshkin <[email protected]>
There is no need to have cgroupv1-specific controller paths on restore
in case of cgroupv2.

Signed-off-by: Kir Kolyshkin <[email protected]>
This function is only called from cgroupv1 code, so there is no need
for it to implement cgroupv2 stuff.

Make it v1-specific, and panic if it is called from v2 code (since this
is an internal function, the panic would mean incorrect runc code).

Signed-off-by: Kir Kolyshkin <[email protected]>
In particular, state that for cgroup v2 the result is very different.

Signed-off-by: Kir Kolyshkin <[email protected]>
This function is cgroupv1-specific, is only used once, and its name
is very close to the name of another function, FindCgroupMountpoint.

Inline it into the (only) caller.

Signed-off-by: Kir Kolyshkin <[email protected]>
In most project, "utils" is a big mess, and this is not an exception.
Try to clean it up a bit by moving cgroup v1 specific code to a separate
source file.

There are no code changes in this commit, just moving it from one file
to another.

Signed-off-by: Kir Kolyshkin <[email protected]>
When testing GetCgroupMounts, the map data is supposed to be obtained
from /proc/self/cgroup, but since we're mocking things, we provide
our own map.

Unfortunately, not all controllers existing in mountinfos were listed.
Also, "name=systemd" needs special handling, so add it.

The controllers added were:

 * for fedoraMountinfo case: name=systemd
 * for systemdMountinfo case: name=systemd, net_prio
 * for bedrockMountinfo case: name=systemd, net_prio, pids

Signed-off-by: Kir Kolyshkin <[email protected]>
It is easy to just use TrimPrefix which does nothing in case the prefix
does not exist.

Signed-off-by: Kir Kolyshkin <[email protected]>
no changes, just a few git renames

Signed-off-by: Kir Kolyshkin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants