-
Notifications
You must be signed in to change notification settings - Fork 2.2k
libcontainer/intelrdt: add support for EnableMonitoring field #4832
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
libcontainer/intelrdt: add support for EnableMonitoring field #4832
Conversation
520aadd to
d141fb0
Compare
libcontainer/intelrdt/intelrdt.go
Outdated
|
|
||
| // Create MON group | ||
| if monPath := m.GetMonPath(); monPath != "" { | ||
| if err := os.MkdirAll(monPath, 0o755); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this path? Inside the container? On the host?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is on the host (now changed to Mkdir)
169609d to
4024488
Compare
86329fe to
2380794
Compare
|
Rebased |
e31d98c to
4af20b5
Compare
|
Updated:
|
fd132e2 to
4e43d65
Compare
rata
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the fmt.Println() lines
4e43d65 to
2fbcde5
Compare
|
|
||
| // Create MON group | ||
| if monPath := m.GetMonPath(); monPath != "" { | ||
| if err := os.Mkdir(monPath, 0o755); err != nil && !os.IsExist(err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who has control of this path? In runc this is trusted, okay, but is it exposed in k8s or containerd or some other to the user?
Not sure with the https://github.com/intel/k8s-rdt-controller what is exposed to an end user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's runc, it's in this very same file (and patch):
func (m *Manager) GetMonPath() string {
if closPath := m.GetPath(); closPath != "" && m.config.IntelRdt.EnableMonitoring {
path, err := securejoin.SecureJoin(filepath.Join(closPath, "mon_groups"), m.id)So it's basically <clos-dir>/mon_groups/<container-id>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, and that comes from intelRdtRoot. But where does that come from? Is there any way an unprivileged user (or just anyone that is not the sysadmin or so) can control any path component (or the intelRDT root)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That, in turn, comes from parsing the output of statfs syscall (unix.Statfs()). Note that in the case of runc update the closPath is taken from the config.json of the container.
In any case I cannot see any way that an unprivileged user can control the path
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So statfs will have some string value and we will mkdir it on the host, outside of the container rootfs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conversation was broken out of this thread, it continued in the main PR discussion. The final answer I found for this is posted here: #4832 (comment)
Basically, the fs will be mounted somewhere on the host by the admin and we might create/delete some dirs inside that. None of that is accessible to the container process.
@marquiz correct me if I'm getting something wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kolyshkin PTAL, I'd like someone else to look at this part too, just in case I'm missing something :)
2fbcde5 to
abafdf8
Compare
|
Rebased (see if the unrelated linter errors go away...) |
|
|
||
| // Create MON group | ||
| if monPath := m.GetMonPath(); monPath != "" { | ||
| if err := os.Mkdir(monPath, 0o755); err != nil && !os.IsExist(err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So statfs will have some string value and we will mkdir it on the host, outside of the container rootfs?
Yes the data comes from the Linux kernel. See statfs syscall, e.g. https://man7.org/linux/man-pages/man2/statfs.2.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly LGTM. But let's use the well-known table tests (or are you avoiding them for a reason?)
|
Updated: test refactored |
rata
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this is getting closer IMHO :)
| if tt.precreateClos { | ||
| if err := os.MkdirAll(filepath.Join(closPath, "mon_groups"), 0o755); err != nil { | ||
| t.Fatal(err) | ||
| } | ||
| } | ||
| m := newManager(&configs.Config{IntelRdt: &tt.config}, id, closPath) | ||
| err := m.Apply(pid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems weird. Apply will create the "mon_groups" directory, so maybe you need to create some parent paths but why "mon_groups"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the mocked filesystem layout. When you have the real resctrl filesystem mounted all the files and directories are there (created/exposed by the linux kernel). Specifically, the Apply() does NOT create the mon_groups directory but the mon_groups/<mon-group-name> dir
EDIT: @rata I probably misread your comment a bit. Apply() creates the CLOS in some cases if it does not already exist. In the precreateClos case we want to test the case(s) where the CLOS already exists and Apply does not create the CLOS. Nevertheless, Apply() never creates the mon_groups directory (under the CLOS directory)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, I see. But we end up doing this here and in the other tests: https://github.com/opencontainers/runc/pull/4832/files#diff-10a177e788e7be5a6826c74946ebbb7390ead3a61f1342a4776dba4d57143942R264-R267
Any reason to not put this also in the constructor for the "fake" intelrdt used in tests?
It can be a param, saying create it, and we just take that from the test if it's an issue to create it when we don't need it. (it seems cleaner to do it that way, maybe)
eb6f5ec to
04b55ac
Compare
rata
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more comment and I think we are there :)
| if tt.precreateClos { | ||
| if err := os.MkdirAll(filepath.Join(closPath, "mon_groups"), 0o755); err != nil { | ||
| t.Fatal(err) | ||
| } | ||
| } | ||
| m := newManager(&configs.Config{IntelRdt: &tt.config}, id, closPath) | ||
| err := m.Apply(pid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, I see. But we end up doing this here and in the other tests: https://github.com/opencontainers/runc/pull/4832/files#diff-10a177e788e7be5a6826c74946ebbb7390ead3a61f1342a4776dba4d57143942R264-R267
Any reason to not put this also in the constructor for the "fake" intelrdt used in tests?
It can be a param, saying create it, and we just take that from the test if it's an issue to create it when we don't need it. (it seems cleaner to do it that way, maybe)
I wouldn't put it there. The constructor is used also in other tests that do not need/want Apply(). We want to setup a mock fs, not exercise the Apply() function which has a very refined logic. Also, in the case of the tests modified/added here. For apply test we want to TEST the Apply() function, thus calling it. For the Destroy test we use it for creation of the per-container-id-CLOS. We could create it "manually", not using Apply() if you think that's better. I know the unit tests are a mess. I would suggest to do bigger refactoring/sanitizing in a separate PR. |
rata
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marquiz I guess some github email reply is not keeping the thread on the proper line of code for you. I'm not sure what you mean with: "we can create it manually, not using Apply()". My suggestion was to move os.mkdirAll() into the fake constructor, maybe under a param if you don't want to create the dirs on evey instantiation.
Or maybe doing it unconditionally as part of the current tests (given that is really just a mkdir, it's not a heavy thing to do) if that sounds better for you.
Marking it as LGTM, but I'd really like for @kolyshkin to take a look, specially at: #4832 (comment) in case I'm missing something
Ah OK, now that makes sense to me. There really was some misalignment. I'll check the details and update the PR |
We cannot do that unconditionally as some tests require the CLOS not to be pre-created. I added a new commit that refactors the tests to give the pre-existing clos (if any) as an arg to the helper constructor. |
The linux.intelRdt.enableMonitoring field enables the creation of a per-container monitoring group. The monitoring group is removed when the container is destroyed. Signed-off-by: Markus Lehtonen <[email protected]>
bb35f6c to
f352280
Compare
|
Rebased |
|
friendly ping @rata @kolyshkin |
|
I have already LGTM, but we need two LGTM to merge :) |
Thanks :) I had added this one commit (refactoring unit tests) since your last comment. |
|
@marquiz thanks, but can we remove that commit? It's not what I had in mind and it's not making the code simpler to read. Sorry. |
f352280 to
7aa4e1a
Compare
Done |
|
ping @kolyshkin |
kolyshkin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
|
@marquiz do you want it to be in 1.4, or 1.5 (in ~6 months) is fine? We're very close to releasing 1.4.0-rc.2 and if you want it, a backport PR is needed right now. |
|
@kolyshkin if possible, I'd very much like to see this in 1.4. It would complete the intelRdt features wrt the runtime-spec. I can do the backport EDIT: #4921 |
The linux.intelRdt.enableMonitoring field enables the creation of a per-container monitoring group. The monitoring group is removed when the container is destroyed.
Refs: opencontainers/runtime-spec#1287