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

Implement function cgroupid(path) -> cgroup id #170

Merged
merged 4 commits into from Oct 16, 2018

Conversation

alban
Copy link
Contributor

@alban alban commented Oct 11, 2018

This PR is the second part to implement #150.

Note: it works fine on my Fedora laptop when compiled with:

LLVM_DIR=/usr/lib64/llvm cmake . && make all

But the Docker build stopped building. The alpine builder image is based on musl libc instead of glibc and it does not support name_to_handle_at. I tried to switch back to the ubuntu builder image but I got the same error as in this email from linux.debian.bugs.dist and I couldn't fix it.

I added a test in tests/codegen.cpp for the builtin cgroup but I am not sure how to check the generated instructions. I assume it is fine because it works when I test manually.

I didn't add a test for the function cgroupid() because it does not generate any interesting BPF instructions but just calls name_to_handle_at() in userspace. The result of that is depending on the local system. With systemd configured in cgroup hybrid mode, cgroup-v2 would be mounted in /sys/fs/cgroup/unified but it could be mounted differently in other systemd configuration.

@alban
Copy link
Contributor Author

alban commented Oct 11, 2018

I also tried to build from a Fedora Docker image, without success (build log).

@brendangregg
Copy link
Contributor

Yes, we think there's a different issue with Docker builds at the moment. This patch looks good.

@brendangregg
Copy link
Contributor

Just noticed: this needs an addition to the reference guide as well. Thanks!

@ajor
Copy link
Member

ajor commented Oct 11, 2018

The Fedora Docker build errors are because it’s using LLVM 7 - see #149

The Docker errors we’ve got at the moment are limited to string comparisons so I’d rather not completely break the Alpine build

src/bpftrace.cpp Outdated
uint64_t cgid;
int err, mount_id;
file_handle *handle = reinterpret_cast<struct file_handle *>(
malloc(sizeof(file_handle) + sizeof(uint64_t)));
Copy link
Member

Choose a reason for hiding this comment

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

Can handle just be allocated on the stack instead here?

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I see it needs more space than the struct now...
Could we do something like create our own wrapper struct with the regular file_handle and a uint64_t inside to avoid the dynamic allocation then? Or use smart pointers - I just don't like having malloc and free in here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, I'll rewrite it to put it on the stack.

@ajor
Copy link
Member

ajor commented Oct 11, 2018

name_to_handle_at was added to musl a month ago but there was a release a week before that so I don't think we can just wait for them to put out another release. I think Alpine is necessary as the base Docker image because it was the only distro I found which packaged libclang as a static library.

Maybe we could just #ifdef this code out so it's not available from Alpine/Docker builds until the next release of musl

@@ -254,6 +254,14 @@ void SemanticAnalyser::visit(Call &call)
}
call.type = SizedType(Type::integer, 8);
}
else if (call.func == "cgroupid") {
if (check_nargs(call, 1)) {
if (check_arg(call, Type::string, 0, true)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This if is pointless, no? So just having check_arg(call, …); should be enough.

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 reproducing the coding style from above

Copy link
Member

Choose a reason for hiding this comment

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

Appreciate you sticking to the file's coding style, but I think in this case that code is just wrong

src/bpftrace.cpp Outdated
{
uint64_t cgid;
int err, mount_id;
file_handle *handle = reinterpret_cast<struct file_handle *>(
Copy link
Contributor

Choose a reason for hiding this comment

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

The struct keyword inside reinterpret cast is unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, I'll remove it.

Copy link
Contributor Author

@alban alban left a comment

Choose a reason for hiding this comment

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

I had a look at the alpine:edge and alpine:latest docker images but they still don't provide name_to_handle_at. I'll add #ifdef for now, as suggested.

@@ -254,6 +254,14 @@ void SemanticAnalyser::visit(Call &call)
}
call.type = SizedType(Type::integer, 8);
}
else if (call.func == "cgroupid") {
if (check_nargs(call, 1)) {
if (check_arg(call, Type::string, 0, true)) {
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 reproducing the coding style from above

src/bpftrace.cpp Outdated
{
uint64_t cgid;
int err, mount_id;
file_handle *handle = reinterpret_cast<struct file_handle *>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, I'll remove it.

src/bpftrace.cpp Outdated
uint64_t cgid;
int err, mount_id;
file_handle *handle = reinterpret_cast<struct file_handle *>(
malloc(sizeof(file_handle) + sizeof(uint64_t)));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, I'll rewrite it to put it on the stack.

@krnowak
Copy link
Contributor

krnowak commented Oct 15, 2018

Updated the PR, I think I addresses all the review issues. But running build.sh failed here, though:

~/projects/kinvolk/bpftrace
-- The C compiler identification is GNU 6.4.0
-- The CXX compiler identification is GNU 6.4.0
-- Check for working C compiler: /usr/bin/cc
CMake Error: Generator: execution of make failed. Make command was: "/usr/bin/gmake" "cmTC_0204d/fast"
-- Check for working C compiler: /usr/bin/cc -- broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCCompiler.cmake:52 (message):
  The C compiler

    "/usr/bin/cc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /home/kv/projects/kinvolk/bpftrace/CMakeFiles/CMakeTmp
    
    Run Build Command:"/usr/bin/gmake" "cmTC_0204d/fast"
    No such file or directory
    Generator: execution of make failed. Make command was: "/usr/bin/gmake" "cmTC_0204d/fast"
    

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "/home/kv/projects/kinvolk/bpftrace/CMakeFiles/CMakeOutput.log".
See also "/home/kv/projects/kinvolk/bpftrace/CMakeFiles/CMakeError.log".

@krnowak
Copy link
Contributor

krnowak commented Oct 15, 2018

Uh, I still need to add it to the reference guide, I haven't noticed it before.

@brendangregg
Copy link
Contributor

I doubt your changes broke build.sh, that's likely a separate issue we need to fix. I've been doing manual builds on ubuntu as shown in install.md.

I'd suggest improving this error message:

# bpftrace -e 'tracepoint:syscalls:sys_enter_openat /cgroup == cgroupid("/sys/fs/cgroup/unified/mycg")/ { printf("%s\n", str(args->filename)); }'
terminate called after throwing an instance of 'std::runtime_error'
  what():  name_to_handle_at() failed!
Aborted (core dumped)

Instead of what(): name_to_handle_at() failed!, I think it'd be better to say: cgroup /sys/fs/cgroup/unified/mycg not found.

This also core dumps (it doesn't need to), but that's something we can clean up separately along with the other normal error paths that use throw when they probably should use something else. So right now I'd just change the text.

@ajor
Copy link
Member

ajor commented Oct 15, 2018

build.sh still works for me when I check out your branch. Not sure what's causing the problem you're seeing, but I don't think these changes are responsible

krnowak and others added 4 commits October 16, 2018 14:09
We will wrap the file_handle struct in the next commit. The struct has
a flexible array member, which is not supported by C++. Compiler may
complain about using it when allocated on stack, even indirectly as a
member of a struct. I'm not sure if using this kind of types is even a
defined behavior…
Currently used image of alpine has a version of musl libc that does
not have name_to_handle_at function that is required to resolve the
cgroup id. In such case we just use an implementation that says that
resolving cgroupid is not supported.
Mention the `cgroup` variable and the `cgroupid` function alongside an
example that uses them both.
@krnowak
Copy link
Contributor

krnowak commented Oct 16, 2018

Updated the PR - changed the error message (I think it would be nice to consume errno there too), updated the reference to mention both cgroup variable and cgroupid function. Apart from that, build.sh started working again, after I dropped all the images and refetched everything again. I guess something got updated in the meantime or I was using some old broken image of something (alpine?).

@brendangregg
Copy link
Contributor

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants