Repository: mesos Updated Branches: refs/heads/master d7c0873e7 -> b8b9255eb
Use IDLE scheduling for revocable CPU in cgroups isolator. Review: https://reviews.apache.org/r/34310 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/b8b9255e Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/b8b9255e Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/b8b9255e Branch: refs/heads/master Commit: b8b9255ebeb1ae6ac8e854f1267c04915039f4bd Parents: 6de149e Author: Ian Downes <[email protected]> Authored: Fri May 15 18:03:45 2015 -0700 Committer: Ian Downes <[email protected]> Committed: Fri May 29 14:33:21 2015 -0700 ---------------------------------------------------------------------- .../isolators/cgroups/cpushare.cpp | 21 +++++++ .../isolators/cgroups/cpushare.hpp | 1 + src/slave/flags.cpp | 7 +++ src/slave/flags.hpp | 1 + src/tests/isolator_tests.cpp | 65 ++++++++++++++++++++ 5 files changed, 95 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/b8b9255e/src/slave/containerizer/isolators/cgroups/cpushare.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/isolators/cgroups/cpushare.cpp b/src/slave/containerizer/isolators/cgroups/cpushare.cpp index e3b5e2a..214ba23 100644 --- a/src/slave/containerizer/isolators/cgroups/cpushare.cpp +++ b/src/slave/containerizer/isolators/cgroups/cpushare.cpp @@ -40,6 +40,7 @@ #include <stout/try.hpp> #include "linux/cgroups.hpp" +#include "linux/sched.hpp" #include "slave/flags.hpp" @@ -332,6 +333,25 @@ Future<Nothing> CgroupsCpushareIsolatorProcess::isolate( } } + // NOTE: This only sets the executor and descendants to IDLE policy + // if the initial CPU resource is revocable and not if initial CPU + // is non-revocable but subsequent updates include revocable CPU. + if (info->resources.isSome() && + info->resources.get().revocable().cpus().isSome() && + flags.revocable_cpu_low_priority) { + Try<Nothing> set = sched::policy::set(sched::Policy::IDLE, pid); + if (set.isError()) { + return Failure("Failed to set SCHED_IDLE for pid " + stringify(pid) + + " in container '" + stringify(containerId) + "'" + + " with revocable CPU: " + set.error()); + } + + LOG(INFO) << "Set scheduling policy to SCHED_IDLE for pid " << pid + << " in container '" << containerId << "' because it includes '" + << info->resources.get().revocable().cpus().get() + << "' revocable CPU"; + } + return Nothing(); } @@ -367,6 +387,7 @@ Future<Nothing> CgroupsCpushareIsolatorProcess::update( } Info* info = CHECK_NOTNULL(infos[containerId]); + info->resources = resources; double cpus = resources.cpus().get(); http://git-wip-us.apache.org/repos/asf/mesos/blob/b8b9255e/src/slave/containerizer/isolators/cgroups/cpushare.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/isolators/cgroups/cpushare.hpp b/src/slave/containerizer/isolators/cgroups/cpushare.hpp index ff4a9db..14adf0a 100644 --- a/src/slave/containerizer/isolators/cgroups/cpushare.hpp +++ b/src/slave/containerizer/isolators/cgroups/cpushare.hpp @@ -89,6 +89,7 @@ private: const ContainerID containerId; const std::string cgroup; Option<pid_t> pid; + Option<Resources> resources; process::Promise<mesos::slave::Limitation> limitation; }; http://git-wip-us.apache.org/repos/asf/mesos/blob/b8b9255e/src/slave/flags.cpp ---------------------------------------------------------------------- diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp index 6b7c61e..7f2e1e8 100644 --- a/src/slave/flags.cpp +++ b/src/slave/flags.cpp @@ -236,6 +236,13 @@ mesos::internal::slave::Flags::Flags() "Duration of a perf stat sample. The duration must be less\n" "that the perf_interval.", Seconds(10)); + + add(&Flags::revocable_cpu_low_priority, + "revocable_cpu_low_priority", + "Run containers with revocable CPU at a lower priority than\n" + "normal containers (non-revocable cpu). Currently only\n" + "supported by the cgroups/cpu isolator.", + true); #endif add(&Flags::credential, http://git-wip-us.apache.org/repos/asf/mesos/blob/b8b9255e/src/slave/flags.hpp ---------------------------------------------------------------------- diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp index 944ed79..e84efc1 100644 --- a/src/slave/flags.hpp +++ b/src/slave/flags.hpp @@ -74,6 +74,7 @@ public: Option<std::string> perf_events; Duration perf_interval; Duration perf_duration; + bool revocable_cpu_low_priority; #endif Option<Path> credential; Option<std::string> containerizer_path; http://git-wip-us.apache.org/repos/asf/mesos/blob/b8b9255e/src/tests/isolator_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/isolator_tests.cpp b/src/tests/isolator_tests.cpp index 24c71b7..acb1404 100644 --- a/src/tests/isolator_tests.cpp +++ b/src/tests/isolator_tests.cpp @@ -41,6 +41,7 @@ #ifdef __linux__ #include "linux/ns.hpp" +#include "linux/sched.hpp" #endif // __linux__ #include "master/master.hpp" @@ -365,6 +366,70 @@ TYPED_TEST(CpuIsolatorTest, SystemCpuUsage) #ifdef __linux__ +class RevocableCpuIsolatorTest : public MesosTest {}; + + +TEST_F(RevocableCpuIsolatorTest, ROOT_CGROUPS_RevocableCpu) +{ + slave::Flags flags; + + Try<Isolator*> isolator = CgroupsCpushareIsolatorProcess::create(flags); + CHECK_SOME(isolator); + + Try<Launcher*> launcher = PosixLauncher::create(flags); + + // Include revocable CPU in the executor's resources. + Resource cpu = Resources::parse("cpus", "1", "*").get(); + cpu.mutable_revocable(); + + ExecutorInfo executorInfo; + executorInfo.add_resources()->CopyFrom(cpu); + + ContainerID containerId; + containerId.set_value(UUID::random().toString()); + + AWAIT_READY(isolator.get()->prepare( + containerId, + executorInfo, + os::getcwd(), + None())); + + vector<string> argv{"sleep", "100"}; + + Try<pid_t> pid = launcher.get()->fork( + containerId, + "/bin/sleep", + argv, + Subprocess::PATH("/dev/null"), + Subprocess::PATH("/dev/null"), + Subprocess::PATH("/dev/null"), + None(), + None(), + None()); + + ASSERT_SOME(pid); + + AWAIT_READY(isolator.get()->isolate(containerId, pid.get())); + + // Check the executor has its scheduling policy set to IDLE. + EXPECT_SOME_EQ(sched::Policy::IDLE, sched::policy::get(pid.get())); + + // Kill the container and clean up. + Future<Option<int>> status = process::reap(pid.get()); + + AWAIT_READY(launcher.get()->destroy(containerId)); + + AWAIT_READY(status); + + AWAIT_READY(isolator.get()->cleanup(containerId)); + + delete isolator.get(); + delete launcher.get(); +} +#endif // __linux__ + + +#ifdef __linux__ class LimitedCpuIsolatorTest : public MesosTest {};
