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 <[email protected]> Authored: Mon Apr 17 10:06:12 2017 +0800 Committer: Haosdent Huang <[email protected]> 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;
