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/30 00:43:10 UTC

[2/2] mesos git commit: Added a d_type check in containerizer backend validation.

Added a d_type check in containerizer backend validation.

In the unified containerizer, the overlay fs backend depends
on the underlying filesystem populating the `d_type` field in
`struct dirent`. Raise an error if the user specifies overlayfs
as backend on an unsupported filesystem.  Fallback to other
backends in the default case and raise a warning.

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


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

Branch: refs/heads/master
Commit: 9d27e429cbe63ed882df8cb2162776ec33bc3c81
Parents: 63e6219
Author: Meng Zhu <mz...@mesosphere.io>
Authored: Wed Nov 29 15:11:03 2017 -0800
Committer: James Peach <jp...@apache.org>
Committed: Wed Nov 29 16:34:38 2017 -0800

----------------------------------------------------------------------
 src/linux/fs.cpp                                | 32 +++++++++++++++++
 src/linux/fs.hpp                                |  8 ++++-
 .../mesos/provisioner/provisioner.cpp           | 38 ++++++++++++++++++++
 3 files changed, 77 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/9d27e429/src/linux/fs.cpp
----------------------------------------------------------------------
diff --git a/src/linux/fs.cpp b/src/linux/fs.cpp
index 3492b3f..94e78df 100644
--- a/src/linux/fs.cpp
+++ b/src/linux/fs.cpp
@@ -99,6 +99,38 @@ Try<bool> supported(const string& fsname)
 }
 
 
+Try<bool> dtypeSupported(const string& directory)
+{
+  DIR* dir = ::opendir(directory.c_str());
+
+  if (dir == nullptr) {
+    return ErrnoError("Failed to open '" + directory + "'");
+  }
+
+  bool result = true;
+  struct dirent* entry;
+
+  errno = 0;
+  while ((entry = ::readdir(dir)) != nullptr) {
+    if (entry->d_type == DT_UNKNOWN) {
+      result = false;
+    }
+  }
+
+  if (errno != 0) {
+    Error error = ErrnoError("Failed to read '" + directory + "'");
+    ::closedir(dir);
+    return error;
+  }
+
+  if (::closedir(dir) == -1) {
+    return ErrnoError("Failed to close '" + directory + "'");
+  }
+
+  return result;
+}
+
+
 Try<uint32_t> type(const string& path)
 {
   struct statfs buf;

http://git-wip-us.apache.org/repos/asf/mesos/blob/9d27e429/src/linux/fs.hpp
----------------------------------------------------------------------
diff --git a/src/linux/fs.hpp b/src/linux/fs.hpp
index a79e646..76dc09c 100644
--- a/src/linux/fs.hpp
+++ b/src/linux/fs.hpp
@@ -178,6 +178,13 @@ namespace fs {
 Try<bool> supported(const std::string& fsname);
 
 
+// Detect whether the given file system supports `d_type`
+// in `struct dirent`.
+// @directory must not be empty for correct `d_type` detection.
+// It is the caller's responsibility to ensure this holds.
+Try<bool> dtypeSupported(const std::string& directory);
+
+
 // Returns a filesystem type id, given a directory.
 // http://man7.org/linux/man-pages/man2/fstatfs64.2.html
 Try<uint32_t> type(const std::string& path);
@@ -186,7 +193,6 @@ Try<uint32_t> type(const std::string& path);
 // Returns the filesystem type name, given a filesystem type id.
 Try<std::string> typeName(uint32_t fsType);
 
-
 // TODO(idownes): These different variations of mount information
 // should be consolidated and moved to stout, along with mount and
 // umount.

http://git-wip-us.apache.org/repos/asf/mesos/blob/9d27e429/src/slave/containerizer/mesos/provisioner/provisioner.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/provisioner/provisioner.cpp b/src/slave/containerizer/mesos/provisioner/provisioner.cpp
index 9d1a4e5..81d2f93 100644
--- a/src/slave/containerizer/mesos/provisioner/provisioner.cpp
+++ b/src/slave/containerizer/mesos/provisioner/provisioner.cpp
@@ -126,6 +126,41 @@ static Try<Nothing> validateBackend(
           "on the underlying filesystem '" + fsTypeName + "'");
     }
 
+    // Check whether `d_type` is supported. We need to create a
+    // directory entry to probe this since `.` and `..` may be
+    // marked `DT_DIR` even if the filesystem does not otherwise
+    // have `d_type` support.
+    string probeDir = path::join(directory, ".probe");
+
+    Try<Nothing> mkdir = os::mkdir(probeDir);
+    if (mkdir.isError()) {
+      return Error(
+          "Failed to create temporary directory '" +
+          probeDir + "': " + mkdir.error());
+    }
+
+    Try<bool> supportDType = fs::dtypeSupported(directory);
+
+    // clean up first
+    Try<Nothing> rmdir = os::rmdir(probeDir);
+    if (rmdir.isError()) {
+      LOG(WARNING) << "Failed to remove temporary directory"
+                   << "' " << probeDir << "': " << rmdir.error();
+     }
+
+    if (supportDType.isError()) {
+      return Error(
+          "Cannot verify filesystem attributes: " +
+          supportDType.error());
+    }
+
+    if (!supportDType.get()) {
+      return Error(
+          "Backend '" + stringify(OVERLAY_BACKEND) +
+          "' is not supported due to missing d_type support " +
+          "on the underlying filesystem");
+    }
+
     return Nothing();
   }
 
@@ -242,6 +277,9 @@ Try<Owned<Provisioner>> Provisioner::create(
 
       Try<Nothing> supported = validateBackend(backendName, rootDir.get());
       if (supported.isError()) {
+        LOG(INFO) << "Provisioner backend '"
+                  << backendName << "' is not supported on '"
+                  << rootDir.get() << "': " << supported.error();
         continue;
       }