1 // Copyright 2024, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! This module provides policies to manage zram features.
16 
17 pub mod idle;
18 pub mod recompression;
19 pub mod setup;
20 pub mod stats;
21 pub mod writeback;
22 
23 use std::io;
24 
25 // Files for zram general information
26 const ZRAM_DISKSIZE_PATH: &str = "/sys/block/zram0/disksize";
27 const ZRAM_MM_STAT_PATH: &str = "/sys/block/zram0/mm_stat";
28 
29 // Files for memory tracking
30 const ZRAM_IDLE_PATH: &str = "/sys/block/zram0/idle";
31 
32 // Files for writeback
33 const ZRAM_BACKING_DEV_PATH: &str = "/sys/block/zram0/backing_dev";
34 const ZRAM_WRITEBACK_PATH: &str = "/sys/block/zram0/writeback";
35 const ZRAM_WRITEBACK_LIMIT_PATH: &str = "/sys/block/zram0/writeback_limit";
36 const ZRAM_BD_STAT_PATH: &str = "/sys/block/zram0/bd_stat";
37 
38 // Files for recompression
39 const ZRAM_RECOMP_ALGORITHM_PATH: &str = "/sys/block/zram0/recomp_algorithm";
40 const ZRAM_RECOMPRESS_PATH: &str = "/sys/block/zram0/recompress";
41 
42 /// [SysfsZramApi] is a mockable interface for access to files under
43 /// "/sys/block/zram0" which is system global.
44 ///
45 /// The naming convention: functions for files which is readable and writable
46 ///
47 /// * fn read_<file_name>() -> io::Result<String>
48 /// * fn write_<file_name>(contents: &str) -> io::Result<()>
49 ///
50 /// We don't have naming conventions for files which is writable only.
51 #[cfg_attr(test, mockall::automock)]
52 pub trait SysfsZramApi {
53     /// Read "/sys/block/zram0/disksize".
read_disksize() -> io::Result<String>54     fn read_disksize() -> io::Result<String>;
55     /// Write "/sys/block/zram0/disksize".
write_disksize(contents: &str) -> io::Result<()>56     fn write_disksize(contents: &str) -> io::Result<()>;
57     /// Read "/sys/block/zram0/mm_stat".
read_mm_stat() -> io::Result<String>58     fn read_mm_stat() -> io::Result<String>;
59 
60     /// Write contents to "/sys/block/zram0/idle".
set_idle(contents: &str) -> io::Result<()>61     fn set_idle(contents: &str) -> io::Result<()>;
62 
63     /// Read "/sys/block/zram0/backing_dev".
read_backing_dev() -> io::Result<String>64     fn read_backing_dev() -> io::Result<String>;
65     /// Write contents to "/sys/block/zram0/writeback".
writeback(contents: &str) -> io::Result<()>66     fn writeback(contents: &str) -> io::Result<()>;
67     /// Write contents to "/sys/block/zram0/writeback_limit".
write_writeback_limit(contents: &str) -> io::Result<()>68     fn write_writeback_limit(contents: &str) -> io::Result<()>;
69     /// Read "/sys/block/zram0/writeback_limit".
read_writeback_limit() -> io::Result<String>70     fn read_writeback_limit() -> io::Result<String>;
71     /// Read "/sys/block/zram0/bd_stat".
read_bd_stat() -> io::Result<String>72     fn read_bd_stat() -> io::Result<String>;
73 
74     /// Read "/sys/block/zram0/recomp_algorithm".
read_recomp_algorithm() -> io::Result<String>75     fn read_recomp_algorithm() -> io::Result<String>;
76     /// Write contents to "/sys/block/zram0/recompress".
recompress(contents: &str) -> io::Result<()>77     fn recompress(contents: &str) -> io::Result<()>;
78 }
79 
80 /// The implementation of [SysfsZramApi].
81 pub struct SysfsZramApiImpl;
82 
83 impl SysfsZramApi for SysfsZramApiImpl {
read_disksize() -> io::Result<String>84     fn read_disksize() -> io::Result<String> {
85         std::fs::read_to_string(ZRAM_DISKSIZE_PATH)
86     }
87 
write_disksize(contents: &str) -> io::Result<()>88     fn write_disksize(contents: &str) -> io::Result<()> {
89         std::fs::write(ZRAM_DISKSIZE_PATH, contents)
90     }
91 
read_mm_stat() -> io::Result<String>92     fn read_mm_stat() -> io::Result<String> {
93         std::fs::read_to_string(ZRAM_MM_STAT_PATH)
94     }
95 
set_idle(contents: &str) -> io::Result<()>96     fn set_idle(contents: &str) -> io::Result<()> {
97         std::fs::write(ZRAM_IDLE_PATH, contents)
98     }
99 
read_backing_dev() -> io::Result<String>100     fn read_backing_dev() -> io::Result<String> {
101         std::fs::read_to_string(ZRAM_BACKING_DEV_PATH)
102     }
103 
writeback(contents: &str) -> io::Result<()>104     fn writeback(contents: &str) -> io::Result<()> {
105         std::fs::write(ZRAM_WRITEBACK_PATH, contents)
106     }
107 
write_writeback_limit(contents: &str) -> io::Result<()>108     fn write_writeback_limit(contents: &str) -> io::Result<()> {
109         std::fs::write(ZRAM_WRITEBACK_LIMIT_PATH, contents)
110     }
111 
read_writeback_limit() -> io::Result<String>112     fn read_writeback_limit() -> io::Result<String> {
113         std::fs::read_to_string(ZRAM_WRITEBACK_LIMIT_PATH)
114     }
115 
read_bd_stat() -> io::Result<String>116     fn read_bd_stat() -> io::Result<String> {
117         std::fs::read_to_string(ZRAM_BD_STAT_PATH)
118     }
119 
read_recomp_algorithm() -> io::Result<String>120     fn read_recomp_algorithm() -> io::Result<String> {
121         std::fs::read_to_string(ZRAM_RECOMP_ALGORITHM_PATH)
122     }
123 
recompress(contents: &str) -> io::Result<()>124     fn recompress(contents: &str) -> io::Result<()> {
125         std::fs::write(ZRAM_RECOMPRESS_PATH, contents)
126     }
127 }
128 
129 /// Mutex to synchronize tests using [MockSysfsZramApi].
130 ///
131 /// mockall for static functions requires synchronization.
132 ///
133 /// https://docs.rs/mockall/latest/mockall/#static-methods
134 #[cfg(test)]
135 pub static ZRAM_API_MTX: std::sync::Mutex<()> = std::sync::Mutex::new(());
136