You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by qi...@apache.org on 2016/11/05 08:40:12 UTC
[5/6] mesos git commit: Implemented handling AUFS whiteouts for copy
backend.
Implemented handling AUFS whiteouts for copy backend.
Review: https://reviews.apache.org/r/53115
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/0f4c15ad
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/0f4c15ad
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/0f4c15ad
Branch: refs/heads/master
Commit: 0f4c15ad735e437a8e8b9bb6846025aea02c765b
Parents: 3800cfd
Author: Qian Zhang <zh...@cn.ibm.com>
Authored: Sat Oct 22 21:45:44 2016 +0800
Committer: Qian Zhang <zh...@gmail.com>
Committed: Sat Nov 5 16:18:30 2016 +0800
----------------------------------------------------------------------
.../mesos/provisioner/backends/copy.cpp | 103 ++++++++++++++++++-
1 file changed, 98 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/0f4c15ad/src/slave/containerizer/mesos/provisioner/backends/copy.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/provisioner/backends/copy.cpp b/src/slave/containerizer/mesos/provisioner/backends/copy.cpp
index 9c5354e..7e98110 100644
--- a/src/slave/containerizer/mesos/provisioner/backends/copy.cpp
+++ b/src/slave/containerizer/mesos/provisioner/backends/copy.cpp
@@ -16,6 +16,8 @@
#include <list>
+#include <mesos/docker/spec.hpp>
+
#include <process/collect.hpp>
#include <process/defer.hpp>
#include <process/dispatch.hpp>
@@ -24,7 +26,6 @@
#include <process/process.hpp>
#include <process/subprocess.hpp>
-
#include <stout/foreach.hpp>
#include <stout/os.hpp>
@@ -32,7 +33,6 @@
#include "slave/containerizer/mesos/provisioner/backends/copy.hpp"
-
using namespace process;
using std::string;
@@ -128,9 +128,92 @@ Future<Nothing> CopyBackendProcess::provision(
Future<Nothing> CopyBackendProcess::_provision(
- string layer,
- const string& rootfs)
+ string layer,
+ const string& rootfs)
{
+ // Traverse the layer to check if there is any whiteout files, if
+ // yes, remove the corresponding files/directories from the rootfs.
+ // Note: We assume all image types use AUFS whiteout format.
+ char* source[] = {const_cast<char*>(layer.c_str()), nullptr};
+
+ FTS* tree = ::fts_open(source, FTS_NOCHDIR | FTS_PHYSICAL, nullptr);
+ if (tree == nullptr) {
+ return Failure("Failed to open '" + layer + "': " + os::strerror(errno));
+ }
+
+ vector<string> whiteouts;
+ for (FTSENT *node = ::fts_read(tree);
+ node != nullptr; node = ::fts_read(tree)) {
+ if (node->fts_info != FTS_F) {
+ continue;
+ }
+
+ if (!strings::startsWith(node->fts_name, docker::spec::WHITEOUT_PREFIX)) {
+ continue;
+ }
+
+ string ftsPath = string(node->fts_path);
+ Path whiteout = Path(ftsPath.substr(layer.length() + 1));
+
+ // Keep the relative paths of the whiteout files, we will
+ // remove them from rootfs after layer is copied to rootfs.
+ whiteouts.push_back(whiteout.string());
+
+ if (node->fts_name == string(docker::spec::WHITEOUT_OPAQUE_PREFIX)) {
+ const string path = path::join(rootfs, Path(whiteout).dirname());
+
+ // Remove the entries under the directory labeled
+ // as opaque whiteout from rootfs.
+ Try<Nothing> rmdir = os::rmdir(path, true, false);
+ if (rmdir.isError()) {
+ ::fts_close(tree);
+ return Failure(
+ "Failed to remove the entries under the directory labeled as"
+ " opaque whiteout '" + path + "': " + rmdir.error());
+ }
+ } else {
+ const string path = path::join(
+ rootfs,
+ whiteout.dirname(),
+ whiteout.basename().substr(strlen(docker::spec::WHITEOUT_PREFIX)));
+
+ // The file/directory labeled as whiteout may have already been
+ // removed with the code above due to its parent directory labeled
+ // as opaque whiteout, so here we need to check if it still exists
+ // before trying to remove it.
+ if (os::exists(path)) {
+ if (os::stat::isdir(path)) {
+ Try<Nothing> rmdir = os::rmdir(path);
+ if (rmdir.isError()) {
+ ::fts_close(tree);
+ return Failure(
+ "Failed to remove the directory labeled as whiteout '" +
+ path + "': " + rmdir.error());
+ }
+ } else {
+ Try<Nothing> rm = os::rm(path);
+ if (rm.isError()) {
+ ::fts_close(tree);
+ return Failure(
+ "Failed to remove the file labeled as whiteout '" +
+ path + "': " + rm.error());
+ }
+ }
+ }
+ }
+ }
+
+ if (errno != 0) {
+ Error error = ErrnoError();
+ ::fts_close(tree);
+ return Failure(error);
+ }
+
+ if (::fts_close(tree) != 0) {
+ return Failure(
+ "Failed to stop traversing file system: " + os::strerror(errno));
+ }
+
VLOG(1) << "Copying layer path '" << layer << "' to rootfs '" << rootfs
<< "'";
@@ -160,7 +243,7 @@ Future<Nothing> CopyBackendProcess::_provision(
Subprocess cp = s.get();
return cp.status()
- .then([cp](const Option<int>& status) -> Future<Nothing> {
+ .then([=](const Option<int>& status) -> Future<Nothing> {
if (status.isNone()) {
return Failure("Failed to reap subprocess to copy image");
} else if (status.get() != 0) {
@@ -170,6 +253,16 @@ Future<Nothing> CopyBackendProcess::_provision(
});
}
+ // Remove the whiteout files from rootfs.
+ foreach (const string whiteout, whiteouts) {
+ Try<Nothing> rm = os::rm(path::join(rootfs, whiteout));
+ if (rm.isError()) {
+ return Failure(
+ "Failed to remove whiteout file '" +
+ whiteout + "': " + rm.error());
+ }
+ }
+
return Nothing();
});
}