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;
}