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 2015/03/11 01:24:52 UTC

[10/10] mesos git commit: Add Linux pivot_root() wrapper.

Add Linux pivot_root() wrapper.

Review: https://reviews.apache.org/r/31442


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/55869a5c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/55869a5c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/55869a5c

Branch: refs/heads/master
Commit: 55869a5c33fd96202164021e795b473ede3415fe
Parents: b37c1ba
Author: Ian Downes <id...@twitter.com>
Authored: Wed Feb 25 11:21:11 2015 -0800
Committer: Ian Downes <id...@twitter.com>
Committed: Tue Mar 10 17:18:25 2015 -0700

----------------------------------------------------------------------
 src/linux/fs.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 src/linux/fs.hpp |  6 ++++++
 2 files changed, 53 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/55869a5c/src/linux/fs.cpp
----------------------------------------------------------------------
diff --git a/src/linux/fs.cpp b/src/linux/fs.cpp
index b01d14c..b2af7a6 100644
--- a/src/linux/fs.cpp
+++ b/src/linux/fs.cpp
@@ -23,6 +23,9 @@
 #include <linux/limits.h>
 
 #include <stout/error.hpp>
+#include <stout/strings.hpp>
+
+#include <stout/os/stat.hpp>
 
 #include "common/lock.hpp"
 
@@ -178,6 +181,50 @@ Try<Nothing> unmount(const std::string& target, int flags)
 }
 
 
+Try<Nothing> pivot_root(
+    const std::string& newRoot,
+    const std::string& putOld)
+{
+  // These checks are done in the syscall but we'll do them here to
+  // provide less cryptic error messages. See 'man 2 pivot_root'.
+  if (!os::stat::isdir(newRoot)) {
+    return Error("newRoot '" + newRoot + "' is not a directory");
+  }
+
+  if (!os::stat::isdir(putOld)) {
+    return Error("putOld '" + putOld + "' is not a directory");
+  }
+
+  // TODO(idownes): Verify that newRoot (and putOld) is on a different
+  // filesystem to the current root. st_dev distinguishes the device
+  // an inode is on, but bind mounts (which are acceptable to
+  // pivot_root) share the same st_dev as the source of the mount so
+  // st_dev is not generally sufficient.
+
+  if (!strings::startsWith(putOld, newRoot)) {
+    return Error("putOld '" + putOld +
+                 "' must be beneath newRoot '" + newRoot);
+  }
+
+#ifdef __NR_pivot_root
+  int ret = ::syscall(__NR_pivot_root, newRoot.c_str(), putOld.c_str());
+#elif __x86_64__
+  // A workaround for systems that have an old glib but have a new
+  // kernel. The magic number '155' is the syscall number for
+  // 'pivot_root' on the x86_64 architecture, see
+  // arch/x86/syscalls/syscall_64.tbl
+  int ret = ::syscall(155, newRoot.c_str(), putOld.c_str());
+#else
+#error "pivot_root is not available"
+#endif
+  if (ret == -1) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
 } // namespace fs {
 } // namespace internal {
 } // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/55869a5c/src/linux/fs.hpp
----------------------------------------------------------------------
diff --git a/src/linux/fs.hpp b/src/linux/fs.hpp
index ac8b5f4..8280bcb 100644
--- a/src/linux/fs.hpp
+++ b/src/linux/fs.hpp
@@ -141,6 +141,12 @@ Try<Nothing> mount(const std::string& source,
 Try<Nothing> unmount(const std::string& target, int flags = 0);
 
 
+// Change the root filesystem.
+Try<Nothing> pivot_root(
+    const std::string& newRoot,
+    const std::string& putOld);
+
+
 } // namespace fs {
 } // namespace internal {
 } // namespace mesos {