1use std::io::{Read, Write};
12use std::path::PathBuf;
13
14use crate::fs::error::ErrorKind::*;
15use crate::fs::error::*;
16use crate::fs::{ControllIdentifier, ControllerInternal, Controllers, Resources, Subsystem};
17use crate::FreezerState;
18
19#[derive(Debug, Clone)]
28pub struct FreezerController {
29 base: PathBuf,
30 path: PathBuf,
31 v2: bool,
32}
33
34impl ControllerInternal for FreezerController {
35 fn control_type(&self) -> Controllers {
36 Controllers::Freezer
37 }
38 fn get_path(&self) -> &PathBuf {
39 &self.path
40 }
41 fn get_path_mut(&mut self) -> &mut PathBuf {
42 &mut self.path
43 }
44 fn get_base(&self) -> &PathBuf {
45 &self.base
46 }
47
48 fn apply(&self, _res: &Resources) -> Result<()> {
49 Ok(())
50 }
51}
52
53impl ControllIdentifier for FreezerController {
54 fn controller_type() -> Controllers {
55 Controllers::Freezer
56 }
57}
58
59impl<'a> From<&'a Subsystem> for &'a FreezerController {
60 fn from(sub: &'a Subsystem) -> &'a FreezerController {
61 unsafe {
62 match sub {
63 Subsystem::Freezer(c) => c,
64 _ => {
65 assert_eq!(1, 0);
66 let v = std::mem::MaybeUninit::uninit();
67 v.assume_init()
68 }
69 }
70 }
71 }
72}
73
74impl FreezerController {
75 pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self {
77 Self {
78 base: root,
79 path: point,
80 v2,
81 }
82 }
83 pub fn freeze(&self) -> Result<()> {
85 let mut file_name = "freezer.state";
86 let mut content = "FROZEN".to_string();
87 if self.v2 {
88 file_name = "cgroup.freeze";
89 content = "1".to_string();
90 }
91
92 self.open_path(file_name, true).and_then(|mut file| {
93 file.write_all(content.as_ref())
94 .map_err(|e| Error::with_cause(WriteFailed(file_name.to_string(), content), e))
95 })
96 }
97
98 pub fn thaw(&self) -> Result<()> {
100 let mut file_name = "freezer.state";
101 let mut content = "THAWED".to_string();
102 if self.v2 {
103 file_name = "cgroup.freeze";
104 content = "0".to_string();
105 }
106 self.open_path(file_name, true).and_then(|mut file| {
107 file.write_all(content.as_ref())
108 .map_err(|e| Error::with_cause(WriteFailed(file_name.to_string(), content), e))
109 })
110 }
111
112 pub fn state(&self) -> Result<FreezerState> {
114 let mut file_name = "freezer.state";
115 if self.v2 {
116 file_name = "cgroup.freeze";
117 }
118 self.open_path(file_name, false).and_then(|mut file| {
119 let mut s = String::new();
120 let res = file.read_to_string(&mut s);
121 match res {
122 Ok(_) => match s.trim() {
123 "FROZEN" => Ok(FreezerState::Frozen),
124 "THAWED" => Ok(FreezerState::Thawed),
125 "1" => Ok(FreezerState::Frozen),
126 "0" => Ok(FreezerState::Thawed),
127 "FREEZING" => Ok(FreezerState::Freezing),
128 _ => Err(Error::new(ParseError)),
129 },
130 Err(e) => Err(Error::with_cause(ReadFailed(file_name.to_string()), e)),
131 }
132 })
133 }
134}