You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ha...@apache.org on 2017/04/17 03:56:52 UTC
mesos git commit: Allowed whitelist additional devices in cgroups
devices subsystem.
Repository: mesos
Updated Branches:
refs/heads/master d61db9157 -> ff9ed0c83
Allowed whitelist additional devices in cgroups devices subsystem.
Review: https://reviews.apache.org/r/58337/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ff9ed0c8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ff9ed0c8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ff9ed0c8
Branch: refs/heads/master
Commit: ff9ed0c831c347204d065c5f39e5c8bb86f38514
Parents: d61db91
Author: Zhongbo Tian <wi...@gmail.com>
Authored: Mon Apr 17 10:06:12 2017 +0800
Committer: Haosdent Huang <ha...@apache.org>
Committed: Mon Apr 17 11:56:36 2017 +0800
----------------------------------------------------------------------
docs/configuration.md | 21 ++++
.../isolators/cgroups/subsystems/devices.cpp | 111 ++++++++++++++++---
.../isolators/cgroups/subsystems/devices.hpp | 9 +-
src/slave/flags.cpp | 16 +++
src/slave/flags.hpp | 1 +
5 files changed, 140 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/ff9ed0c8/docs/configuration.md
----------------------------------------------------------------------
diff --git a/docs/configuration.md b/docs/configuration.md
index 159f946..3c9aabc 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -1153,6 +1153,27 @@ effect only when the <code>--cgroups_net_cls_primary_handle</code> is set.
</tr>
<tr>
<td>
+ --cgroups_whitelist_devices
+ </td>
+ <td>
+JSON array representing the devices that will be additionally
+whitelisted by cgroups devices subsystem. This will take effect
+only when <code>cgroups/devices</code> is set in <code>--isolation</code> flag.
+<p/>
+Example:
+<pre><code>[
+ {
+ "path": "/path/to/device",
+ "read_access": true,
+ "write_access": false,
+ "mknod_access": false
+ }
+]
+</code></pre>
+ </td>
+</tr>
+<tr>
+ <td>
--cgroups_root=VALUE
</td>
<td>
http://git-wip-us.apache.org/repos/asf/mesos/blob/ff9ed0c8/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
index 9b5cf83..d96e716 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp
@@ -14,12 +14,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <sys/stat.h>
+
#include <process/id.hpp>
#include <stout/nothing.hpp>
#include <stout/try.hpp>
-
-#include "linux/cgroups.hpp"
+#include <stout/os.hpp>
#include "slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp"
@@ -30,6 +31,7 @@ using process::Future;
using process::Owned;
using std::string;
+using std::vector;
namespace mesos {
namespace internal {
@@ -63,15 +65,98 @@ Try<Owned<Subsystem>> DevicesSubsystem::create(
const Flags& flags,
const string& hierarchy)
{
- return Owned<Subsystem>(new DevicesSubsystem(flags, hierarchy));
+ vector<cgroups::devices::Entry> whitelistDeviceEntries;
+
+ foreach (const char* _entry, DEFAULT_WHITELIST_ENTRIES) {
+ Try<cgroups::devices::Entry> entry =
+ cgroups::devices::Entry::parse(_entry);
+
+ CHECK_SOME(entry);
+ whitelistDeviceEntries.push_back(entry.get());
+ }
+
+ if (flags.cgroups_whitelist_devices.isSome()) {
+ foreach (const JSON::Value& value,
+ flags.cgroups_whitelist_devices.get().values) {
+ if (!value.is<JSON::Object>()) {
+ return Error(
+ "Failed to parse whitelist devices '" +
+ stringify(flags.cgroups_whitelist_devices.get()) +
+ "' in flag --cgroups_whitelist_devices");
+ }
+
+ JSON::Object object = value.as<JSON::Object>();
+
+ Result<JSON::String> path = object.at<JSON::String>("path");
+ if (!path.isSome()) {
+ return Error("Malformed whitelist device entry '" +
+ stringify(object) + "'");
+ }
+
+ Result<JSON::Boolean> _readAccess =
+ object.at<JSON::Boolean>("read_access");
+
+ Result<JSON::Boolean> _writeAccess =
+ object.at<JSON::Boolean>("write_access");
+
+ Result<JSON::Boolean> _mknodAccess =
+ object.at<JSON::Boolean>("mknod_access");
+
+ bool readAccess = (_readAccess.isSome() && _readAccess->value);
+ bool writeAccess = (_readAccess.isSome() && _readAccess->value);
+ bool mknodAccess = (_readAccess.isSome() && _readAccess->value);
+
+ if (!(readAccess || writeAccess || mknodAccess)) {
+ return Error("Could not whitelist device '" + path->value
+ + "' without any access privileges");
+ }
+
+ Try<dev_t> device = os::stat::rdev(path->value);
+ if (device.isError()) {
+ return Error("Failed to obtain device ID for '" + path->value +
+ "': " + device.error());
+ }
+
+ Try<mode_t> mode = os::stat::mode(path->value);
+ if (mode.isError()) {
+ return Error("Failed to obtain device mode for '" + path->value +
+ "': " + mode.error());
+ }
+
+ Entry::Selector::Type type;
+ if (S_ISBLK(mode.get())) {
+ type = Entry::Selector::Type::BLOCK;
+ } else if (S_ISCHR(mode.get())) {
+ type = Entry::Selector::Type::CHARACTER;
+ } else {
+ return Error("Failed to determine device type for '" + path->value +
+ "'");
+ }
+
+ cgroups::devices::Entry entry;
+ entry.selector.type = type;
+ entry.selector.major = major(device.get());
+ entry.selector.minor = minor(device.get());
+ entry.access.read = readAccess;
+ entry.access.write = writeAccess;
+ entry.access.mknod = mknodAccess;
+
+ whitelistDeviceEntries.push_back(entry);
+ }
+ }
+
+ return Owned<Subsystem>(
+ new DevicesSubsystem(flags, hierarchy, whitelistDeviceEntries));
}
DevicesSubsystem::DevicesSubsystem(
const Flags& _flags,
- const string& _hierarchy)
+ const string& _hierarchy,
+ const vector<cgroups::devices::Entry>& _whitelistDeviceEntries)
: ProcessBase(process::ID::generate("cgroups-devices-subsystem")),
- Subsystem(_flags, _hierarchy) {}
+ Subsystem(_flags, _hierarchy),
+ whitelistDeviceEntries(_whitelistDeviceEntries) {}
Future<Nothing> DevicesSubsystem::recover(
@@ -127,20 +212,12 @@ Future<Nothing> DevicesSubsystem::prepare(
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,
- cgroup,
- entry.get());
+ foreach (const cgroups::devices::Entry& entry, whitelistDeviceEntries) {
+ Try<Nothing> allow = cgroups::devices::allow(hierarchy, cgroup, entry);
if (allow.isError()) {
- return Failure("Failed to whitelist default device "
- "'" + stringify(entry.get()) + "': " + allow.error());
+ return Failure("Failed to whitelist device "
+ "'" + stringify(entry) + "': " + allow.error());
}
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/ff9ed0c8/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
index ca27271..4ab224e 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.hpp
@@ -18,12 +18,15 @@
#define __CGROUPS_ISOLATOR_SUBSYSTEMS_DEVICES_HPP__
#include <string>
+#include <vector>
#include <process/owned.hpp>
#include <stout/hashset.hpp>
#include <stout/try.hpp>
+#include "linux/cgroups.hpp"
+
#include "slave/flags.hpp"
#include "slave/containerizer/mesos/isolators/cgroups/constants.hpp"
@@ -63,9 +66,13 @@ public:
const std::string& cgroup);
private:
- DevicesSubsystem(const Flags& flags, const std::string& hierarchy);
+ DevicesSubsystem(
+ const Flags& flags,
+ const std::string& hierarchy,
+ const std::vector<cgroups::devices::Entry>& whitelistDeviceEntries);
hashset<ContainerID> containerIds;
+ std::vector<cgroups::devices::Entry> whitelistDeviceEntries;
};
} // namespace slave {
http://git-wip-us.apache.org/repos/asf/mesos/blob/ff9ed0c8/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index c50e43c..f22837c 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -454,6 +454,22 @@ mesos::internal::slave::Flags::Flags()
"handles that can be used with the primary handle. This will take\n"
"effect only when the `--cgroups_net_cls_primary_handle is set.");
+ add(&Flags::cgroups_whitelist_devices,
+ "cgroups_whitelist_devices",
+ "JSON array representing the devices that will be additionally\n"
+ "whitelisted by cgroups devices subsystem. This will take effect\n"
+ "only when `cgroups/devices` is set in `--isolation` flag.\n"
+ "Example:\n"
+ "[\n"
+ " {\n"
+ " \"path\": \"/path/to/device\",\n"
+ " \"read_access\": true,\n"
+ " \"write_access\": false,\n"
+ " \"mknod_access\": false\n"
+ " }\n"
+ "]\n"
+ );
+
add(&Flags::agent_subsystems,
"agent_subsystems",
flags::DeprecatedName("slave_subsystems"),
http://git-wip-us.apache.org/repos/asf/mesos/blob/ff9ed0c8/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index c7a4604..38c05af 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -99,6 +99,7 @@ public:
bool cgroups_cpu_enable_pids_and_tids_count;
Option<std::string> cgroups_net_cls_primary_handle;
Option<std::string> cgroups_net_cls_secondary_handles;
+ Option<JSON::Array> cgroups_whitelist_devices;
Option<std::string> agent_subsystems;
Option<std::vector<unsigned int>> nvidia_gpu_devices;
Option<std::string> perf_events;