Skip to content

Commit a231715

Browse files
committed
Merge remote-tracking branch 'rlupton20/disk-stats'
* rlupton20/disk-stats: Use usize over u64 Add example Layout tweak Move block stats struct Tidying Put name inside stats Add block_device_statistics to linux Parsers for /proc/diskstats Move to map data structure Stub out disk stats
2 parents 7789741 + a0c997b commit a231715

File tree

7 files changed

+96
-0
lines changed

7 files changed

+96
-0
lines changed

examples/info.rs

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ fn main() {
1818
Err(x) => println!("\nMounts: error: {}", x)
1919
}
2020

21+
match sys.block_device_statistics() {
22+
Ok(stats) => {
23+
for blkstats in stats.values() {
24+
println!("{}: {:?}", blkstats.name, blkstats);
25+
}
26+
}
27+
Err(x) => println!("Block statistics error: {}", x.to_string())
28+
}
29+
2130
match sys.networks() {
2231
Ok(netifs) => {
2332
println!("\nNetworks:");

src/data.rs

+16
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,22 @@ pub struct Filesystem {
173173
pub fs_mounted_on: String,
174174
}
175175

176+
#[derive(Debug, Clone)]
177+
pub struct BlockDeviceStats {
178+
pub name: String,
179+
pub read_ios: usize,
180+
pub read_merges: usize,
181+
pub read_sectors: usize,
182+
pub read_ticks: usize,
183+
pub write_ios: usize,
184+
pub write_merges: usize,
185+
pub write_sectors: usize,
186+
pub write_ticks: usize,
187+
pub in_flight: usize,
188+
pub io_ticks: usize,
189+
pub time_in_queue: usize,
190+
}
191+
176192
#[derive(Debug, Clone, PartialEq)]
177193
pub enum IpAddr {
178194
Empty,

src/platform/common.rs

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pub trait Platform {
6060
/// Returns a filesystem mount information object for the filesystem at a given path.
6161
fn mount_at<P: AsRef<path::Path>>(&self, path: P) -> io::Result<Filesystem>;
6262

63+
/// Returns a map of block device statistics objects
64+
fn block_device_statistics(&self) -> io::Result<BTreeMap<String, BlockDeviceStats>>;
65+
6366
/// Returns a map of network intefrace information objects.
6467
///
6568
/// It's a map because most operating systems return an object per IP address, not per

src/platform/freebsd.rs

+4
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ impl Platform for PlatformImpl {
141141
Ok(sfs.to_fs())
142142
}
143143

144+
fn block_device_statistics(&self) -> io::Result<BTreeMap<String, BlockDeviceStats>> {
145+
Err(io::Error::new(io::ErrorKind::Other, "Not supported"))
146+
}
147+
144148
fn networks(&self) -> io::Result<BTreeMap<String, Network>> {
145149
unix::networks()
146150
}

src/platform/linux.rs

+56
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,47 @@ fn stat_mount(mount: ProcMountsData) -> io::Result<Filesystem> {
200200
}
201201
}
202202

203+
/// Parse a line of `/proc/diskstats`
204+
named!(
205+
proc_diskstats_line<BlockDeviceStats>,
206+
ws!(do_parse!(
207+
major_number: usize_s >>
208+
minor_number: usize_s >>
209+
name: word_s >>
210+
read_ios: usize_s >>
211+
read_merges: usize_s >>
212+
read_sectors: usize_s >>
213+
read_ticks: usize_s >>
214+
write_ios: usize_s >>
215+
write_merges: usize_s >>
216+
write_sectors: usize_s >>
217+
write_ticks: usize_s >>
218+
in_flight: usize_s >>
219+
io_ticks: usize_s >>
220+
time_in_queue: usize_s >>
221+
(BlockDeviceStats {
222+
name: name,
223+
read_ios: read_ios,
224+
read_merges: read_merges,
225+
read_sectors: read_sectors,
226+
read_ticks: read_ticks,
227+
write_ios: write_ios,
228+
write_merges: write_merges,
229+
write_sectors: write_sectors,
230+
write_ticks: write_ticks,
231+
in_flight: in_flight,
232+
io_ticks: io_ticks,
233+
time_in_queue: time_in_queue
234+
})
235+
))
236+
);
237+
238+
/// Parse `/proc/diskstats` to get a Vec<BlockDeviceStats>
239+
named!(proc_diskstats<Vec<BlockDeviceStats>>,
240+
many0!(ws!(flat_map!(not_line_ending, proc_diskstats_line)))
241+
);
242+
243+
203244
pub struct PlatformImpl;
204245

205246
/// An implementation of `Platform` for Linux.
@@ -370,6 +411,21 @@ impl Platform for PlatformImpl {
370411
.and_then(stat_mount)
371412
}
372413

414+
fn block_device_statistics(&self) -> io::Result<BTreeMap<String, BlockDeviceStats>> {
415+
let mut result: BTreeMap<String, BlockDeviceStats> = BTreeMap::new();
416+
let stats: Vec<BlockDeviceStats> = try!(read_file("/proc/diskstats")
417+
.and_then(|data| {
418+
proc_diskstats(data.as_bytes()).to_result()
419+
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))
420+
})
421+
);
422+
423+
for blkstats in stats {
424+
result.entry(blkstats.name.clone()).or_insert(blkstats);
425+
}
426+
Ok(result)
427+
}
428+
373429
fn networks(&self) -> io::Result<BTreeMap<String, Network>> {
374430
unix::networks()
375431
}

src/platform/openbsd.rs

+4
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ impl Platform for PlatformImpl {
118118
Err(io::Error::new(io::ErrorKind::Other, "Not supported"))
119119
}
120120

121+
fn block_device_statistics(&self) -> io::Result<BTreeMap<String, BlockDeviceStats>> {
122+
Err(io::Error::new(io::ErrorKind::Other, "Not supported"))
123+
}
124+
121125
fn networks(&self) -> io::Result<BTreeMap<String, Network>> {
122126
unix::networks()
123127
}

src/platform/windows.rs

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ impl Platform for PlatformImpl {
8585
Err(io::Error::new(io::ErrorKind::Other, "Not supported"))
8686
}
8787

88+
fn block_device_statistics(&self) -> io::Result<BTreeMap<String, BlockDeviceStats>> {
89+
Err(io::Error::new(io::ErrorKind::Other, "Not supported"))
90+
}
91+
8892
fn networks(&self) -> io::Result<BTreeMap<String, Network>> {
8993
Err(io::Error::new(io::ErrorKind::Other, "Not supported"))
9094
}

0 commit comments

Comments
 (0)