You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jp...@apache.org on 2017/11/29 22:57:15 UTC
mesos git commit: Fall back to binding devices if mknod fails.
Repository: mesos
Updated Branches:
refs/heads/master 17d186e37 -> 5bfdc3bec
Fall back to binding devices if mknod fails.
When importing device nodes into a chroot, the `mknod` can fail
due to devices cgroup or user namespace restrictions. In this
case, we can fall back to bind mounting device nodes into the
new chroot.
Review: https://reviews.apache.org/r/64170/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5bfdc3be
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5bfdc3be
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5bfdc3be
Branch: refs/heads/master
Commit: 5bfdc3bec17908067fece05617bfa37654d08191
Parents: 17d186e
Author: James Peach <jp...@apache.org>
Authored: Wed Nov 29 13:59:41 2017 -0800
Committer: James Peach <jp...@apache.org>
Committed: Wed Nov 29 13:59:41 2017 -0800
----------------------------------------------------------------------
src/linux/fs.cpp | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5bfdc3be/src/linux/fs.cpp
----------------------------------------------------------------------
diff --git a/src/linux/fs.cpp b/src/linux/fs.cpp
index 6539f31..3492b3f 100644
--- a/src/linux/fs.cpp
+++ b/src/linux/fs.cpp
@@ -583,7 +583,12 @@ namespace chroot {
namespace internal {
-Try<Nothing> copyDeviceNode(const string& source, const string& target)
+// Make the source device node appear at the target path. We prefer to
+// `mknod` the device node since that avoids an otherwise unnecessary
+// mount table entry. The `mknod` can fail if we are in a user namespace
+// or if the devices cgroup is restricting that device. In that case, we
+// bind mount the device to the target path.
+Try<Nothing> importDeviceNode(const string& source, const string& target)
{
// We are likely to be operating in a multi-threaded environment so
// it's not safe to change the umask. Instead, we'll explicitly set
@@ -599,13 +604,23 @@ Try<Nothing> copyDeviceNode(const string& source, const string& target)
}
Try<Nothing> mknod = os::mknod(target, mode.get(), dev.get());
- if (mknod.isError()) {
- return Error("Failed to create device: " + mknod.error());
+ if (mknod.isSome()) {
+ Try<Nothing> chmod = os::chmod(target, mode.get());
+ if (chmod.isError()) {
+ return Error("Failed to chmod device: " + chmod.error());
+ }
+
+ return Nothing();
+ }
+
+ Try<Nothing> touch = os::touch(target);
+ if (touch.isError()) {
+ return Error("Failed to create device mount point: " + touch.error());
}
- Try<Nothing> chmod = os::chmod(target, mode.get());
- if (chmod.isError()) {
- return Error("Failed to chmod device: " + chmod.error());
+ Try<Nothing> mnt = fs::mount(source, target, None(), MS_BIND, None());
+ if (mnt.isError()) {
+ return Error("Failed to bind device: " + touch.error());
}
return Nothing();
@@ -634,12 +649,12 @@ Try<Nothing> mountSpecialFilesystems(const string& root)
// List of special filesystems useful for a chroot environment.
// NOTE: This list is ordered, e.g., mount /proc before bind
// mounting /proc/sys and then making it read-only.
- vector<Mount> mounts = {
+ const vector<Mount> mounts = {
{"proc", "/proc", "proc", None(), MS_NOSUID | MS_NOEXEC | MS_NODEV}, // NOLINT(whitespace/line_length)
{"/proc/sys", "/proc/sys", None(), None(), MS_BIND},
{None(), "/proc/sys", None(), None(), MS_BIND | MS_RDONLY | MS_REMOUNT}, // NOLINT(whitespace/line_length)
{"sysfs", "/sys", "sysfs", None(), MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV}, // NOLINT(whitespace/line_length)
- {"tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID | MS_STRICTATIME}, // NOLINT(whitespace/line_length)
+ {"tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID | MS_STRICTATIME | MS_NOEXEC}, // NOLINT(whitespace/line_length)
{"devpts", "/dev/pts", "devpts", "newinstance,ptmxmode=0666", MS_NOSUID | MS_NOEXEC}, // NOLINT(whitespace/line_length)
{"tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID | MS_NODEV | MS_STRICTATIME}, // NOLINT(whitespace/line_length)
};
@@ -713,24 +728,25 @@ Try<Nothing> createStandardDevices(const string& root)
}
}
- // Inject each device into the chroot environment. Copy both the
+ // Import each device into the chroot environment. Copy both the
// mode and the device itself from the corresponding host device.
foreach (const string& device, devices) {
- Try<Nothing> copy = copyDeviceNode(
+ Try<Nothing> import = importDeviceNode(
path::join("/", "dev", device),
path::join(root, "dev", device));
- if (copy.isError()) {
- return Error("Failed to copy device '" + device + "': " + copy.error());
+ if (import.isError()) {
+ return Error(
+ "Failed to import device '" + device + "': " + import.error());
}
}
- vector<SymLink> symlinks = {
+ const vector<SymLink> symlinks = {
{"/proc/self/fd", path::join(root, "dev", "fd")},
{"/proc/self/fd/0", path::join(root, "dev", "stdin")},
{"/proc/self/fd/1", path::join(root, "dev", "stdout")},
{"/proc/self/fd/2", path::join(root, "dev", "stderr")},
- {"pts/ptmx", path::join(root, "dev", "ptmx")}
+ {"pts/ptmx", path::join(root, "dev", "ptmx")}
};
foreach (const SymLink& symlink, symlinks) {