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

commit 8ec509bedb409ec7d0a491aa576419a87efba581
Author: Devin Leamy <[email protected]>
AuthorDate: Wed Mar 27 20:58:35 2024 +0000

    [cgroups2] Introduces a `Controller` abstraction for cgroups v2 controllers.
    
    NOTE: In cgroups v1 we call "controllers" "subsystems". In cgroups v2,
          we exclusively use the term "controller", which is what is used
          in the Linux documentation for cgroups v2.
    
    For cgroups v1, the `Subsystem` abstraction is used represent a cgroup
    controller. `Subsystem`s exist for each of the controllers provided by
    the cgroups v1 API.
    
    We do similar for cgroups v2, now introducing the `Controller` abstraction.
    The difference between a `Controller` and a `Subsystem` - besides the
    name - is that a `Controller` does not have an associated hierarchy. This is
    because in cgroups v2, controllers (a.k.a. subsystems) do not need to be
    individually mounted. All controllers are "mounted" under the unified
    `cgroup2` filesystem that we require be mounted at `/sys/fs/cgroup`.
    
    The `Cgroups2IsolatorProcess` delegates resource isolation requests to
    `Controller`s instead of `Subsystem`s.
---
 .../mesos/isolators/cgroups2/cgroups2.cpp          |  10 +-
 .../mesos/isolators/cgroups2/cgroups2.hpp          |   9 +-
 .../mesos/isolators/cgroups2/controller.cpp        | 221 +++++++++++++++++++++
 .../mesos/isolators/cgroups2/controller.hpp        | 142 ++++++++++++-
 4 files changed, 369 insertions(+), 13 deletions(-)

diff --git a/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.cpp 
b/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.cpp
index 2e8a80a51..8a605ae61 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.cpp
@@ -31,9 +31,9 @@ namespace internal {
 namespace slave {
 
 Cgroups2IsolatorProcess::Cgroups2IsolatorProcess(
-  const hashmap<string, Owned<Subsystem>>& _subsystems)
-  : ProcessBase(process::ID::generate("cgroups2-isolator")),
-    subsystems(_subsystems) {}
+    const hashmap<string, Owned<Controller>>& _controllers)
+    : ProcessBase(process::ID::generate("cgroups2-isolator")),
+    controllers(_controllers) {}
 
 
 Cgroups2IsolatorProcess::~Cgroups2IsolatorProcess() {}
@@ -41,9 +41,9 @@ Cgroups2IsolatorProcess::~Cgroups2IsolatorProcess() {}
 
 Try<Isolator*> Cgroups2IsolatorProcess::create(const Flags& flags)
 {
-  hashmap<string, Owned<Subsystem>> subsystems;
+  hashmap<string, Owned<Controller>> controllers;
 
-  Owned<MesosIsolatorProcess> process(new Cgroups2IsolatorProcess(subsystems));
+  Owned<MesosIsolatorProcess> process(new 
Cgroups2IsolatorProcess(controllers));
   return new MesosIsolator(process);
 }
 
diff --git a/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.hpp 
b/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.hpp
index 54d18a484..c67cf777d 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.hpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups2/cgroups2.hpp
@@ -22,11 +22,10 @@
 #include <process/owned.hpp>
 
 #include <stout/hashmap.hpp>
-#include <stout/hashset.hpp>
 #include <stout/try.hpp>
 
 #include "slave/containerizer/mesos/isolator.hpp"
-#include "slave/containerizer/mesos/isolators/cgroups/subsystem.hpp"
+#include "slave/containerizer/mesos/isolators/cgroups2/controller.hpp"
 #include "slave/flags.hpp"
 
 namespace mesos {
@@ -46,10 +45,10 @@ public:
 
 private:
   Cgroups2IsolatorProcess(
-      const hashmap<std::string, process::Owned<Subsystem>>& _subsystems);
+      const hashmap<std::string, process::Owned<Controller>>& controllers);
 
-  // Maps each subsystems to the `Subsystem` isolator that manages it.
-  const hashmap<std::string, process::Owned<Subsystem>> subsystems;
+  // Maps each controller to the `Controller` isolator that manages it.
+  const hashmap<std::string, process::Owned<Controller>> controllers;
 };
 
 } // namespace slave {
diff --git a/src/slave/containerizer/mesos/isolators/cgroups2/controller.cpp 
b/src/slave/containerizer/mesos/isolators/cgroups2/controller.cpp
index 947691ae2..ed05a2e46 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups2/controller.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups2/controller.cpp
@@ -14,5 +14,226 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+
+#include <utility>
+
+#include <stout/error.hpp>
+
 #include "slave/containerizer/mesos/isolators/cgroups2/controller.hpp"
 
+using mesos::slave::ContainerLimitation;
+
+using process::Future;
+using process::Owned;
+
+using std::string;
+
+namespace mesos {
+namespace internal {
+namespace slave {
+
+Controller::Controller(Owned<ControllerProcess> _process)
+  : process(std::move(_process))
+{
+  process::spawn(process.get());
+}
+
+
+Controller::~Controller()
+{
+  process::terminate(process.get());
+  process::wait(process.get());
+}
+
+
+string Controller::name() const
+{
+  return process->name();
+}
+
+
+Try<Owned<Controller>> Controller::create(
+    const Flags& flags,
+    const string& name)
+{
+  return Error("Controller '" + name + "' is not yet supported in cgroups v2");
+}
+
+
+Future<Nothing> Controller::recover(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::recover,
+      containerId,
+      cgroup);
+}
+
+
+Future<Nothing> Controller::prepare(
+    const ContainerID& containerId,
+    const string& cgroup,
+    const mesos::slave::ContainerConfig& containerConfig)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::prepare,
+      containerId,
+      cgroup,
+      containerConfig);
+}
+
+
+Future<Nothing> Controller::isolate(
+    const ContainerID& containerId,
+    const string& cgroup,
+    pid_t pid)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::isolate,
+      containerId,
+      cgroup,
+      pid);
+}
+
+
+Future<mesos::slave::ContainerLimitation> Controller::watch(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::watch,
+      containerId,
+      cgroup);
+}
+
+
+Future<Nothing> Controller::update(
+    const ContainerID& containerId,
+    const string& cgroup,
+    const Resources& resourceRequests,
+    const google::protobuf::Map<string, Value::Scalar>& resourceLimits)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::update,
+      containerId,
+      cgroup,
+      resourceRequests,
+      resourceLimits);
+}
+
+
+Future<ResourceStatistics> Controller::usage(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::usage,
+      containerId,
+      cgroup);
+}
+
+
+Future<ContainerStatus> Controller::status(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::status,
+      containerId,
+      cgroup);
+}
+
+
+Future<Nothing> Controller::cleanup(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return process::dispatch(
+      process.get(),
+      &ControllerProcess::cleanup,
+      containerId,
+      cgroup);
+}
+
+
+ControllerProcess::ControllerProcess(const Flags& _flags) : flags(_flags) {}
+
+
+Future<Nothing> ControllerProcess::recover(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return Nothing();
+}
+
+
+Future<Nothing> ControllerProcess::prepare(
+    const ContainerID& containerId,
+    const string& cgroup,
+    const mesos::slave::ContainerConfig& containerConfig)
+{
+  return Nothing();
+}
+
+
+Future<Nothing> ControllerProcess::isolate(
+    const ContainerID& containerId,
+    const string& cgroup,
+    pid_t pid)
+{
+  return Nothing();
+}
+
+
+Future<ContainerLimitation> ControllerProcess::watch(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return Future<ContainerLimitation>();
+}
+
+
+Future<Nothing> ControllerProcess::update(
+    const ContainerID& containerId,
+    const string& cgroup,
+    const Resources& resourceRequests,
+    const google::protobuf::Map<string, Value::Scalar>& resourceLimits)
+{
+  return Nothing();
+}
+
+
+Future<ResourceStatistics> ControllerProcess::usage(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return ResourceStatistics();
+}
+
+
+Future<ContainerStatus> ControllerProcess::status(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return ContainerStatus();
+}
+
+
+Future<Nothing> ControllerProcess::cleanup(
+    const ContainerID& containerId,
+    const string& cgroup)
+{
+  return Nothing();
+}
+
+} // namespace slave {
+} // namespace internal {
+} // namespace mesos {
diff --git a/src/slave/containerizer/mesos/isolators/cgroups2/controller.hpp 
b/src/slave/containerizer/mesos/isolators/cgroups2/controller.hpp
index bafc0e8b4..b38628e38 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups2/controller.hpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups2/controller.hpp
@@ -14,7 +14,143 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef __CONTROLLERS_HPP__
-#define __CONTROLLERS_HPP__
+#ifndef __CONTROLLER_HPP__
+#define __CONTROLLER_HPP__
 
-#endif // __CONTROLLERS_HPP__
\ No newline at end of file
+#include <mesos/slave/isolator.hpp>
+
+#include <process/owned.hpp>
+#include <process/process.hpp>
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+#include "slave/flags.hpp"
+
+namespace mesos {
+namespace internal {
+namespace slave {
+
+class ControllerProcess;
+
+// Abstraction for a cgroups v2 controller.
+class Controller
+{
+public:
+  static Try<process::Owned<Controller>> create(
+      const Flags& flags,
+      const std::string& name);
+
+  // Copied from: src/slave/containerizer/mesos/isolators/cgroups/subsystem.hpp
+  // We have unique ownership of the wrapped process and
+  // enforce that objects of this class cannot be copied.
+  //
+  // TODO(bbannier): Remove this once MESOS-5122 is resolved.
+  Controller(const Controller&) = delete;
+  Controller& operator=(const Controller&) = delete;
+
+  ~Controller();
+
+  // Name of the controller.
+  std::string name() const;
+
+  process::Future<Nothing> recover(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  process::Future<Nothing> prepare(
+      const ContainerID& containerId,
+      const std::string& cgroup,
+      const mesos::slave::ContainerConfig& containerConfig);
+
+  process::Future<Nothing> isolate(
+      const ContainerID& containerId,
+      const std::string& cgroup,
+      pid_t pid);
+
+  process::Future<mesos::slave::ContainerLimitation> watch(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  process::Future<Nothing> update(
+      const ContainerID& containerId,
+      const std::string& cgroup,
+      const Resources& resourceRequests,
+      const google::protobuf::Map<
+          std::string, Value::Scalar>& resourceLimits = {});
+
+  process::Future<ResourceStatistics> usage(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  process::Future<ContainerStatus> status(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  process::Future<Nothing> cleanup(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+private:
+  explicit Controller(process::Owned<ControllerProcess> process);
+
+  process::Owned<ControllerProcess> process;
+};
+
+
+class ControllerProcess : public process::Process<ControllerProcess>
+{
+public:
+  ~ControllerProcess() override {}
+
+  virtual std::string name() const = 0;
+
+  virtual process::Future<Nothing> recover(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  virtual process::Future<Nothing> prepare(
+      const ContainerID& containerId,
+      const std::string& cgroup,
+      const mesos::slave::ContainerConfig& containerConfig);
+
+  virtual process::Future<Nothing> isolate(
+      const ContainerID& containerId,
+      const std::string& cgroup,
+      pid_t pid);
+
+  virtual process::Future<mesos::slave::ContainerLimitation> watch(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  virtual process::Future<Nothing> update(
+      const ContainerID& containerId,
+      const std::string& cgroup,
+      const Resources& resourceRequests,
+      const google::protobuf::Map<
+          std::string, Value::Scalar>& resourceLimits = {});
+
+  virtual process::Future<ResourceStatistics> usage(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  virtual process::Future<ContainerStatus> status(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+  virtual process::Future<Nothing> cleanup(
+      const ContainerID& containerId,
+      const std::string& cgroup);
+
+protected:
+  ControllerProcess(const Flags& flags);
+
+  // Flags used to launch the agent.
+  const Flags flags;
+};
+
+} // namespace slave {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __CONTROLLER_HPP__

Reply via email to