Automatically loaded all the local enabled cgroups subsystems.

When `cgroups/all` is specified in the agent flag `--isolation`, we
will automatically load all the local enabled cgroups subsystems in
the cgroups isolator.

Review: https://reviews.apache.org/r/67343/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/b8a1c083
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/b8a1c083
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/b8a1c083

Branch: refs/heads/master
Commit: b8a1c083083994743d224c33155761cc82a20f8b
Parents: 11f1a7c
Author: Qian Zhang <[email protected]>
Authored: Mon Jun 18 23:23:47 2018 -0700
Committer: Gilbert Song <[email protected]>
Committed: Mon Jun 18 23:36:50 2018 -0700

----------------------------------------------------------------------
 src/slave/containerizer/mesos/containerizer.cpp |   1 +
 .../mesos/isolators/cgroups/cgroups.cpp         | 104 +++++++++++++------
 2 files changed, 75 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/b8a1c083/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp 
b/src/slave/containerizer/mesos/containerizer.cpp
index 7b3b0d3..98129d0 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -382,6 +382,7 @@ Try<MesosContainerizer*> MesosContainerizer::create(
 #endif // __WINDOWS__
 
 #ifdef __linux__
+    {"cgroups/all", &CgroupsIsolatorProcess::create},
     {"cgroups/blkio", &CgroupsIsolatorProcess::create},
     {"cgroups/cpu", &CgroupsIsolatorProcess::create},
     {"cgroups/cpuset", &CgroupsIsolatorProcess::create},

http://git-wip-us.apache.org/repos/asf/mesos/blob/b8a1c083/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp 
b/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
index 215e324..6d14672 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
@@ -14,6 +14,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <set>
 #include <vector>
 
 #include <process/collect.hpp>
@@ -46,6 +47,7 @@ using process::Future;
 using process::Owned;
 using process::PID;
 
+using std::set;
 using std::string;
 using std::vector;
 
@@ -89,52 +91,94 @@ Try<Isolator*> CgroupsIsolatorProcess::create(const Flags& 
flags)
     {"pids", CGROUP_SUBSYSTEM_PIDS_NAME},
   };
 
-  foreach (string isolator, strings::tokenize(flags.isolation, ",")) {
-    if (!strings::startsWith(isolator, "cgroups/")) {
-      // Skip when the isolator is not related to cgroups.
-      continue;
-    }
+  // All the subsystems currently supported by Mesos.
+  set<string> supportedSubsystems;
+  foreachvalue (const string& subsystemName, isolatorMap) {
+    supportedSubsystems.insert(subsystemName);
+  }
 
-    isolator = strings::remove(isolator, "cgroups/", strings::Mode::PREFIX);
+  // The subsystems to be loaded.
+  set<string> subsystemSet;
 
-    if (!isolatorMap.contains(isolator)) {
+  if (strings::contains(flags.isolation, "cgroups/all")) {
+    Try<set<string>> enabledSubsystems = cgroups::subsystems();
+    if (enabledSubsystems.isError()) {
       return Error(
-          "Unknown or unsupported isolator 'cgroups/" + isolator + "'");
+          "Failed to get the enabled subsystems: " + 
enabledSubsystems.error());
     }
 
-    // A cgroups isolator name may map to multiple subsystems. We need to
-    // convert the isolator name to its associated subsystems.
-    foreach (const string& subsystemName, isolatorMap.get(isolator)) {
-      if (hierarchies.contains(subsystemName)) {
-        // Skip when the subsystem exists.
+    foreach (const string& subsystemName, enabledSubsystems.get()) {
+      if (supportedSubsystems.count(subsystemName) == 0) {
+        // Skip when the subsystem is not supported by Mesos yet.
+        LOG(WARNING) << "Cannot automatically load the subsystem '"
+                     << subsystemName << "' because it is not "
+                     << "supported by Mesos cgroups isolator yet";
         continue;
       }
 
-      // Prepare hierarchy if it does not exist.
-      Try<string> hierarchy = cgroups::prepare(
-          flags.cgroups_hierarchy,
-          subsystemName,
-          flags.cgroups_root);
+      subsystemSet.insert(subsystemName);
+    }
 
-      if (hierarchy.isError()) {
-        return Error(
-            "Failed to prepare hierarchy for the subsystem '" + subsystemName +
-            "': " + hierarchy.error());
+    if (subsystemSet.empty()) {
+      return Error("No subsystems are enabled by the kernel");
+    }
+
+    LOG(INFO) << "Automatically loading subsystems: "
+              << stringify(subsystemSet);
+  } else {
+    foreach (string isolator, strings::tokenize(flags.isolation, ",")) {
+      if (!strings::startsWith(isolator, "cgroups/")) {
+        // Skip when the isolator is not related to cgroups.
+        continue;
       }
 
-      // Create and load the subsystem.
-      Try<Owned<Subsystem>> subsystem =
-        Subsystem::create(flags, subsystemName, hierarchy.get());
+      isolator = strings::remove(isolator, "cgroups/", strings::Mode::PREFIX);
 
-      if (subsystem.isError()) {
+      if (!isolatorMap.contains(isolator)) {
         return Error(
-            "Failed to create subsystem '" + subsystemName + "': " +
-            subsystem.error());
+            "Unknown or unsupported isolator 'cgroups/" + isolator + "'");
+      }
+
+      // A cgroups isolator name may map to multiple subsystems. We need to
+      // convert the isolator name to its associated subsystems.
+      foreach (const string& subsystemName, isolatorMap.get(isolator)) {
+        subsystemSet.insert(subsystemName);
       }
+    }
+  }
 
-      subsystems.put(hierarchy.get(), subsystem.get());
-      hierarchies.put(subsystemName, hierarchy.get());
+  CHECK(!subsystemSet.empty());
+
+  foreach (const string& subsystemName, subsystemSet) {
+    if (hierarchies.contains(subsystemName)) {
+      // Skip when the subsystem exists.
+      continue;
+    }
+
+    // Prepare hierarchy if it does not exist.
+    Try<string> hierarchy = cgroups::prepare(
+        flags.cgroups_hierarchy,
+        subsystemName,
+        flags.cgroups_root);
+
+    if (hierarchy.isError()) {
+      return Error(
+          "Failed to prepare hierarchy for the subsystem '" + subsystemName +
+          "': " + hierarchy.error());
+    }
+
+    // Create and load the subsystem.
+    Try<Owned<Subsystem>> subsystem =
+      Subsystem::create(flags, subsystemName, hierarchy.get());
+
+    if (subsystem.isError()) {
+      return Error(
+          "Failed to create subsystem '" + subsystemName + "': " +
+          subsystem.error());
     }
+
+    subsystems.put(hierarchy.get(), subsystem.get());
+    hierarchies.put(subsystemName, hierarchy.get());
   }
 
   Owned<MesosIsolatorProcess> process(

Reply via email to