-
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
base: main
Are you sure you want to change the base?
Conversation
520aadd
to
d141fb0
Compare
libcontainer/intelrdt/intelrdt.go
Outdated
@@ -474,6 +474,16 @@ func (m *Manager) Apply(pid int) (err error) { | |||
return newLastCmdError(err) | |||
} | |||
|
|||
// 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
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
@@ -478,6 +478,16 @@ func (m *Manager) Apply(pid int) (err error) { | |||
return newLastCmdError(err) | |||
} | |||
|
|||
// 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...) |
@@ -478,6 +478,16 @@ func (m *Manager) Apply(pid int) (err error) { | |||
return newLastCmdError(err) | |||
} | |||
|
|||
// 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?)
abafdf8
to
dac3655
Compare
Updated, review comments addressed |
ce987d5
to
88604c3
Compare
Updated @rata |
Signed-off-by: Markus Lehtonen <[email protected]>
88604c3
to
c0415e2
Compare
Rebased to resolve conflicts |
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.
Sorry I didn't check the tests before. Let's improve and reduce the c&p. Let's make it more standard golang table-tests.
d7032f0
to
19e2d0a
Compare
Updated: test refactored |
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)
19e2d0a
to
eb6f5ec
Compare
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]>
eb6f5ec
to
04b55ac
Compare
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. |
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 |
Signed-off-by: Markus Lehtonen <[email protected]>
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.
Refs: opencontainers/runtime-spec#1287