1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use std::path::{Path, PathBuf};
use blkio::BlkIoController;
use cpu::CpuController;
use cpuacct::CpuAcctController;
use cpuset::CpuSetController;
use devices::DevicesController;
use freezer::FreezerController;
use hugetlb::HugeTlbController;
use memory::MemController;
use net_cls::NetClsController;
use net_prio::NetPrioController;
use perf_event::PerfEventController;
use pid::PidController;
use rdma::RdmaController;
use {Controllers, Hierarchy, Subsystem};
use cgroup::Cgroup;
pub struct V1 {
mount_point: String,
}
impl Hierarchy for V1 {
fn subsystems(&self) -> Vec<Subsystem> {
let mut subs = vec![];
if self.check_support(Controllers::Pids) {
subs.push(Subsystem::Pid(PidController::new(self.root())));
}
if self.check_support(Controllers::Mem) {
subs.push(Subsystem::Mem(MemController::new(self.root())));
}
if self.check_support(Controllers::CpuSet) {
subs.push(Subsystem::CpuSet(CpuSetController::new(self.root())));
}
if self.check_support(Controllers::CpuAcct) {
subs.push(Subsystem::CpuAcct(CpuAcctController::new(self.root())));
}
if self.check_support(Controllers::Cpu) {
subs.push(Subsystem::Cpu(CpuController::new(self.root())));
}
if self.check_support(Controllers::Devices) {
subs.push(Subsystem::Devices(DevicesController::new(self.root())));
}
if self.check_support(Controllers::Freezer) {
subs.push(Subsystem::Freezer(FreezerController::new(self.root())));
}
if self.check_support(Controllers::NetCls) {
subs.push(Subsystem::NetCls(NetClsController::new(self.root())));
}
if self.check_support(Controllers::BlkIo) {
subs.push(Subsystem::BlkIo(BlkIoController::new(self.root())));
}
if self.check_support(Controllers::PerfEvent) {
subs.push(Subsystem::PerfEvent(PerfEventController::new(self.root())));
}
if self.check_support(Controllers::NetPrio) {
subs.push(Subsystem::NetPrio(NetPrioController::new(self.root())));
}
if self.check_support(Controllers::HugeTlb) {
subs.push(Subsystem::HugeTlb(HugeTlbController::new(self.root())));
}
if self.check_support(Controllers::Rdma) {
subs.push(Subsystem::Rdma(RdmaController::new(self.root())));
}
subs
}
fn root_control_group(&self) -> Cgroup {
Cgroup::load(self, "".to_string())
}
fn check_support(&self, sub: Controllers) -> bool {
let root = self.root().read_dir().unwrap();
for entry in root {
if let Ok(entry) = entry {
if entry.file_name().into_string().unwrap() == sub.to_string() {
return true;
}
}
}
return false;
}
fn root(&self) -> PathBuf {
PathBuf::from(self.mount_point.clone())
}
}
impl V1 {
pub fn new() -> Self {
let mount_point = find_v1_mount().unwrap();
V1 {
mount_point: mount_point,
}
}
}
fn find_v1_mount() -> Option<String> {
let mountinfo_path = Path::new("/proc/self/mountinfo");
if mountinfo_path.exists() == false {
return None;
}
let mountinfo_file = File::open(mountinfo_path).unwrap();
let mountinfo_reader = BufReader::new(&mountinfo_file);
for _line in mountinfo_reader.lines() {
let line = _line.unwrap();
let mut fields = line.split_whitespace();
let index = line.find(" - ").unwrap();
let mut more_fields = line[index + 3..].split_whitespace().collect::<Vec<_>>();
let fstype = more_fields[0];
if fstype == "tmpfs" && more_fields[2].contains("ro") {
let cgroups_mount = fields.nth(4).unwrap();
info!("found cgroups at {:?}", cgroups_mount);
return Some(cgroups_mount.to_string());
}
}
None
}