liboj_cgroups/subsystem/
freezer.rs1use std::fs;
2use std::io;
3use std::path::Path;
4use std::str::FromStr;
5
6use super::Controller;
7use crate::{
8 attr_file::{AttrFile, ReadAttr, WriteAttr},
9 hierarchy::HierarchyNode,
10};
11
12#[derive(PartialEq, Eq, Debug)]
13pub enum State {
14 Thawed,
15 Freezing,
16 Frozen,
17}
18
19impl FromStr for State {
20 type Err = io::Error;
21
22 fn from_str(s: &str) -> io::Result<State> {
23 match s {
24 "THAWED" => Ok(State::Thawed),
25 "FREEZING" => Ok(State::Freezing),
26 "FROZEN" => Ok(State::Frozen),
27 _ => Err(io::Error::new(
28 io::ErrorKind::InvalidData,
29 format!("failed to parse cgroup freezer state \"{}\"", s),
30 )),
31 }
32 }
33}
34
35pub trait FreezerController: Controller {
36 fn state(&self) -> Box<dyn '_ + AttrFile<State>>;
37 fn self_freezing(&self) -> Box<dyn '_ + ReadAttr<bool>>;
38 fn parent_freezing(&self) -> Box<dyn '_ + ReadAttr<bool>>;
39}
40
41impl FreezerController for HierarchyNode {
42 fn state(&self) -> Box<dyn '_ + AttrFile<State>> {
43 let file = self.as_path().join("freezer.state");
44 Box::new(StateFile(file))
45 }
46
47 fn self_freezing(&self) -> Box<dyn '_ + ReadAttr<bool>> {
48 let file = self.as_path().join("freezer.self_freezing");
49 Box::new(FreezingFile(file))
50 }
51
52 fn parent_freezing(&self) -> Box<dyn '_ + ReadAttr<bool>> {
53 let file = self.as_path().join("freezer.parent_freezing");
54 Box::new(FreezingFile(file))
55 }
56}
57
58struct StateFile<P: AsRef<Path>>(P);
59
60impl<P: AsRef<Path>> ReadAttr<State> for StateFile<P> {
61 fn read(&self) -> io::Result<State> {
62 let s = fs::read_to_string(&self.0)?;
63 Ok(s.trim().parse()?)
64 }
65}
66
67impl<P: AsRef<Path>> WriteAttr<State> for StateFile<P> {
68 fn write(&self, state: &State) -> io::Result<()> {
69 let file = self.0.as_ref();
70 match state {
71 State::Thawed => fs::write(&file, "THAWED"),
72 State::Frozen => fs::write(&file, "FROZEN"),
73 State::Freezing => Err(io::Error::new(
74 io::ErrorKind::InvalidData,
75 format!("can not write FREEZING state to {}", file.display()),
76 )),
77 }
78 }
79}
80
81struct FreezingFile<P: AsRef<Path>>(P);
82
83impl<P: AsRef<Path>> ReadAttr<bool> for FreezingFile<P> {
84 fn read(&self) -> io::Result<bool> {
85 let file = self.0.as_ref();
86 let s = fs::read_to_string(&file)?;
87 match s.trim() {
88 "0" => Ok(false),
89 "1" => Ok(true),
90 _ => Err(io::Error::new(
91 io::ErrorKind::InvalidData,
92 format!("failed to parse freezing state from {}", file.display()),
93 )),
94 }
95 }
96}