Simplify cgroup paths handling in v2 via unified v1/v2 API#2386
Merged
Conversation
Contributor
Author
|
Personally, I am very happy with the result. The only ugliness that is left is
|
This was referenced May 7, 2020
Contributor
Author
|
@AkihiroSuda PTAL |
AkihiroSuda
reviewed
May 7, 2020
Member
Merged
Contributor
Author
|
I think I'll split it into two PRs for the sake of easier review. Part I: #2387 (relatively easy to review) |
AkihiroSuda
reviewed
May 8, 2020
13f45c7 to
e2c593b
Compare
This unties the Gordian Knot of using GetPaths in cgroupv2 code.
The problem is, the current code uses GetPaths for three kinds of things:
1. Get all the paths to cgroup v1 controllers to save its state (see
(*linuxContainer).currentState(), (*LinuxFactory).loadState()
methods).
2. Get all the paths to cgroup v1 controllers to have the setns process
enter the proper cgroups in `(*setnsProcess).start()`.
3. Get the path to a specific controller (for example,
`m.GetPaths()["devices"]`).
Now, for cgroup v2 instead of a set of per-controller paths, we have only
one single unified path, and a dedicated function `GetUnifiedPath()` to get it.
This discrepancy between v1 and v2 cgroupManager API leads to the
following problems with the code:
- multiple if/else code blocks that have to treat v1 and v2 separately;
- backward-compatible GetPaths() methods in v2 controllers;
- - repeated writing of the PID into the same cgroup for v2;
Overall, it's hard to write the right code with all this, and the code
that is written is kinda hard to follow.
The solution is to slightly change the API to do the 3 things outlined
above in the same manner for v1 and v2:
1. Use `GetPaths()` for state saving and setns process cgroups entering.
2. Introduce and use Path(subsys string) to obtain a path to a
subsystem. For v2, the argument is ignored and the unified path is
returned.
This commit converts all the controllers to the new API, and modifies
all the users to use it.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Contributor
Author
|
@AkihiroSuda @mrunalp @cyphar PTAL |
kolyshkin
commented
May 8, 2020
| func (m *manager) GetPaths() map[string]string { | ||
| m.mu.Lock() | ||
| defer m.mu.Unlock() | ||
| return m.paths |
Contributor
Author
There was a problem hiding this comment.
Not sure if the locking here is needed. Might help in the case when another goroutine is populating the paths in Apply(), but practically I don't think this is a possibility. Nevertheless, nothing wrong to have it here.
kolyshkin
commented
May 8, 2020
|
|
||
| func (m *legacyManager) GetPaths() map[string]string { | ||
| m.mu.Lock() | ||
| defer m.mu.Unlock() |
Member
Contributor
Author
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This unties the Gordian Knot of using GetPaths in cgroupv2 code.
The problem is, the current code uses GetPaths for three kinds of things:
Get all the paths to cgroup v1 controllers to save its state (see
(*linuxContainer).currentState(), (*LinuxFactory).loadState()
methods).
Get all the paths to cgroup v1 controllers to have the setns process
enter the proper cgroups in
(*setnsProcess).start().Get the path to a specific controller (for example,
m.GetPaths()["devices"]).Now, for cgroup v2 instead of a set of per-controller paths, we have only
one single unified path, and a dedicated function
GetUnifiedPath()to get it.This discrepancy between v1 and v2 cgroupManager API leads to the
following problems with the code:
multiple if/else code blocks that have to treat v1 and v2 separately;
backward-compatible GetPaths() methods in v2 controllers;
repeated writing of the PID into the same cgroup for v2;
Overall, it's hard to write the right code with all this, and the code
that is written is kinda hard to follow.
The solution is to slightly change the API to do the 3 things outlined
above in the same manner for v1 and v2:
Use
GetPaths()for state saving and setns process cgroups entering.Introduce and use
Path(subsys string)to obtain a path to asubsystem. For v2, the argument is ignored and the unified path is
returned.
This commit converts all the controllers to the new API, and modifies
all the users to use it.