This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new 4fb4788ee [ebpf] Add helper function for getting bpf fd by program id.
4fb4788ee is described below

commit 4fb4788ee9f47d4b7146de1384d49c7a2b15b246
Author: Jason Zhou <[email protected]>
AuthorDate: Thu Jul 11 15:01:43 2024 -0400

    [ebpf] Add helper function for getting bpf fd by program id.
    
    Introduces a helper function to help abstract away the logic for
    getting bpf program file descriptor by its program id.
    
    Review: https://reviews.apache.org/r/75083/
---
 src/linux/ebpf.cpp                         | 29 ++++++++++++++++-------
 src/linux/ebpf.hpp                         |  6 +++++
 src/tests/containerizer/cgroups2_tests.cpp | 37 ++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/src/linux/ebpf.cpp b/src/linux/ebpf.cpp
index 3f7f74df2..50f2c6743 100644
--- a/src/linux/ebpf.cpp
+++ b/src/linux/ebpf.cpp
@@ -107,6 +107,23 @@ Try<int> load(const Program& program)
 
 namespace cgroups2 {
 
+Try<int> bpf_get_fd_by_id(uint32_t prog_id)
+{
+  bpf_attr attr;
+  memset(&attr, 0, sizeof(attr));
+  attr.prog_id = prog_id;
+
+  Try<int, ErrnoError> fd = bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
+
+  if (fd.isError()) {
+    return Error("bpf syscall to BPF_PROG_GET_FD_BY_ID failed: " +
+                 fd.error().message);
+  }
+
+  return *fd;
+}
+
+
 // Attaches the eBPF program identified by the provided fd to a cgroup.
 //
 // TODO(dleamy): This currently does not replace existing programs attached
@@ -226,18 +243,14 @@ Try<Nothing> detach(const string& cgroup, uint32_t 
program_id)
     return Error("Failed to open '" + cgroup + "': " + cgroup_fd.error());
   }
 
-  bpf_attr attr;
-  memset(&attr, 0, sizeof(attr));
-  attr.prog_id = program_id;
-
-  Try<int, ErrnoError> program_fd =
-    bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
+  Try<int> program_fd = bpf_get_fd_by_id(program_id);
 
   if (program_fd.isError()) {
-    return Error("bpf syscall to BPF_PROG_GET_FD_BY_ID failed: " +
-                 program_fd.error().message);
+    return Error("Could not get bpf fd from program id: "+
+                 program_fd.error());
   }
 
+  bpf_attr attr;
   memset(&attr, 0, sizeof(attr));
   attr.attach_type = BPF_CGROUP_DEVICE;
   attr.target_fd = *cgroup_fd;
diff --git a/src/linux/ebpf.hpp b/src/linux/ebpf.hpp
index 5bf9d34d4..5a81ee55a 100644
--- a/src/linux/ebpf.hpp
+++ b/src/linux/ebpf.hpp
@@ -30,6 +30,9 @@
 
 namespace ebpf {
 
+Try<int, ErrnoError> bpf(int cmd, bpf_attr* attr, size_t size);
+
+
 // eBPF program.
 class Program
 {
@@ -49,6 +52,9 @@ public:
 
 namespace cgroups2 {
 
+// Get the file descriptor of a valid bpf program by its program id.
+Try<int> bpf_get_fd_by_id(uint32_t prog_id);
+
 // Load and attach a BPF_CGROUP_DEVICE eBPF program to a cgroup.
 Try<Nothing> attach(const std::string& cgroup, const Program& program);
 
diff --git a/src/tests/containerizer/cgroups2_tests.cpp 
b/src/tests/containerizer/cgroups2_tests.cpp
index 751c0e389..e4796b6ca 100644
--- a/src/tests/containerizer/cgroups2_tests.cpp
+++ b/src/tests/containerizer/cgroups2_tests.cpp
@@ -758,6 +758,43 @@ INSTANTIATE_TEST_CASE_P(
         }
       ));
 
+
+TEST_F(Cgroups2Test, ROOT_CGROUPS2_GetBpfFdById)
+{
+  const string& cgroup = TEST_CGROUP;
+
+  ASSERT_SOME(cgroups2::create(cgroup));
+  string path = cgroups2::path(cgroup);
+
+  Try<vector<uint32_t>> attached = ebpf::cgroups2::attached(path);
+  ASSERT_SOME(attached);
+  ASSERT_EQ(0u, attached->size());
+
+  ASSERT_SOME(devices::configure(cgroup, {}, {}));
+  attached = ebpf::cgroups2::attached(path);
+  ASSERT_SOME(attached);
+  ASSERT_EQ(1u, attached->size());
+
+  Try<int> cgroup_fd = os::open(path, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
+  ASSERT_SOME(cgroup_fd);
+
+  Try<int> program_fd = ebpf::cgroups2::bpf_get_fd_by_id(attached->at(0));
+  ASSERT_SOME(program_fd);
+
+  bpf_attr attr;
+  memset(&attr, 0, sizeof(attr));
+  attr.attach_type = BPF_CGROUP_DEVICE;
+  attr.target_fd = *cgroup_fd;
+  attr.attach_bpf_fd = *program_fd;
+
+  Try<int, ErrnoError> result = ebpf::bpf(BPF_PROG_DETACH, &attr, 
sizeof(attr));
+
+  os::close(*cgroup_fd);
+  os::close(*program_fd);
+
+  ASSERT_SOME(result);
+}
+
 } // namespace tests {
 
 } // namespace internal {

Reply via email to