You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/03/28 21:59:46 UTC
[6/8] mesos git commit: Implemented deletion for persistent volumes.
Implemented deletion for persistent volumes.
Prior to this commit, destroying a persistent volume would remove the
Mesos-level metadata about the volume, but wouldn't destroy any of the
volume's filesystem content. We now remove the volume from the slave's
filesystem, essentially via "rm -r".
Review: https://reviews.apache.org/r/45121/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f2dad5ca
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f2dad5ca
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f2dad5ca
Branch: refs/heads/master
Commit: f2dad5caac44bd874275163ce99ec75eb80e9043
Parents: abf2762
Author: Neil Conway <ne...@gmail.com>
Authored: Mon Mar 28 12:58:53 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Mon Mar 28 12:58:53 2016 -0700
----------------------------------------------------------------------
src/slave/slave.cpp | 66 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 56 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/f2dad5ca/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 86ac67b..fc77f59 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -2448,16 +2448,15 @@ void Slave::checkpointResources(const vector<Resource>& _checkpointedResources)
newCheckpointedResources))
<< "Failed to checkpoint resources " << newCheckpointedResources;
- // Creates persistent volumes that do not exist and schedules
- // releasing those persistent volumes that are no longer needed.
+ Resources newVolumes = newCheckpointedResources.persistentVolumes();
+
+ // Create persistent volumes that do not already exist.
//
// TODO(jieyu): Consider introducing a volume manager once we start
// to support multiple disks, or raw disks. Depending on the
// DiskInfo, we may want to create either directories under a root
// directory, or LVM volumes from a given device.
- Resources volumes = newCheckpointedResources.persistentVolumes();
-
- foreach (const Resource& volume, volumes) {
+ foreach (const Resource& volume, newVolumes) {
// This is validated in master.
CHECK_NE(volume.role(), "*");
@@ -2465,14 +2464,61 @@ void Slave::checkpointResources(const vector<Resource>& _checkpointedResources)
if (!os::exists(path)) {
CHECK_SOME(os::mkdir(path, true))
- << "Failed to create persistent volume at '" << path << "'";
+ << "Failed to create persistent volume '"
+ << volume.disk().persistence().id()
+ << "' at '" << path << "'";
}
}
- // TODO(jieyu): Schedule gc for released persistent volumes. We need
- // to consider dynamic reservation here because the framework can
- // release dynamic reservation while still wants to keep the
- // persistent volume.
+ // If a persistent volume that in the slave's previous checkpointed
+ // resources doesn't appear in the new checkpointed resources, this
+ // implies the volume has been explicitly destroyed. We immediately
+ // remove the filesystem objects for the removed volume. Note that
+ // for MOUNT disks, we don't remove the root directory (mount point)
+ // of the volume.
+ //
+ // TODO(neilc): There is a window during which the filesystem
+ // content for destroyed persistent volumes might be orphaned if we
+ // crash after checkpointing the new resources to disk but before we
+ // finish removing the associated filesystem objects. Particularly
+ // for MOUNT disks, this might result in exposing data from a
+ // previous persistent volume on the disk to a framework that
+ // creates a new volume. We might address this by doing a "cleanup"
+ // operation to remove data from MOUNT disks before creating
+ // persistent volumes on them.
+ Resources oldVolumes = checkpointedResources.persistentVolumes();
+
+ foreach (const Resource& volume, oldVolumes) {
+ if (newVolumes.contains(volume)) {
+ continue;
+ }
+
+ string path = paths::getPersistentVolumePath(flags.work_dir, volume);
+
+ LOG(INFO) << "Deleting persistent volume '"
+ << volume.disk().persistence().id()
+ << "' at '" << path << "'";
+
+ if (!os::exists(path)) {
+ LOG(WARNING) << "Failed to find persistent volume '"
+ << volume.disk().persistence().id()
+ << "' at '" << path << "'";
+ } else {
+ const Resource::DiskInfo::Source& source = volume.disk().source();
+
+ bool removeRoot = true;
+ if (source.type() == Resource::DiskInfo::Source::MOUNT) {
+ removeRoot = false;
+ }
+
+ Try<Nothing> result = os::rmdir(path, true, removeRoot);
+ if (result.isError()) {
+ LOG(ERROR) << "Failed to remove persistent volume '"
+ << volume.disk().persistence().id()
+ << "' at '" << path << "'";
+ }
+ }
+ }
LOG(INFO) << "Updated checkpointed resources from "
<< checkpointedResources << " to "