You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by id...@apache.org on 2014/04/29 19:16:48 UTC
git commit: Rename CgroupsLauncher to LinuxLauncher.
Repository: mesos
Updated Branches:
refs/heads/master 12511606a -> b1b2b4cc9
Rename CgroupsLauncher to LinuxLauncher.
This is a rename only; there are no code changes but this facilitates a
follow on review which will modify the launcher to support both Linux
cgroups and Linux namespaces.
Review: https://reviews.apache.org/r/20025
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/b1b2b4cc
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/b1b2b4cc
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/b1b2b4cc
Branch: refs/heads/master
Commit: b1b2b4cc9d2c45f953c9c97318f0c4f4955fc174
Parents: 1251160
Author: Ian Downes <ia...@gmail.com>
Authored: Tue Apr 29 10:14:19 2014 -0700
Committer: Ian Downes <id...@twitter.com>
Committed: Tue Apr 29 10:14:19 2014 -0700
----------------------------------------------------------------------
src/Makefile.am | 4 +-
src/slave/containerizer/cgroups_launcher.cpp | 269 ----------------------
src/slave/containerizer/cgroups_launcher.hpp | 64 -----
src/slave/containerizer/containerizer.cpp | 4 +-
src/slave/containerizer/linux_launcher.cpp | 269 ++++++++++++++++++++++
src/slave/containerizer/linux_launcher.hpp | 64 +++++
src/tests/isolator_tests.cpp | 8 +-
7 files changed, 341 insertions(+), 341 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index cd06125..cb95f7c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -254,7 +254,7 @@ if OS_LINUX
libmesos_no_3rdparty_la_SOURCES += linux/cgroups.cpp
libmesos_no_3rdparty_la_SOURCES += slave/containerizer/isolators/cgroups/cpushare.cpp
libmesos_no_3rdparty_la_SOURCES += slave/containerizer/isolators/cgroups/mem.cpp
- libmesos_no_3rdparty_la_SOURCES += slave/containerizer/cgroups_launcher.cpp
+ libmesos_no_3rdparty_la_SOURCES += slave/containerizer/linux_launcher.cpp
libmesos_no_3rdparty_la_SOURCES += linux/fs.cpp
else
EXTRA_DIST += linux/cgroups.cpp
@@ -283,7 +283,7 @@ libmesos_no_3rdparty_la_SOURCES += common/attributes.hpp \
master/registrar.hpp \
master/master.hpp master/sorter.hpp \
messages/messages.hpp slave/constants.hpp \
- slave/containerizer/cgroups_launcher.hpp \
+ slave/containerizer/linux_launcher.hpp \
slave/containerizer/containerizer.hpp \
slave/containerizer/isolator.hpp \
slave/containerizer/isolators/cgroups/cpushare.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/slave/containerizer/cgroups_launcher.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/cgroups_launcher.cpp b/src/slave/containerizer/cgroups_launcher.cpp
deleted file mode 100644
index 39f0e4c..0000000
--- a/src/slave/containerizer/cgroups_launcher.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/**
- * 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 <vector>
-
-#include <stout/abort.hpp>
-#include <stout/hashset.hpp>
-#include <stout/path.hpp>
-#include <stout/unreachable.hpp>
-
-#include "linux/cgroups.hpp"
-
-#include "mesos/resources.hpp"
-
-#include "slave/containerizer/cgroups_launcher.hpp"
-
-using namespace process;
-
-using std::list;
-using std::string;
-using std::vector;
-
-namespace mesos {
-namespace internal {
-namespace slave {
-
-using state::RunState;
-
-CgroupsLauncher::CgroupsLauncher(const Flags& _flags, const string& _hierarchy)
- : flags(_flags),
- hierarchy(_hierarchy) {}
-
-
-Try<Launcher*> CgroupsLauncher::create(const Flags& flags)
-{
- Try<string> hierarchy = cgroups::prepare(
- flags.cgroups_hierarchy, "freezer", flags.cgroups_root);
-
- if (hierarchy.isError()) {
- return Error("Failed to create cgroups launcher: " + hierarchy.error());
- }
-
- LOG(INFO) << "Using " << hierarchy.get()
- << " as the freezer hierarchy for the cgroups launcher";
-
- return new CgroupsLauncher(flags, hierarchy.get());
-}
-
-
-Try<Nothing> CgroupsLauncher::recover(const std::list<state::RunState>& states)
-{
- hashset<string> cgroups;
-
- foreach (const RunState& state, states) {
- if (state.id.isNone()) {
- return Error("ContainerID is required to recover");
- }
- const ContainerID& containerId = state.id.get();
-
- Try<bool> exists = cgroups::exists(hierarchy, cgroup(containerId));
-
- if (!exists.get()) {
- // This may occur if the freezer cgroup was destroyed but the slave dies
- // before noticing this.
- // The containerizer will monitor the container's pid and notice that it
- // has exited, triggering destruction of the container.
- LOG(INFO) << "Couldn't find freezer cgroup for container " << containerId;
- continue;
- }
-
- if (state.forkedPid.isNone()) {
- return Error("Executor pid is required to recover container " +
- stringify(containerId));
- }
- pid_t pid = state.forkedPid.get();
-
- if (pids.containsValue(pid)) {
- // This should (almost) never occur. There is the possibility that a new
- // executor is launched with the same pid as one that just exited (highly
- // unlikely) and the slave dies after the new executor is launched but
- // before it hears about the termination of the earlier executor (also
- // unlikely). Regardless, the launcher can't do anything sensible so this
- // is considered an error.
- return Error("Detected duplicate pid " + stringify(pid) +
- " for container " + stringify(containerId));
- }
-
- pids.put(containerId, pid);
-
- cgroups.insert(cgroup(containerId));
- }
-
- Try<vector<string> > orphans = cgroups::get(hierarchy, flags.cgroups_root);
- if (orphans.isError()) {
- return Error(orphans.error());
- }
-
- foreach (const string& orphan, orphans.get()) {
- if (!cgroups.contains(orphan)) {
- LOG(INFO) << "Removing orphaned cgroup"
- << " '" << path::join("freezer", orphan) << "'";
- cgroups::destroy(hierarchy, orphan);
- }
- }
-
- return Nothing();
-}
-
-
-Try<pid_t> CgroupsLauncher::fork(
- const ContainerID& containerId,
- const lambda::function<int()>& inChild)
-{
- // Create a freezer cgroup for this container if necessary.
- Try<bool> exists = cgroups::exists(hierarchy, cgroup(containerId));
-
- if (exists.isError()) {
- return Error("Failed to create freezer cgroup: " + exists.error());
- }
-
- if (!exists.get()) {
- Try<Nothing> created = cgroups::create(hierarchy, cgroup(containerId));
-
- if (created.isError()) {
- LOG(ERROR) << "Failed to create freezer cgroup for container '"
- << containerId << "': " << created.error();
- return Error("Failed to contain process: " + created.error());
- }
- }
-
- // Additional processes forked will be put into the same process group and
- // session.
- Option<pid_t> pgid = pids.get(containerId);
-
- // Use a pipe to block the child until it's been moved into the freezer
- // cgroup.
- int pipes[2];
- // We assume this should not fail under reasonable conditions so we use CHECK.
- CHECK(pipe(pipes) == 0);
-
- pid_t pid;
-
- if ((pid = ::fork()) == -1) {
- return ErrnoError("Failed to fork");
- }
-
- if (pid == 0) {
- // In child.
- os::close(pipes[1]);
-
- // Move to a previously created process group (and session) if available,
- // else create a new session and process group. Even though we track
- // processes using cgroups we need to move to a different session so we're
- // independent from the slave's session (otherwise children will receive
- // SIGHUP if the slave exits).
- // TODO(idownes): perror is not listed as async-signal-safe and should be
- // reimplemented safely.
- if (pgid.isSome() && (setpgid(0, pgid.get()) == -1)) {
- perror("Failed to put child into process group");
- os::close(pipes[0]);
- _exit(1);
- } else if (setsid() == -1) {
- perror("Failed to put child in a new session");
- os::close(pipes[0]);
- _exit(1);
- }
-
- // Do a blocking read on the pipe until the parent signals us to continue.
- int buf;
- int len;
- while ((len = read(pipes[0], &buf, sizeof(buf))) == -1 && errno == EINTR);
-
- if (len != sizeof(buf)) {
- os::close(pipes[0]);
- ABORT("Failed to synchronize with parent");
- }
-
- os::close(pipes[0]);
-
- // This function should exec() and therefore not return.
- inChild();
-
- ABORT("Child failed to exec");
- }
-
- // Parent.
- os::close(pipes[0]);
-
- // Move the child into the freezer cgroup. Any grandchildren will also be
- // contained in the cgroup.
- Try<Nothing> assign = cgroups::assign(hierarchy, cgroup(containerId), pid);
-
- if (assign.isError()) {
- LOG(ERROR) << "Failed to assign process " << pid
- << " of container '" << containerId << "'"
- << " to its freezer cgroup: " << assign.error();
- kill(pid, SIGKILL);
- return Error("Failed to contain process");
- }
-
- // Now that we've contained the child we can signal it to continue by
- // writing to the pipe.
- int buf;
- ssize_t len;
- while ((len = write(pipes[1], &buf, sizeof(buf))) == -1 && errno == EINTR);
-
- if (len != sizeof(buf)) {
- // Ensure the child is killed.
- kill(pid, SIGKILL);
- os::close(pipes[1]);
- return Error("Failed to synchronize child process");
- }
- os::close(pipes[1]);
-
- // Store the pid (session id and process group id) if this is the first
- // process forked for this container.
- if (!pids.contains(containerId)) {
- pids.put(containerId, pid);
- }
-
- return pid;
-}
-
-
-Future<Nothing> _destroy(
- const ContainerID& containerId,
- process::Future<bool> destroyed)
-{
- if (destroyed.isFailed()) {
- LOG(ERROR) << "Failed to destroy freezer cgroup for '"
- << containerId << "': " << destroyed.failure();
- return Failure("Failed to destroy launcher: " + destroyed.failure());
- }
- return Nothing();
-}
-
-
-Future<Nothing> CgroupsLauncher::destroy(const ContainerID& containerId)
-{
- pids.erase(containerId);
-
- return cgroups::destroy(hierarchy, cgroup(containerId))
- .then(lambda::bind(&_destroy, containerId, lambda::_1));
-}
-
-
-string CgroupsLauncher::cgroup(const ContainerID& containerId)
-{
- return path::join(flags.cgroups_root, containerId.value());
-}
-
-} // namespace slave {
-} // namespace internal {
-} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/slave/containerizer/cgroups_launcher.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/cgroups_launcher.hpp b/src/slave/containerizer/cgroups_launcher.hpp
deleted file mode 100644
index db61107..0000000
--- a/src/slave/containerizer/cgroups_launcher.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * 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_LAUNCHER_HPP__
-#define __CGROUPS_LAUNCHER_HPP__
-
-#include "slave/containerizer/launcher.hpp"
-
-namespace mesos {
-namespace internal {
-namespace slave {
-
-// Launcher for Linux systems with cgroups. Uses a freezer cgroup to track
-// pids.
-class CgroupsLauncher : public Launcher
-{
-public:
- static Try<Launcher*> create(const Flags& flags);
-
- virtual ~CgroupsLauncher() {}
-
- virtual Try<Nothing> recover(const std::list<state::RunState>& states);
-
- virtual Try<pid_t> fork(
- const ContainerID& containerId,
- const lambda::function<int()>& inChild);
-
- virtual process::Future<Nothing> destroy(const ContainerID& containerId);
-
-private:
- CgroupsLauncher(const Flags& flags, const std::string& hierarchy);
-
- static const std::string subsystem;
- const Flags flags;
- const std::string hierarchy;
-
- std::string cgroup(const ContainerID& containerId);
-
- // The 'pid' is the process id of the first process and also the process
- // group id and session id.
- hashmap<ContainerID, pid_t> pids;
-};
-
-
-} // namespace slave {
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __CGROUPS_LAUNCHER_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/slave/containerizer/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/containerizer.cpp b/src/slave/containerizer/containerizer.cpp
index 9321bbd..374a778 100644
--- a/src/slave/containerizer/containerizer.cpp
+++ b/src/slave/containerizer/containerizer.cpp
@@ -32,7 +32,7 @@
#include "slave/slave.hpp"
#ifdef __linux__
-#include "slave/containerizer/cgroups_launcher.hpp"
+#include "slave/containerizer/linux_launcher.hpp"
#endif // __linux__
#include "slave/containerizer/containerizer.hpp"
#include "slave/containerizer/isolator.hpp"
@@ -210,7 +210,7 @@ Try<Containerizer*> Containerizer::create(
#ifdef __linux__
// Use cgroups on Linux if any cgroups isolators are used.
Try<Launcher*> launcher = strings::contains(isolation, "cgroups")
- ? CgroupsLauncher::create(flags) : PosixLauncher::create(flags);
+ ? LinuxLauncher::create(flags) : PosixLauncher::create(flags);
#else
Try<Launcher*> launcher = PosixLauncher::create(flags);
#endif // __linux__
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/slave/containerizer/linux_launcher.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/linux_launcher.cpp b/src/slave/containerizer/linux_launcher.cpp
new file mode 100644
index 0000000..530e0bd
--- /dev/null
+++ b/src/slave/containerizer/linux_launcher.cpp
@@ -0,0 +1,269 @@
+/**
+ * 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 <vector>
+
+#include <stout/abort.hpp>
+#include <stout/hashset.hpp>
+#include <stout/path.hpp>
+#include <stout/unreachable.hpp>
+
+#include "linux/cgroups.hpp"
+
+#include "mesos/resources.hpp"
+
+#include "slave/containerizer/linux_launcher.hpp"
+
+using namespace process;
+
+using std::list;
+using std::string;
+using std::vector;
+
+namespace mesos {
+namespace internal {
+namespace slave {
+
+using state::RunState;
+
+LinuxLauncher::LinuxLauncher(const Flags& _flags, const string& _hierarchy)
+ : flags(_flags),
+ hierarchy(_hierarchy) {}
+
+
+Try<Launcher*> LinuxLauncher::create(const Flags& flags)
+{
+ Try<string> hierarchy = cgroups::prepare(
+ flags.cgroups_hierarchy, "freezer", flags.cgroups_root);
+
+ if (hierarchy.isError()) {
+ return Error("Failed to create Linux launcher: " + hierarchy.error());
+ }
+
+ LOG(INFO) << "Using " << hierarchy.get()
+ << " as the freezer hierarchy for the Linux launcher";
+
+ return new LinuxLauncher(flags, hierarchy.get());
+}
+
+
+Try<Nothing> LinuxLauncher::recover(const std::list<state::RunState>& states)
+{
+ hashset<string> cgroups;
+
+ foreach (const RunState& state, states) {
+ if (state.id.isNone()) {
+ return Error("ContainerID is required to recover");
+ }
+ const ContainerID& containerId = state.id.get();
+
+ Try<bool> exists = cgroups::exists(hierarchy, cgroup(containerId));
+
+ if (!exists.get()) {
+ // This may occur if the freezer cgroup was destroyed but the slave dies
+ // before noticing this.
+ // The containerizer will monitor the container's pid and notice that it
+ // has exited, triggering destruction of the container.
+ LOG(INFO) << "Couldn't find freezer cgroup for container " << containerId;
+ continue;
+ }
+
+ if (state.forkedPid.isNone()) {
+ return Error("Executor pid is required to recover container " +
+ stringify(containerId));
+ }
+ pid_t pid = state.forkedPid.get();
+
+ if (pids.containsValue(pid)) {
+ // This should (almost) never occur. There is the possibility that a new
+ // executor is launched with the same pid as one that just exited (highly
+ // unlikely) and the slave dies after the new executor is launched but
+ // before it hears about the termination of the earlier executor (also
+ // unlikely). Regardless, the launcher can't do anything sensible so this
+ // is considered an error.
+ return Error("Detected duplicate pid " + stringify(pid) +
+ " for container " + stringify(containerId));
+ }
+
+ pids.put(containerId, pid);
+
+ cgroups.insert(cgroup(containerId));
+ }
+
+ Try<vector<string> > orphans = cgroups::get(hierarchy, flags.cgroups_root);
+ if (orphans.isError()) {
+ return Error(orphans.error());
+ }
+
+ foreach (const string& orphan, orphans.get()) {
+ if (!cgroups.contains(orphan)) {
+ LOG(INFO) << "Removing orphaned cgroup"
+ << " '" << path::join("freezer", orphan) << "'";
+ cgroups::destroy(hierarchy, orphan);
+ }
+ }
+
+ return Nothing();
+}
+
+
+Try<pid_t> LinuxLauncher::fork(
+ const ContainerID& containerId,
+ const lambda::function<int()>& inChild)
+{
+ // Create a freezer cgroup for this container if necessary.
+ Try<bool> exists = cgroups::exists(hierarchy, cgroup(containerId));
+
+ if (exists.isError()) {
+ return Error("Failed to create freezer cgroup: " + exists.error());
+ }
+
+ if (!exists.get()) {
+ Try<Nothing> created = cgroups::create(hierarchy, cgroup(containerId));
+
+ if (created.isError()) {
+ LOG(ERROR) << "Failed to create freezer cgroup for container '"
+ << containerId << "': " << created.error();
+ return Error("Failed to contain process: " + created.error());
+ }
+ }
+
+ // Additional processes forked will be put into the same process group and
+ // session.
+ Option<pid_t> pgid = pids.get(containerId);
+
+ // Use a pipe to block the child until it's been moved into the freezer
+ // cgroup.
+ int pipes[2];
+ // We assume this should not fail under reasonable conditions so we use CHECK.
+ CHECK(pipe(pipes) == 0);
+
+ pid_t pid;
+
+ if ((pid = ::fork()) == -1) {
+ return ErrnoError("Failed to fork");
+ }
+
+ if (pid == 0) {
+ // In child.
+ os::close(pipes[1]);
+
+ // Move to a previously created process group (and session) if available,
+ // else create a new session and process group. Even though we track
+ // processes using cgroups we need to move to a different session so we're
+ // independent from the slave's session (otherwise children will receive
+ // SIGHUP if the slave exits).
+ // TODO(idownes): perror is not listed as async-signal-safe and should be
+ // reimplemented safely.
+ if (pgid.isSome() && (setpgid(0, pgid.get()) == -1)) {
+ perror("Failed to put child into process group");
+ os::close(pipes[0]);
+ _exit(1);
+ } else if (setsid() == -1) {
+ perror("Failed to put child in a new session");
+ os::close(pipes[0]);
+ _exit(1);
+ }
+
+ // Do a blocking read on the pipe until the parent signals us to continue.
+ int buf;
+ int len;
+ while ((len = read(pipes[0], &buf, sizeof(buf))) == -1 && errno == EINTR);
+
+ if (len != sizeof(buf)) {
+ os::close(pipes[0]);
+ ABORT("Failed to synchronize with parent");
+ }
+
+ os::close(pipes[0]);
+
+ // This function should exec() and therefore not return.
+ inChild();
+
+ ABORT("Child failed to exec");
+ }
+
+ // Parent.
+ os::close(pipes[0]);
+
+ // Move the child into the freezer cgroup. Any grandchildren will also be
+ // contained in the cgroup.
+ Try<Nothing> assign = cgroups::assign(hierarchy, cgroup(containerId), pid);
+
+ if (assign.isError()) {
+ LOG(ERROR) << "Failed to assign process " << pid
+ << " of container '" << containerId << "'"
+ << " to its freezer cgroup: " << assign.error();
+ kill(pid, SIGKILL);
+ return Error("Failed to contain process");
+ }
+
+ // Now that we've contained the child we can signal it to continue by
+ // writing to the pipe.
+ int buf;
+ ssize_t len;
+ while ((len = write(pipes[1], &buf, sizeof(buf))) == -1 && errno == EINTR);
+
+ if (len != sizeof(buf)) {
+ // Ensure the child is killed.
+ kill(pid, SIGKILL);
+ os::close(pipes[1]);
+ return Error("Failed to synchronize child process");
+ }
+ os::close(pipes[1]);
+
+ // Store the pid (session id and process group id) if this is the first
+ // process forked for this container.
+ if (!pids.contains(containerId)) {
+ pids.put(containerId, pid);
+ }
+
+ return pid;
+}
+
+
+Future<Nothing> _destroy(
+ const ContainerID& containerId,
+ process::Future<bool> destroyed)
+{
+ if (destroyed.isFailed()) {
+ LOG(ERROR) << "Failed to destroy freezer cgroup for '"
+ << containerId << "': " << destroyed.failure();
+ return Failure("Failed to destroy launcher: " + destroyed.failure());
+ }
+ return Nothing();
+}
+
+
+Future<Nothing> LinuxLauncher::destroy(const ContainerID& containerId)
+{
+ pids.erase(containerId);
+
+ return cgroups::destroy(hierarchy, cgroup(containerId))
+ .then(lambda::bind(&_destroy, containerId, lambda::_1));
+}
+
+
+string LinuxLauncher::cgroup(const ContainerID& containerId)
+{
+ return path::join(flags.cgroups_root, containerId.value());
+}
+
+} // namespace slave {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/slave/containerizer/linux_launcher.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/linux_launcher.hpp b/src/slave/containerizer/linux_launcher.hpp
new file mode 100644
index 0000000..8f96c69
--- /dev/null
+++ b/src/slave/containerizer/linux_launcher.hpp
@@ -0,0 +1,64 @@
+/**
+ * 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 __LINUX_LAUNCHER_HPP__
+#define __LINUX_LAUNCHER_HPP__
+
+#include "slave/containerizer/launcher.hpp"
+
+namespace mesos {
+namespace internal {
+namespace slave {
+
+// Launcher for Linux systems with cgroups. Uses a freezer cgroup to track
+// pids.
+class LinuxLauncher : public Launcher
+{
+public:
+ static Try<Launcher*> create(const Flags& flags);
+
+ virtual ~LinuxLauncher() {}
+
+ virtual Try<Nothing> recover(const std::list<state::RunState>& states);
+
+ virtual Try<pid_t> fork(
+ const ContainerID& containerId,
+ const lambda::function<int()>& inChild);
+
+ virtual process::Future<Nothing> destroy(const ContainerID& containerId);
+
+private:
+ LinuxLauncher(const Flags& flags, const std::string& hierarchy);
+
+ static const std::string subsystem;
+ const Flags flags;
+ const std::string hierarchy;
+
+ std::string cgroup(const ContainerID& containerId);
+
+ // The 'pid' is the process id of the first process and also the process
+ // group id and session id.
+ hashmap<ContainerID, pid_t> pids;
+};
+
+
+} // namespace slave {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __LINUX_LAUNCHER_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/b1b2b4cc/src/tests/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/isolator_tests.cpp b/src/tests/isolator_tests.cpp
index dde977e..b0eff57 100644
--- a/src/tests/isolator_tests.cpp
+++ b/src/tests/isolator_tests.cpp
@@ -39,7 +39,7 @@
#include "slave/slave.hpp"
#ifdef __linux__
-#include "slave/containerizer/cgroups_launcher.hpp"
+#include "slave/containerizer/linux_launcher.hpp"
#endif // __linux__
#include "slave/containerizer/isolator.hpp"
#include "slave/containerizer/launcher.hpp"
@@ -62,8 +62,8 @@ using namespace process;
using mesos::internal::master::Master;
#ifdef __linux__
using mesos::internal::slave::CgroupsCpushareIsolatorProcess;
-using mesos::internal::slave::CgroupsLauncher;
using mesos::internal::slave::CgroupsMemIsolatorProcess;
+using mesos::internal::slave::LinuxLauncher;
#endif // __linux__
using mesos::internal::slave::Isolator;
using mesos::internal::slave::IsolatorProcess;
@@ -308,7 +308,7 @@ TEST_F(LimitedCpuIsolatorTest, ROOT_CGROUPS_Cfs)
Try<Isolator*> isolator = CgroupsCpushareIsolatorProcess::create(flags);
CHECK_SOME(isolator);
- Try<Launcher*> launcher = CgroupsLauncher::create(flags);
+ Try<Launcher*> launcher = LinuxLauncher::create(flags);
CHECK_SOME(launcher);
// Set the executor's resources to 0.5 cpu.
@@ -395,7 +395,7 @@ TEST_F(LimitedCpuIsolatorTest, ROOT_CGROUPS_Cfs_Big_Quota)
Try<Isolator*> isolator = CgroupsCpushareIsolatorProcess::create(flags);
CHECK_SOME(isolator);
- Try<Launcher*> launcher = CgroupsLauncher::create(flags);
+ Try<Launcher*> launcher = LinuxLauncher::create(flags);
CHECK_SOME(launcher);
// Set the executor's resources to 100.5 cpu.