procfs_core/
diskstats.rs

1use crate::{expect, from_str, ProcResult};
2#[cfg(feature = "serde1")]
3use serde::{Deserialize, Serialize};
4use std::io::BufRead;
5
6/// Disk IO stat information
7///
8/// To fully understand these fields, please see the [iostats.txt](https://www.kernel.org/doc/Documentation/iostats.txt)
9/// kernel documentation.
10///
11/// For an example, see the [diskstats.rs](https://github.com/eminence/procfs/tree/master/examples)
12/// example in the source repo.
13// Doc reference: https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats
14// Doc reference: https://www.kernel.org/doc/Documentation/iostats.txt
15#[derive(Debug, Clone)]
16#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
17pub struct DiskStat {
18    /// The device major number
19    pub major: i32,
20
21    /// The device minor number
22    pub minor: i32,
23
24    /// Device name
25    pub name: String,
26
27    /// Reads completed successfully
28    ///
29    /// This is the total number of reads completed successfully
30    pub reads: u64,
31
32    /// Reads merged
33    ///
34    /// The number of adjacent reads that have been merged for efficiency.
35    pub merged: u64,
36
37    /// Sectors read successfully
38    ///
39    /// This is the total number of sectors read successfully.
40    pub sectors_read: u64,
41
42    /// Time spent reading (ms)
43    pub time_reading: u64,
44
45    /// writes completed
46    pub writes: u64,
47
48    /// writes merged
49    ///
50    /// The number of adjacent writes that have been merged for efficiency.
51    pub writes_merged: u64,
52
53    /// Sectors written successfully
54    pub sectors_written: u64,
55
56    /// Time spent writing (ms)
57    pub time_writing: u64,
58
59    /// I/Os currently in progress
60    pub in_progress: u64,
61
62    /// Time spent doing I/Os (ms)
63    pub time_in_progress: u64,
64
65    /// Weighted time spent doing I/Os (ms)
66    pub weighted_time_in_progress: u64,
67
68    /// Discards completed successfully
69    ///
70    /// (since kernel 4.18)
71    pub discards: Option<u64>,
72
73    /// Discards merged
74    pub discards_merged: Option<u64>,
75
76    /// Sectors discarded
77    pub sectors_discarded: Option<u64>,
78
79    /// Time spent discarding
80    pub time_discarding: Option<u64>,
81
82    /// Flush requests completed successfully
83    ///
84    /// (since kernel 5.5)
85    pub flushes: Option<u64>,
86
87    /// Time spent flushing
88    pub time_flushing: Option<u64>,
89}
90
91/// A list of disk stats.
92#[derive(Debug, Clone)]
93#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
94pub struct DiskStats(pub Vec<DiskStat>);
95
96impl crate::FromBufRead for DiskStats {
97    fn from_buf_read<R: BufRead>(r: R) -> ProcResult<Self> {
98        let mut v = Vec::new();
99
100        for line in r.lines() {
101            let line = line?;
102            v.push(DiskStat::from_line(&line)?);
103        }
104        Ok(DiskStats(v))
105    }
106}
107
108impl DiskStat {
109    pub fn from_line(line: &str) -> ProcResult<DiskStat> {
110        let mut s = line.split_whitespace();
111
112        let major = from_str!(i32, expect!(s.next()));
113        let minor = from_str!(i32, expect!(s.next()));
114        let name = expect!(s.next()).to_string();
115        let reads = from_str!(u64, expect!(s.next()));
116        let merged = from_str!(u64, expect!(s.next()));
117        let sectors_read = from_str!(u64, expect!(s.next()));
118        let time_reading = from_str!(u64, expect!(s.next()));
119        let writes = from_str!(u64, expect!(s.next()));
120        let writes_merged = from_str!(u64, expect!(s.next()));
121        let sectors_written = from_str!(u64, expect!(s.next()));
122        let time_writing = from_str!(u64, expect!(s.next()));
123        let in_progress = from_str!(u64, expect!(s.next()));
124        let time_in_progress = from_str!(u64, expect!(s.next()));
125        let weighted_time_in_progress = from_str!(u64, expect!(s.next()));
126        let discards = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
127        let discards_merged = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
128        let sectors_discarded = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
129        let time_discarding = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
130        let flushes = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
131        let time_flushing = s.next().and_then(|s| u64::from_str_radix(s, 10).ok());
132
133        Ok(DiskStat {
134            major,
135            minor,
136            name,
137            reads,
138            merged,
139            sectors_read,
140            time_reading,
141            writes,
142            writes_merged,
143            sectors_written,
144            time_writing,
145            in_progress,
146            time_in_progress,
147            weighted_time_in_progress,
148            discards,
149            discards_merged,
150            sectors_discarded,
151            time_discarding,
152            flushes,
153            time_flushing,
154        })
155    }
156}