You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ya...@apache.org on 2017/05/23 07:44:28 UTC

[2/4] mesos git commit: Extract a BasicBlocks class for disk block arithmetic.

Extract a BasicBlocks class for disk block arithmetic.

Extract a BasicBlocks class to handle disk blocks to clarify block-based
arithmetic in the XFS disk isolator.

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


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

Branch: refs/heads/master
Commit: 80b652c3342120cb476fda6d16eb5ba231cab10a
Parents: bb048ec
Author: James Peach <jp...@apache.org>
Authored: Tue May 23 00:34:30 2017 -0700
Committer: Jiang Yan Xu <xu...@apple.com>
Committed: Tue May 23 00:44:23 2017 -0700

----------------------------------------------------------------------
 .../containerizer/mesos/isolators/xfs/utils.cpp | 26 +++++++---------
 .../containerizer/mesos/isolators/xfs/utils.hpp | 32 ++++++++++++++++++++
 src/tests/containerizer/xfs_quota_tests.cpp     | 16 ++++++++++
 3 files changed, 59 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/80b652c3/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/xfs/utils.cpp b/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
index 8018ad3..2708524 100644
--- a/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
+++ b/src/slave/containerizer/mesos/isolators/xfs/utils.cpp
@@ -59,11 +59,6 @@ namespace mesos {
 namespace internal {
 namespace xfs {
 
-// The quota API defines space limits in terms of in basic
-// blocks (512 bytes).
-static constexpr Bytes BASIC_BLOCK_SIZE = Bytes(512u);
-
-
 // Although XFS itself doesn't define any invalid project IDs,
 // we need a way to know whether or not a project ID was assigned
 // so we use 0 as our sentinel value.
@@ -154,12 +149,13 @@ static Try<Nothing> setProjectQuota(
   quota.d_id = projectId;
   quota.d_flags = FS_PROJ_QUOTA;
 
-  // Set both the hard and the soft limit to the same quota, just
-  // for consistency. Functionally all we need is the hard quota.
+  // Set both the hard and the soft limit to the same quota. Functionally
+  // all we need is the hard limit. The soft limit has no effect when it
+  // is the same as the hard limit but we set it for explicitness.
   quota.d_fieldmask = FS_DQ_BSOFT | FS_DQ_BHARD;
 
-  quota.d_blk_hardlimit = limit.bytes() / BASIC_BLOCK_SIZE.bytes();
-  quota.d_blk_softlimit = limit.bytes() / BASIC_BLOCK_SIZE.bytes();
+  quota.d_blk_hardlimit = BasicBlocks(limit).blocks();
+  quota.d_blk_softlimit = BasicBlocks(limit).blocks();
 
   if (::quotactl(QCMD(Q_XSETQLIM, PRJQUOTA),
                  devname.get().c_str(),
@@ -250,8 +246,8 @@ Result<QuotaInfo> getProjectQuota(
   }
 
   QuotaInfo info;
-  info.limit = BASIC_BLOCK_SIZE * quota.d_blk_hardlimit;
-  info.used =  BASIC_BLOCK_SIZE * quota.d_bcount;
+  info.limit = BasicBlocks(quota.d_blk_hardlimit).bytes();
+  info.used = BasicBlocks(quota.d_bcount).bytes();
 
   return info;
 }
@@ -266,10 +262,10 @@ Try<Nothing> setProjectQuota(
     return nonProjectError();
   }
 
-  // A 0 limit deletes the quota record. Since the limit is in basic
-  // blocks that effectively means > 512 bytes.
-  if (limit < BASIC_BLOCK_SIZE) {
-    return Error("Quota limit must be >= " + stringify(BASIC_BLOCK_SIZE));
+  // A 0 limit deletes the quota record. If that's desired, the
+  // caller should use clearProjectQuota().
+  if (limit == 0) {
+    return Error( "Quota limit must be greater than 0");
   }
 
   return internal::setProjectQuota(path, projectId, limit);

http://git-wip-us.apache.org/repos/asf/mesos/blob/80b652c3/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/xfs/utils.hpp b/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
index eddd4c3..e5567c5 100644
--- a/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
+++ b/src/slave/containerizer/mesos/isolators/xfs/utils.hpp
@@ -37,6 +37,38 @@ struct QuotaInfo
 };
 
 
+// Quota operations are defined in terms of basic blocks (512 byte units).
+class BasicBlocks
+{
+public:
+  // Convert from Bytes to basic blocks. Note that we round up since a partial
+  // block costs a full block to store on disk.
+  explicit BasicBlocks(const Bytes& bytes)
+    : blockCount((bytes.bytes() + BASIC_BLOCK_SIZE - 1) / BASIC_BLOCK_SIZE) {}
+
+  explicit constexpr BasicBlocks(uint64_t _blockCount)
+    : blockCount(_blockCount) {}
+
+  bool operator==(const BasicBlocks& that) const
+  {
+    return blockCount == that.blockCount;
+  }
+
+  bool operator!=(const BasicBlocks& that) const
+  {
+    return blockCount != that.blockCount;
+  }
+
+  uint64_t blocks() const { return blockCount; }
+  Bytes bytes() const { return Bytes(BASIC_BLOCK_SIZE) * blockCount; }
+
+private:
+  uint64_t blockCount;
+
+  static constexpr unsigned BASIC_BLOCK_SIZE = 512;
+};
+
+
 inline bool operator==(const QuotaInfo& left, const QuotaInfo& right)
 {
   return left.limit == right.limit && left.used == right.used;

http://git-wip-us.apache.org/repos/asf/mesos/blob/80b652c3/src/tests/containerizer/xfs_quota_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/xfs_quota_tests.cpp b/src/tests/containerizer/xfs_quota_tests.cpp
index 7beb60b..78a8fce 100644
--- a/src/tests/containerizer/xfs_quota_tests.cpp
+++ b/src/tests/containerizer/xfs_quota_tests.cpp
@@ -937,6 +937,22 @@ TEST_F(ROOT_XFS_QuotaTest, CheckQuotaEnabled)
   EXPECT_SOME_EQ(true, xfs::isQuotaEnabled(mountPoint.get()));
 }
 
+
+TEST(XFS_QuotaTest, BasicBlocks)
+{
+  // 0 is the same for blocks and bytes.
+  EXPECT_EQ(BasicBlocks(0).bytes(), Bytes(0u));
+
+  EXPECT_EQ(BasicBlocks(1).bytes(), Bytes(512));
+
+  // A partial block should round up.
+  EXPECT_EQ(Bytes(512), BasicBlocks(Bytes(128)).bytes());
+  EXPECT_EQ(Bytes(1024), BasicBlocks(Bytes(513)).bytes());
+
+  EXPECT_EQ(BasicBlocks(1), BasicBlocks(1));
+  EXPECT_EQ(BasicBlocks(1), BasicBlocks(Bytes(512)));
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {