cgroups_rs/systemd/
props.rs1use zbus::zvariant::Value as ZbusValue;
7
8use crate::fs::hierarchies;
9use crate::systemd::utils::is_slice_unit;
10use crate::systemd::{
11 BLOCK_IO_ACCOUNTING, CPU_ACCOUNTING, DEFAULT_DEPENDENCIES, DEFAULT_DESCRIPTION, DELEGATE,
12 DESCRIPTION, IO_ACCOUNTING, MEMORY_ACCOUNTING, PIDS, SLICE, TASKS_ACCOUNTING,
13 TIMEOUT_STOP_USEC, WANTS,
14};
15
16pub type Property<'a> = (&'a str, ZbusValue<'a>);
17
18#[derive(Debug, Clone, Default)]
19pub struct PropertiesBuilder {
20 cpu_accounting: Option<bool>,
21 memory_accounting: Option<bool>,
25 task_accounting: Option<bool>,
26 io_accounting: Option<bool>,
28 default_dependencies: Option<bool>,
29 description: Option<String>,
30 wants: Option<String>,
31 slice: Option<String>,
32 delegate: Option<bool>,
33 pids: Option<Vec<u32>>,
34 timeout_stop_usec: Option<u64>,
35}
36
37impl PropertiesBuilder {
38 pub fn default_cgroup(slice: &str, unit: &str) -> Self {
39 let mut builder = Self::default()
40 .cpu_accounting(true)
41 .memory_accounting(true)
42 .task_accounting(true)
43 .io_accounting(true)
44 .default_dependencies(false)
45 .description(format!("{} {}:{}", DEFAULT_DESCRIPTION, slice, unit));
46
47 if is_slice_unit(unit) {
48 builder = builder.wants(slice.to_string());
50 } else {
51 builder = builder.slice(slice.to_string());
53 builder = builder.delegate(true);
55 }
56
57 builder
58 }
59
60 pub fn cpu_accounting(mut self, enabled: bool) -> Self {
61 self.cpu_accounting = Some(enabled);
62 self
63 }
64
65 pub fn memory_accounting(mut self, enabled: bool) -> Self {
66 self.memory_accounting = Some(enabled);
67 self
68 }
69
70 pub fn task_accounting(mut self, enabled: bool) -> Self {
71 self.task_accounting = Some(enabled);
72 self
73 }
74
75 pub fn io_accounting(mut self, enabled: bool) -> Self {
76 self.io_accounting = Some(enabled);
77 self
78 }
79
80 pub fn default_dependencies(mut self, enabled: bool) -> Self {
81 self.default_dependencies = Some(enabled);
82 self
83 }
84
85 pub fn description(mut self, desc: String) -> Self {
86 self.description = Some(desc);
87 self
88 }
89
90 pub fn wants(mut self, wants: String) -> Self {
91 self.wants = Some(wants);
92 self
93 }
94
95 pub fn slice(mut self, slice: String) -> Self {
96 self.slice = Some(slice);
97 self
98 }
99
100 pub fn delegate(mut self, enabled: bool) -> Self {
101 self.delegate = Some(enabled);
102 self
103 }
104
105 pub fn pids(mut self, pids: Vec<u32>) -> Self {
106 self.pids = Some(pids);
107 self
108 }
109
110 pub fn timeout_stop_usec(mut self, timeout: u64) -> Self {
111 self.timeout_stop_usec = Some(timeout);
112 self
113 }
114
115 pub fn build(self) -> Vec<Property<'static>> {
116 let mut props = vec![];
117
118 if let Some(cpu_accounting) = self.cpu_accounting {
119 props.push((CPU_ACCOUNTING, ZbusValue::Bool(cpu_accounting)));
120 }
121
122 if let Some(memory_accounting) = self.memory_accounting {
123 props.push((MEMORY_ACCOUNTING, ZbusValue::Bool(memory_accounting)));
124 }
125
126 if let Some(task_accounting) = self.task_accounting {
127 props.push((TASKS_ACCOUNTING, ZbusValue::Bool(task_accounting)));
128 }
129
130 if let Some(io_accounting) = self.io_accounting {
131 if hierarchies::is_cgroup2_unified_mode() {
132 props.push((IO_ACCOUNTING, ZbusValue::Bool(io_accounting)));
133 } else {
134 props.push((BLOCK_IO_ACCOUNTING, ZbusValue::Bool(io_accounting)));
135 }
136 }
137
138 if let Some(default_dependencies) = self.default_dependencies {
139 props.push((DEFAULT_DEPENDENCIES, ZbusValue::Bool(default_dependencies)));
140 }
141
142 if let Some(description) = self.description {
143 props.push((DESCRIPTION, ZbusValue::Str(description.into())));
144 } else {
145 props.push((DESCRIPTION, ZbusValue::Str(DEFAULT_DESCRIPTION.into())));
146 }
147
148 if let Some(wants) = self.wants {
149 props.push((WANTS, ZbusValue::Str(wants.into())));
150 }
151
152 if let Some(slice) = self.slice {
153 props.push((SLICE, ZbusValue::Str(slice.into())));
154 }
155
156 if let Some(delegate) = self.delegate {
157 props.push((DELEGATE, ZbusValue::Bool(delegate)));
158 }
159
160 if let Some(pids) = self.pids {
161 props.push((PIDS, ZbusValue::Array(pids.into())));
162 }
163
164 if let Some(timeout) = self.timeout_stop_usec {
165 props.push((TIMEOUT_STOP_USEC, ZbusValue::U64(timeout)));
166 }
167
168 props
169 }
170}