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 96fcaf20f [ebpf][cgroups2] Attaching a eBFP programs to a cgroups.
96fcaf20f is described below

commit 96fcaf20fb440e8190fb5cce0660f565496a7274
Author: Devin Leamy <[email protected]>
AuthorDate: Fri Mar 8 16:55:48 2024 -0500

    [ebpf][cgroups2] Attaching a eBFP programs to a cgroups.
    
    Introduces `ebpf::cgroups2::attach()` which allows an `ebpf::Program()` to 
be
    attached to a cgroup, given the absolute path to the cgroup and the file
    descriptor of the loaded program.
    
    This will be used by cgroups v2 Device Controller.
    
    This closes #505
---
 src/linux/ebpf.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/linux/ebpf.hpp | 16 ++++++++++++++-
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/src/linux/ebpf.cpp b/src/linux/ebpf.cpp
index 7bffcb68c..ca68e3e2f 100644
--- a/src/linux/ebpf.cpp
+++ b/src/linux/ebpf.cpp
@@ -24,6 +24,9 @@
 
 #include "stout/check.hpp"
 #include "stout/error.hpp"
+#include "stout/nothing.hpp"
+#include "stout/os/close.hpp"
+#include "stout/os/open.hpp"
 #include "stout/try.hpp"
 
 using std::string;
@@ -96,4 +99,58 @@ Try<int> load(const Program& program)
   return *fd;
 }
 
+namespace cgroups2 {
+
+Try<Nothing> attach(int fd, const string& cgroup)
+{
+  Try<int> cgroup_fd = os::open(cgroup, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
+  if (cgroup_fd.isError()) {
+    return Error("Failed to open '" + cgroup + "': " + cgroup_fd.error());
+  }
+
+  bpf_attr attr;
+  memset(&attr, 0, sizeof(attr));
+  attr.attach_type = BPF_CGROUP_DEVICE;
+  attr.target_fd = *cgroup_fd;
+  attr.attach_bpf_fd = fd;
+
+  // TODO(dleamy): Replace any existing attached programs here!
+  //
+  // BPF_F_ALLOW_MULTI allows multiple eBPF programs to be attached to a single
+  // cgroup and determines how the programs up and down the hierarchy will run.
+  //
+  // Rules (assuming all cgroups use BPF_F_ALLOW_MULTI):
+  //
+  //   1. Programs attached to child cgroups run before programs attached
+  //      to their parent.
+  //   2. Within a cgroup, programs attached earlier will run before programs
+  //      attached later. Note that we do not want to attach multiple programs
+  //      to a single cgroup.
+  //
+  // Order: oldest, ..., newest
+  // cgroup1: A, B
+  //   cgroup2: C
+  //   cgroup3: D, E
+  //     cgroup4: F
+  // cgroup4 run order: F, D, E, A, B
+  // cgroup2 run order: C, A, B
+  //
+  // For full details, see:
+  // 
https://elixir.bootlin.com/linux/v6.7.9/source/include/uapi/linux/bpf.h#L1090
+  attr.attach_flags = BPF_F_ALLOW_MULTI;
+
+  Try<int, ErrnoError> result = bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));
+
+  os::close(*cgroup_fd);
+
+  if (result.isError()) {
+    return Error("BPF program attach syscall failed: "
+                 + result.error().message);
+  }
+
+  return Nothing();
+}
+
+} // namespace cgroups2 {
+
 } // namespace ebpf {
diff --git a/src/linux/ebpf.hpp b/src/linux/ebpf.hpp
index b55e3b962..0e6d81b7f 100644
--- a/src/linux/ebpf.hpp
+++ b/src/linux/ebpf.hpp
@@ -22,8 +22,10 @@
 
 #include <linux/bpf.h>
 
+#include <string>
 #include <vector>
 
+#include "stout/nothing.hpp"
 #include "stout/try.hpp"
 
 namespace ebpf {
@@ -50,6 +52,18 @@ public:
 Try<int> load(const Program& program);
 
 
+namespace cgroups2 {
+
+// Attaches the eBPF program identified by the provided fd to a cgroup.
+//
+// TODO(dleamy): This currently does not replace existing programs attached
+// to the cgroup, we will need to add replacement to support adding / removing
+// device access dynamically.
+Try<Nothing> attach(int fd, const std::string& cgroup);
+
+} // namespace cgroups2 {
+
+
 // Utility macros for constructing eBPF instructions.
 #define BPF_ALU32_IMM(OP, DST, IMM)       \
   ((bpf_insn){                            \
@@ -133,4 +147,4 @@ Try<int> load(const Program& program);
 
 } // namespace ebpf {
 
-#endif // __EBPF_HPP__
\ No newline at end of file
+#endif // __EBPF_HPP__

Reply via email to