1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use crate::{FileWrapper, ProcResult};
use std::io::{BufRead, BufReader};
#[derive(Debug)]
pub struct DiskStat {
pub major: i32,
pub minor: i32,
pub name: String,
pub reads: usize,
pub merged: usize,
pub sectors_read: usize,
pub time_reading: usize,
pub writes: usize,
pub writes_merged: usize,
pub sectors_written: usize,
pub time_writing: usize,
pub in_progress: usize,
pub time_in_progress: usize,
pub weighted_time_in_progress: usize,
pub discards: Option<usize>,
pub discards_merged: Option<usize>,
pub sectors_discarded: Option<usize>,
pub time_discarding: Option<usize>,
pub flushes: Option<usize>,
pub time_flushing: Option<usize>,
}
pub fn diskstats() -> ProcResult<Vec<DiskStat>> {
let file = FileWrapper::open("/proc/diskstats")?;
let reader = BufReader::new(file);
let mut v = Vec::new();
for line in reader.lines() {
let line = line?;
v.push(DiskStat::from_line(&line)?);
}
Ok(v)
}
impl DiskStat {
pub fn from_line(line: &str) -> ProcResult<DiskStat> {
let mut s = line.trim().split_whitespace();
let major = from_str!(i32, expect!(s.next()));
let minor = from_str!(i32, expect!(s.next()));
let name = expect!(s.next()).to_string();
let reads = from_str!(usize, expect!(s.next()));
let merged = from_str!(usize, expect!(s.next()));
let sectors_read = from_str!(usize, expect!(s.next()));
let time_reading = from_str!(usize, expect!(s.next()));
let writes = from_str!(usize, expect!(s.next()));
let writes_merged = from_str!(usize, expect!(s.next()));
let sectors_written = from_str!(usize, expect!(s.next()));
let time_writing = from_str!(usize, expect!(s.next()));
let in_progress = from_str!(usize, expect!(s.next()));
let time_in_progress = from_str!(usize, expect!(s.next()));
let weighted_time_in_progress = from_str!(usize, expect!(s.next()));
let discards = s.next().and_then(|s| usize::from_str_radix(s, 10).ok());
let discards_merged = s.next().and_then(|s| usize::from_str_radix(s, 10).ok());
let sectors_discarded = s.next().and_then(|s| usize::from_str_radix(s, 10).ok());
let time_discarding = s.next().and_then(|s| usize::from_str_radix(s, 10).ok());
let flushes = s.next().and_then(|s| usize::from_str_radix(s, 10).ok());
let time_flushing = s.next().and_then(|s| usize::from_str_radix(s, 10).ok());
Ok(DiskStat {
major,
minor,
name,
reads,
merged,
sectors_read,
time_reading,
writes,
writes_merged,
sectors_written,
time_writing,
in_progress,
time_in_progress,
weighted_time_in_progress,
discards,
discards_merged,
sectors_discarded,
time_discarding,
flushes,
time_flushing,
})
}
}
#[cfg(test)]
mod tests {
#[test]
fn diskstat() {
for disk in super::diskstats().unwrap() {
println!("{:?}", disk);
}
}
}