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_