You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/08/20 21:18:33 UTC
mesos git commit: Implemented `DevicesSubsystem`.
Repository: mesos
Updated Branches:
refs/heads/master ee4f8a251 -> 67c36f6f9
Implemented `DevicesSubsystem`.
Review: https://reviews.apache.org/r/49854/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/67c36f6f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/67c36f6f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/67c36f6f
Branch: refs/heads/master
Commit: 67c36f6f9071f970bd913b38838248adb9c109ab
Parents: ee4f8a2
Author: haosdent huang <ha...@gmail.com>
Authored: Sat Aug 20 09:40:25 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Sat Aug 20 14:18:16 2016 -0700
----------------------------------------------------------------------
src/CMakeLists.txt | 1 +
src/Makefile.am | 2 +
.../mesos/isolators/cgroups/cgroups.cpp | 1 +
.../mesos/isolators/cgroups/constants.hpp | 1 +
.../mesos/isolators/cgroups/subsystem.cpp | 2 +
.../isolators/cgroups/subsystems/devices.cpp | 165 +++++++++++++++++++
.../isolators/cgroups/subsystems/devices.hpp | 67 ++++++++
7 files changed, 239 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 85eb2b8..ff51705 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -169,6 +169,7 @@ set(LINUX_SRC
slave/containerizer/mesos/isolators/cgroups/subsystem.cpp
slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.cpp
slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.cpp
+ slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp
slave/containerizer/mesos/isolators/docker/runtime.cpp
slave/containerizer/mesos/isolators/docker/volume/driver.cpp
slave/containerizer/mesos/isolators/docker/volume/isolator.cpp
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index d0f937d..61c941f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1053,6 +1053,7 @@ MESOS_LINUX_FILES = \
slave/containerizer/mesos/isolators/cgroups/subsystem.cpp \
slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.cpp \
slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.cpp \
+ slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp \
slave/containerizer/mesos/isolators/docker/runtime.cpp \
slave/containerizer/mesos/isolators/docker/volume/isolator.cpp \
slave/containerizer/mesos/isolators/filesystem/linux.cpp \
@@ -1088,6 +1089,7 @@ MESOS_LINUX_FILES += \
slave/containerizer/mesos/isolators/cgroups/subsystem.hpp \
slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.hpp \
slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.hpp \
+ slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp \
slave/containerizer/mesos/isolators/docker/runtime.hpp \
slave/containerizer/mesos/isolators/docker/volume/isolator.hpp \
slave/containerizer/mesos/isolators/filesystem/linux.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/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 1b84a56..5be2b71 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
@@ -77,6 +77,7 @@ Try<Isolator*> CgroupsIsolatorProcess::create(const Flags& flags)
multihashmap<string, string> isolatorMap = {
{"cpu", CGROUP_SUBSYSTEM_CPU_NAME},
{"cpu", CGROUP_SUBSYSTEM_CPUACCT_NAME},
+ {"devices", CGROUP_SUBSYSTEM_DEVICES_NAME},
};
foreach (string isolator, strings::tokenize(flags.isolation, ",")) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/src/slave/containerizer/mesos/isolators/cgroups/constants.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/constants.hpp b/src/slave/containerizer/mesos/isolators/cgroups/constants.hpp
index 3146cc6..4a7b556 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/constants.hpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/constants.hpp
@@ -41,6 +41,7 @@ const Bytes MIN_MEMORY = Megabytes(32);
// Subsystem names.
const std::string CGROUP_SUBSYSTEM_CPU_NAME = "cpu";
const std::string CGROUP_SUBSYSTEM_CPUACCT_NAME = "cpuacct";
+const std::string CGROUP_SUBSYSTEM_DEVICES_NAME = "devices";
} // namespace slave {
} // namespace internal {
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/src/slave/containerizer/mesos/isolators/cgroups/subsystem.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/subsystem.cpp b/src/slave/containerizer/mesos/isolators/cgroups/subsystem.cpp
index 9789cf6..df701d2 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/subsystem.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/subsystem.cpp
@@ -22,6 +22,7 @@
#include "slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.hpp"
#include "slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.hpp"
+#include "slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp"
using process::Future;
using process::Owned;
@@ -41,6 +42,7 @@ Try<Owned<Subsystem>> Subsystem::create(
creators = {
{CGROUP_SUBSYSTEM_CPU_NAME, &CpuSubsystem::create},
{CGROUP_SUBSYSTEM_CPUACCT_NAME, &CpuacctSubsystem::create},
+ {CGROUP_SUBSYSTEM_DEVICES_NAME, &DevicesSubsystem::create},
};
if (!creators.contains(name)) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp
new file mode 100644
index 0000000..0e83aa1
--- /dev/null
+++ b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp
@@ -0,0 +1,165 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <process/id.hpp>
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+#include "linux/cgroups.hpp"
+
+#include "slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp"
+
+using cgroups::devices::Entry;
+
+using process::Failure;
+using process::Future;
+using process::Owned;
+
+using std::string;
+
+namespace mesos {
+namespace internal {
+namespace slave {
+
+// The default list of devices to whitelist when device isolation is
+// turned on. The full list of devices can be found here:
+// https://www.kernel.org/doc/Documentation/devices.txt
+//
+// Device whitelisting is described here:
+// https://www.kernel.org/doc/Documentation/cgroup-v1/devices.txt
+static const char* DEFAULT_WHITELIST_ENTRIES[] = {
+ "c *:* m", // Make new character devices.
+ "b *:* m", // Make new block devices.
+ "c 5:1 rwm", // /dev/console
+ "c 4:0 rwm", // /dev/tty0
+ "c 4:1 rwm", // /dev/tty1
+ "c 136:* rwm", // /dev/pts/*
+ "c 5:2 rwm", // /dev/ptmx
+ "c 10:200 rwm", // /dev/net/tun
+ "c 1:3 rwm", // /dev/null
+ "c 1:5 rwm", // /dev/zero
+ "c 1:7 rwm", // /dev/full
+ "c 5:0 rwm", // /dev/tty
+ "c 1:9 rwm", // /dev/urandom
+ "c 1:8 rwm", // /dev/random
+};
+
+
+Try<Owned<Subsystem>> DevicesSubsystem::create(
+ const Flags& flags,
+ const string& hierarchy)
+{
+ return Owned<Subsystem>(new DevicesSubsystem(flags, hierarchy));
+}
+
+
+DevicesSubsystem::DevicesSubsystem(
+ const Flags& _flags,
+ const string& _hierarchy)
+ : ProcessBase(process::ID::generate("cgroups-devices-subsystem")),
+ Subsystem(_flags, _hierarchy) {}
+
+
+Future<Nothing> DevicesSubsystem::recover(const ContainerID& containerId)
+{
+ if (containerIds.contains(containerId)) {
+ return Failure(
+ "The subsystem '" + name() + "' of container " +
+ stringify(containerId) + " has already been recovered");
+ }
+
+ containerIds.insert(containerId);
+
+ return Nothing();
+}
+
+
+Future<Nothing> DevicesSubsystem::prepare(const ContainerID& containerId)
+{
+ if (containerIds.contains(containerId)) {
+ return Failure("The subsystem '" + name() + "' has already been prepared");
+ }
+
+ // When a devices cgroup is first created, its whitelist inherits
+ // all devices from its parent's whitelist (i.e., "a *:* rwm" by
+ // default). In theory, we should be able to add and remove devices
+ // from the whitelist by writing to the respective `devices.allow`
+ // and `devices.deny` files associated with the cgroup. However, the
+ // semantics of the whitelist are such that writing to the deny file
+ // will only remove entries in the whitelist that are explicitly
+ // listed in there (i.e., denying "b 1:3 rwm" when the whitelist
+ // only contains "a *:* rwm" will not modify the whitelist because
+ // "b 1:3 rwm" is not explicitly listed). Although the whitelist
+ // doesn't change, access to the device is still denied as expected
+ // (there is just no way of querying the system to detect it).
+ // Because of this, we first deny access to all devices and
+ // selectively add some back in so we can control the entries in the
+ // whitelist explicitly.
+ cgroups::devices::Entry all;
+ all.selector.type = Entry::Selector::Type::ALL;
+ all.selector.major = None();
+ all.selector.minor = None();
+ all.access.read = true;
+ all.access.write = true;
+ all.access.mknod = true;
+
+ Try<Nothing> deny = cgroups::devices::deny(
+ hierarchy,
+ path::join(flags.cgroups_root, containerId.value()),
+ all);
+
+ if (deny.isError()) {
+ return Failure("Failed to deny all devices: " + deny.error());
+ }
+
+ foreach (const char* _entry, DEFAULT_WHITELIST_ENTRIES) {
+ Try<cgroups::devices::Entry> entry =
+ cgroups::devices::Entry::parse(_entry);
+
+ CHECK_SOME(entry);
+
+ Try<Nothing> allow = cgroups::devices::allow(
+ hierarchy, path::join(flags.cgroups_root, containerId.value()),
+ entry.get());
+
+ if (allow.isError()) {
+ return Failure("Failed to whitelist default device "
+ "'" + stringify(entry.get()) + "': " + allow.error());
+ }
+ }
+
+ containerIds.insert(containerId);
+
+ return Nothing();
+}
+
+
+Future<Nothing> DevicesSubsystem::cleanup(const ContainerID& containerId)
+{
+ // Multiple calls may occur during test clean up.
+ if (!containerIds.contains(containerId)) {
+ return Failure("Unknown container");
+ }
+
+ containerIds.erase(containerId);
+
+ return Nothing();
+}
+
+} // namespace slave {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/67c36f6f/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp
new file mode 100644
index 0000000..b5d5ed2
--- /dev/null
+++ b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp
@@ -0,0 +1,67 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __CGROUPS_ISOLATOR_SUBSYSTEMS_DEVICES_HPP__
+#define __CGROUPS_ISOLATOR_SUBSYSTEMS_DEVICES_HPP__
+
+#include <string>
+
+#include <process/owned.hpp>
+
+#include <stout/hashset.hpp>
+#include <stout/try.hpp>
+
+#include "slave/flags.hpp"
+
+#include "slave/containerizer/mesos/isolators/cgroups/constants.hpp"
+#include "slave/containerizer/mesos/isolators/cgroups/subsystem.hpp"
+
+namespace mesos {
+namespace internal {
+namespace slave {
+
+/**
+ * Represent cgroups devices subsystem.
+ */
+class DevicesSubsystem: public Subsystem
+{
+public:
+ static Try<process::Owned<Subsystem>> create(
+ const Flags& flags,
+ const std::string& hierarchy);
+
+ virtual ~DevicesSubsystem() {}
+
+ virtual std::string name() const
+ {
+ return CGROUP_SUBSYSTEM_DEVICES_NAME;
+ }
+
+ virtual process::Future<Nothing> prepare(const ContainerID& containerId);
+ virtual process::Future<Nothing> recover(const ContainerID& containerId);
+ virtual process::Future<Nothing> cleanup(const ContainerID& containerId);
+
+private:
+ DevicesSubsystem(const Flags& flags, const std::string& hierarchy);
+
+ hashset<ContainerID> containerIds;
+};
+
+} // namespace slave {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __CGROUPS_ISOLATOR_SUBSYSTEMS_DEVICES_HPP__