1use std::io::{Read, Write};
12use std::path::PathBuf;
13
14use crate::fs::error::ErrorKind::*;
15use crate::fs::error::*;
16
17use crate::fs::read_u64_from;
18use crate::fs::{
19 parse_max_value, ControllIdentifier, ControllerInternal, Controllers, MaxValue, PidResources,
20 Resources, Subsystem,
21};
22
23#[derive(Debug, Clone)]
25pub struct PidController {
26 base: PathBuf,
27 path: PathBuf,
28 v2: bool,
29}
30
31impl ControllerInternal for PidController {
32 fn control_type(&self) -> Controllers {
33 Controllers::Pids
34 }
35 fn get_path(&self) -> &PathBuf {
36 &self.path
37 }
38 fn get_path_mut(&mut self) -> &mut PathBuf {
39 &mut self.path
40 }
41 fn get_base(&self) -> &PathBuf {
42 &self.base
43 }
44
45 fn is_v2(&self) -> bool {
46 self.v2
47 }
48
49 fn apply(&self, res: &Resources) -> Result<()> {
50 let pidres: &PidResources = &res.pid;
52
53 update_and_test!(
55 self,
56 set_pid_max,
57 pidres.maximum_number_of_processes,
58 get_pid_max
59 );
60
61 Ok(())
62 }
63}
64
65impl ControllIdentifier for PidController {
72 fn controller_type() -> Controllers {
73 Controllers::Pids
74 }
75}
76
77impl<'a> From<&'a Subsystem> for &'a PidController {
78 fn from(sub: &'a Subsystem) -> &'a PidController {
79 unsafe {
80 match sub {
81 Subsystem::Pid(c) => c,
82 _ => {
83 assert_eq!(1, 0);
84 let v = std::mem::MaybeUninit::uninit();
85 v.assume_init()
86 }
87 }
88 }
89 }
90}
91
92impl PidController {
93 pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self {
96 Self {
97 base: root,
98 path: point,
99 v2,
100 }
101 }
102
103 pub fn get_pid_events(&self) -> Result<u64> {
105 self.open_path("pids.events", false).and_then(|mut file| {
106 let mut string = String::new();
107 match file.read_to_string(&mut string) {
108 Ok(_) => match string.split_whitespace().nth(1) {
109 Some(elem) => match elem.parse() {
110 Ok(val) => Ok(val),
111 Err(e) => Err(Error::with_cause(ParseError, e)),
112 },
113 None => Err(Error::new(ParseError)),
114 },
115 Err(e) => Err(Error::with_cause(ReadFailed("pids.events".to_string()), e)),
116 }
117 })
118 }
119
120 pub fn get_pid_current(&self) -> Result<u64> {
122 self.open_path("pids.current", false)
123 .and_then(read_u64_from)
124 }
125
126 pub fn get_pid_max(&self) -> Result<MaxValue> {
128 self.open_path("pids.max", false).and_then(|mut file| {
129 let mut string = String::new();
130 let res = file.read_to_string(&mut string);
131 match res {
132 Ok(_) => parse_max_value(&string),
133 Err(e) => Err(Error::with_cause(ReadFailed("pids.max".to_string()), e)),
134 }
135 })
136 }
137
138 pub fn set_pid_max(&self, max_pid: MaxValue) -> Result<()> {
144 self.open_path("pids.max", true).and_then(|mut file| {
145 let string_to_write = max_pid.to_string();
146 match file.write_all(string_to_write.as_ref()) {
147 Ok(_) => Ok(()),
148 Err(e) => Err(Error::with_cause(
149 WriteFailed("pids.max".to_string(), format!("{:?}", max_pid)),
150 e,
151 )),
152 }
153 })
154 }
155}