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 2018/09/05 23:45:35 UTC
[mesos] 03/03: Exposed an XFS helper to find the block device for a
given path.
This is an automated email from the ASF dual-hosted git repository.
jpeach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 6a933e780a2bd835b31c6420ad23d86de94f77ac
Author: James Peach <jp...@apache.org>
AuthorDate: Wed Sep 5 15:11:34 2018 -0700
Exposed an XFS helper to find the block device for a given path.
To manage persistent volumes in the `disk/xfs` isolator we need
to keep track of the block device that hosts a given filesystem
path. Expose the `getDeviceForPath` helper API to directly return
this information.
Review: https://reviews.apache.org/r/68400/
---
.../containerizer/mesos/isolators/xfs/utils.cpp | 8 ++++---
.../containerizer/mesos/isolators/xfs/utils.hpp | 6 +++++
src/tests/containerizer/xfs_quota_tests.cpp | 27 ++++++++++++++++++----
3 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/src/slave/containerizer/mesos/isolators/xfs/utils.cpp b/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
index b691c76..d5d0377 100644
--- a/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
+++ b/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
@@ -107,9 +107,7 @@ static Try<struct fsxattr> getAttributes(int fd)
}
-// Return the path of the device backing the filesystem containing
-// the given path.
-static Try<string> getDeviceForPath(const string& path)
+Try<string> getDeviceForPath(const string& path)
{
struct stat statbuf;
@@ -117,6 +115,10 @@ static Try<string> getDeviceForPath(const string& path)
return ErrnoError("Unable to access '" + path + "'");
}
+ if (S_ISBLK(statbuf.st_mode)) {
+ return path;
+ }
+
char* name = blkid_devno_to_devname(statbuf.st_dev);
if (name == nullptr) {
return ErrnoError("Unable to get device for '" + path + "'");
diff --git a/src/slave/containerizer/mesos/isolators/xfs/utils.hpp b/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
index e269eb5..db1829a 100644
--- a/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
+++ b/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
@@ -98,6 +98,12 @@ bool isPathXfs(const std::string& path);
Try<bool> isQuotaEnabled(const std::string& path);
+// Return the path of the block device backing the given path. If the path
+// is a filesystem path, then the corresponding block device is resolved. If
+// the path is already a block device path, then the same path is returned.
+Try<std::string> getDeviceForPath(const std::string& path);
+
+
Result<QuotaInfo> getProjectQuota(
const std::string& path,
prid_t projectId);
diff --git a/src/tests/containerizer/xfs_quota_tests.cpp b/src/tests/containerizer/xfs_quota_tests.cpp
index 59ec182..2b3a2e2 100644
--- a/src/tests/containerizer/xfs_quota_tests.cpp
+++ b/src/tests/containerizer/xfs_quota_tests.cpp
@@ -289,14 +289,18 @@ TEST_F(ROOT_XFS_QuotaTest, QuotaGetSet)
ASSERT_SOME(os::mkdir(root));
EXPECT_SOME(setProjectQuota(root, projectId, limit));
+ EXPECT_SOME_EQ(
+ makeQuotaInfo(limit, 0 /* used */),
+ getProjectQuota(root, projectId));
- Result<QuotaInfo> info = getProjectQuota(root, projectId);
- ASSERT_SOME(info);
+ EXPECT_SOME(clearProjectQuota(root, projectId));
- EXPECT_EQ(limit, info->hardLimit);
- EXPECT_EQ(Bytes(0), info->used);
+ // After we clear the quota, the quota record is removed and we will get
+ // ENOENT trying to read it back.
+ EXPECT_ERROR(getProjectQuota(root, projectId));
- EXPECT_SOME(clearProjectQuota(root, projectId));
+ EXPECT_SOME_EQ(loopDevice, getDeviceForPath(root));
+ EXPECT_SOME_EQ(loopDevice, getDeviceForPath(loopDevice.get()));
}
@@ -328,6 +332,19 @@ TEST_F(ROOT_XFS_QuotaTest, QuotaLimit)
EXPECT_ERROR(mkfile(path::join(root, "file2"), Megabytes(2)));
EXPECT_SOME(clearProjectQuota(root, projectId));
+
+ // Since this project ID still consumes space, there should still
+ // be a quota record. However, the limits should be cleared.
+ Result<QuotaInfo> info = getProjectQuota(root, projectId);
+ ASSERT_SOME(info);
+
+ EXPECT_EQ(Bytes(0), info->softLimit);
+ EXPECT_EQ(Bytes(0), info->hardLimit);
+
+ // We use LE here because we know that the 10MB write succeeded but
+ // the 2MB write did not. We could end up using 10MB if the second
+ // write atomically failed, or 11MB if it partially succeeded.
+ EXPECT_LE(used, info->used);
}