1use std::io::Write;
11use std::path::PathBuf;
12
13use crate::fs::error::ErrorKind::*;
14use crate::fs::error::*;
15
16use crate::fs::{read_string_from, read_u64_from};
17use crate::fs::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem};
18
19#[derive(Debug, Clone)]
24pub struct CpuAcctController {
25 base: PathBuf,
26 path: PathBuf,
27}
28
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub struct CpuAcct {
32 pub stat: String,
34 pub usage: u64,
36 pub usage_all: String,
48 pub usage_percpu: String,
51 pub usage_percpu_sys: String,
53 pub usage_percpu_user: String,
55 pub usage_sys: u64,
57 pub usage_user: u64,
59}
60
61impl ControllerInternal for CpuAcctController {
62 fn control_type(&self) -> Controllers {
63 Controllers::CpuAcct
64 }
65 fn get_path(&self) -> &PathBuf {
66 &self.path
67 }
68 fn get_path_mut(&mut self) -> &mut PathBuf {
69 &mut self.path
70 }
71 fn get_base(&self) -> &PathBuf {
72 &self.base
73 }
74
75 fn apply(&self, _res: &Resources) -> Result<()> {
76 Ok(())
77 }
78}
79
80impl ControllIdentifier for CpuAcctController {
81 fn controller_type() -> Controllers {
82 Controllers::CpuAcct
83 }
84}
85
86impl<'a> From<&'a Subsystem> for &'a CpuAcctController {
87 fn from(sub: &'a Subsystem) -> &'a CpuAcctController {
88 unsafe {
89 match sub {
90 Subsystem::CpuAcct(c) => c,
91 _ => {
92 assert_eq!(1, 0);
93 let v = std::mem::MaybeUninit::uninit();
94 v.assume_init()
95 }
96 }
97 }
98 }
99}
100
101impl CpuAcctController {
102 pub fn new(point: PathBuf, root: PathBuf) -> Self {
104 Self {
105 base: root,
106 path: point,
107 }
108 }
109
110 pub fn cpuacct(&self) -> CpuAcct {
112 CpuAcct {
113 stat: self
114 .open_path("cpuacct.stat", false)
115 .and_then(read_string_from)
116 .unwrap_or_default(),
117 usage: self
118 .open_path("cpuacct.usage", false)
119 .and_then(read_u64_from)
120 .unwrap_or(0),
121 usage_all: self
122 .open_path("cpuacct.usage_all", false)
123 .and_then(read_string_from)
124 .unwrap_or_default(),
125 usage_percpu: self
126 .open_path("cpuacct.usage_percpu", false)
127 .and_then(read_string_from)
128 .unwrap_or_default(),
129 usage_percpu_sys: self
130 .open_path("cpuacct.usage_percpu_sys", false)
131 .and_then(read_string_from)
132 .unwrap_or_default(),
133 usage_percpu_user: self
134 .open_path("cpuacct.usage_percpu_user", false)
135 .and_then(read_string_from)
136 .unwrap_or_default(),
137 usage_sys: self
138 .open_path("cpuacct.usage_sys", false)
139 .and_then(read_u64_from)
140 .unwrap_or(0),
141 usage_user: self
142 .open_path("cpuacct.usage_user", false)
143 .and_then(read_u64_from)
144 .unwrap_or(0),
145 }
146 }
147
148 pub fn reset(&self) -> Result<()> {
150 self.open_path("cpuacct.usage", true).and_then(|mut file| {
151 file.write_all(b"0").map_err(|e| {
152 Error::with_cause(WriteFailed("cpuacct.usage".to_string(), "0".to_string()), e)
153 })
154 })
155 }
156}