This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new 40e531522 [cgroups] Add Device::Selector::encompasses.
40e531522 is described below

commit 40e531522edc76d6d47b71760ea72c46a0aeb2d5
Author: Jason Zhou <jasonzhou...@gmail.com>
AuthorDate: Wed Jul 24 16:10:49 2024 -0400

    [cgroups] Add Device::Selector::encompasses.
    
    Currently, we have to check via Selector's member variables if the
    devices represented by one Selector encompasses those represented by
    another.
    
    We add a helper function to simplify the logic which differ depending on
    whether one Selector encompasses the other.
    
    Review: https://reviews.apache.org/r/75106/
---
 src/linux/cgroups.cpp                     | 29 +++++++++------
 src/linux/cgroups.hpp                     |  5 ++-
 src/tests/containerizer/cgroups_tests.cpp | 59 +++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/src/linux/cgroups.cpp b/src/linux/cgroups.cpp
index e58c2977a..203a1f6e1 100644
--- a/src/linux/cgroups.cpp
+++ b/src/linux/cgroups.cpp
@@ -2920,16 +2920,7 @@ bool Entry::encompasses(const Entry& other) const
     return true;
   }
 
-  if (selector.major.isSome() && selector.major != other.selector.major) {
-    return false;
-  }
-
-  if (selector.minor.isSome() && selector.minor != other.selector.minor) {
-    return false;
-  }
-
-  if (selector.type != Entry::Selector::Type::ALL
-      && selector.type != other.selector.type) {
+  if (!selector.encompasses(other.selector)) {
     return false;
   }
 
@@ -2960,6 +2951,24 @@ bool Entry::Selector::has_wildcard() const
 }
 
 
+bool Entry::Selector::encompasses(const Entry::Selector& other) const
+{
+  if (type != Entry::Selector::Type::ALL && type != other.type) {
+    return false;
+  }
+
+  if (major.isSome() && major != other.major) {
+    return false;
+  }
+
+  if (minor.isSome() && minor != other.minor) {
+    return false;
+  }
+
+  return true;
+}
+
+
 Try<vector<Entry>> list(const string& hierarchy, const string& cgroup)
 {
   Try<string> read = cgroups::read(hierarchy, cgroup, "devices.list");
diff --git a/src/linux/cgroups.hpp b/src/linux/cgroups.hpp
index c50ec59e3..53bdf9d6a 100644
--- a/src/linux/cgroups.hpp
+++ b/src/linux/cgroups.hpp
@@ -953,8 +953,11 @@ struct Entry
     Option<unsigned int> major; // Matches all `major` numbers if None.
     Option<unsigned int> minor; // Matches all `minor` numbers if None.
 
-    // Returns iff major or minor are wildcards or if type == ALL.
+    // Returns true iff major or minor are wildcards or if type == ALL.
     bool has_wildcard() const;
+
+    // Returns true iff selector encompasses the other selector.
+    bool encompasses(const Selector& other) const;
   };
 
   struct Access
diff --git a/src/tests/containerizer/cgroups_tests.cpp 
b/src/tests/containerizer/cgroups_tests.cpp
index 7e6bb0659..ff8a2ed91 100644
--- a/src/tests/containerizer/cgroups_tests.cpp
+++ b/src/tests/containerizer/cgroups_tests.cpp
@@ -1547,6 +1547,65 @@ TEST(DeviceTest, SelectorWildcardTest)
   EXPECT_FALSE(selector.has_wildcard());
 }
 
+
+TEST(DeviceTest, SelectorEncompassTest)
+{
+  cgroups::devices::Entry::Selector other;
+  other.type = cgroups::devices::Entry::Selector::Type::CHARACTER;
+  other.major = 1;
+  other.minor = 1;
+
+  // Same selector should be encompass each other.
+  cgroups::devices::Entry::Selector selector;
+  selector.type = cgroups::devices::Entry::Selector::Type::CHARACTER;
+  selector.major = 1;
+  selector.minor = 1;
+  EXPECT_TRUE(selector.encompasses(other));
+  EXPECT_TRUE(other.encompasses(selector));
+
+  // Wildcard in type
+  selector.type = cgroups::devices::Entry::Selector::Type::ALL;
+  selector.major = 1;
+  selector.minor = 1;
+  EXPECT_TRUE(selector.encompasses(other));
+  EXPECT_FALSE(other.encompasses(selector));
+
+  // Wildcard in major
+  selector.type = cgroups::devices::Entry::Selector::Type::CHARACTER;
+  selector.major = Option<unsigned int>::none();
+  selector.minor = 1;
+  EXPECT_TRUE(selector.encompasses(other));
+  EXPECT_FALSE(other.encompasses(selector));
+
+  // Wildcard in minor
+  selector.type = cgroups::devices::Entry::Selector::Type::CHARACTER;
+  selector.major = 1;
+  selector.minor = Option<unsigned int>::none();
+  EXPECT_TRUE(selector.encompasses(other));
+  EXPECT_FALSE(other.encompasses(selector));
+
+  // Mismatch in type
+  selector.type = cgroups::devices::Entry::Selector::Type::BLOCK;
+  selector.major = Option<unsigned int>::none();
+  selector.minor = Option<unsigned int>::none();
+  EXPECT_FALSE(selector.encompasses(other));
+  EXPECT_FALSE(other.encompasses(selector));
+
+  // Mismatch in major
+  selector.type = cgroups::devices::Entry::Selector::Type::ALL;
+  selector.major = 2;
+  selector.minor = Option<unsigned int>::none();
+  EXPECT_FALSE(selector.encompasses(other));
+  EXPECT_FALSE(other.encompasses(selector));
+
+  // Mismatch in minor
+  selector.type = cgroups::devices::Entry::Selector::Type::ALL;
+  selector.major = Option<unsigned int>::none();
+  selector.minor = 2;
+  EXPECT_FALSE(selector.encompasses(other));
+  EXPECT_FALSE(other.encompasses(selector));
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

Reply via email to