github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/util/cgroup_util.h (about) 1 // Copyright 2021 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GVISOR_TEST_UTIL_CGROUP_UTIL_H_ 16 #define GVISOR_TEST_UTIL_CGROUP_UTIL_H_ 17 18 #include <unistd.h> 19 20 #include "absl/container/flat_hash_map.h" 21 #include "absl/container/flat_hash_set.h" 22 #include "absl/strings/string_view.h" 23 #include "test/util/cleanup.h" 24 #include "test/util/fs_util.h" 25 #include "test/util/temp_path.h" 26 27 namespace gvisor { 28 namespace testing { 29 30 // Cgroup represents a cgroup directory on a mounted cgroupfs. 31 class Cgroup { 32 public: 33 Cgroup(std::string_view path); 34 35 uint64_t id() const { return id_; } 36 37 const std::string& Path() const { return cgroup_path_; } 38 39 std::string Relpath(absl::string_view leaf) const { 40 return JoinPath(cgroup_path_, leaf); 41 } 42 43 // Returns the contents of a cgroup control file with the given name. 44 PosixErrorOr<std::string> ReadControlFile(absl::string_view name) const; 45 46 // Reads the contents of a cgroup control with the given name, and attempts 47 // to parse it as an integer. 48 PosixErrorOr<int64_t> ReadIntegerControlFile(absl::string_view name) const; 49 50 // Writes a string to a cgroup control file. 51 PosixError WriteControlFile(absl::string_view name, 52 const std::string& value) const; 53 54 // Writes an integer value to a cgroup control file. 55 PosixError WriteIntegerControlFile(absl::string_view name, 56 int64_t value) const; 57 58 // Returns the thread ids of the leaders of thread groups managed by this 59 // cgroup. 60 PosixErrorOr<absl::flat_hash_set<pid_t>> Procs() const; 61 62 PosixErrorOr<absl::flat_hash_set<pid_t>> Tasks() const; 63 64 // ContainsCallingProcess checks whether the calling process is part of the 65 PosixError ContainsCallingProcess() const; 66 67 private: 68 PosixErrorOr<absl::flat_hash_set<pid_t>> ParsePIDList( 69 absl::string_view data) const; 70 71 static int64_t next_id_; 72 int64_t id_; 73 const std::string cgroup_path_; 74 }; 75 76 // Mounter is a utility for creating cgroupfs mounts. It automatically manages 77 // the lifetime of created mounts. 78 class Mounter { 79 public: 80 Mounter(TempPath root) : root_(std::move(root)) {} 81 82 PosixErrorOr<Cgroup> MountCgroupfs(std::string mopts); 83 84 PosixError Unmount(const Cgroup& c); 85 86 void release(const Cgroup& c); 87 88 private: 89 // The destruction order of these members avoids errors during cleanup. We 90 // first unmount (by executing the mounts_ cleanups), then delete the 91 // mountpoint subdirs, then delete the root. 92 TempPath root_; 93 absl::flat_hash_map<int64_t, TempPath> mountpoints_; 94 absl::flat_hash_map<int64_t, Cleanup> mounts_; 95 }; 96 97 // Represents a line from /proc/cgroups. 98 struct CgroupsEntry { 99 std::string subsys_name; 100 uint32_t hierarchy; 101 uint64_t num_cgroups; 102 bool enabled; 103 }; 104 105 // Returns a parsed representation of /proc/cgroups. 106 PosixErrorOr<absl::flat_hash_map<std::string, CgroupsEntry>> 107 ProcCgroupsEntries(); 108 109 // Represents a line from /proc/<pid>/cgroup. 110 struct PIDCgroupEntry { 111 uint32_t hierarchy; 112 std::string controllers; 113 std::string path; 114 }; 115 116 // Returns a parsed representation of /proc/<pid>/cgroup. 117 PosixErrorOr<absl::flat_hash_map<std::string, PIDCgroupEntry>> 118 ProcPIDCgroupEntries(pid_t pid); 119 120 } // namespace testing 121 } // namespace gvisor 122 123 #endif // GVISOR_TEST_UTIL_CGROUP_UTIL_H_