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 {