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
use std::{
cell::RefCell,
fmt::Debug,
fs::File,
io::{self, Read},
path::{Path, PathBuf},
str::FromStr,
};
use sysfs_class::{Block, SysClass};
pub trait BlockDeviceExt {
fn sys_block_path(&self) -> PathBuf { sys_block_path(self.get_device_name(), "") }
fn is_read_only(&self) -> bool {
Block::from_path(&self.sys_block_path())
.ok()
.map_or(false, |block| block.ro().ok() == Some(1))
}
fn is_removable(&self) -> bool {
Block::from_path(&self.sys_block_path())
.ok()
.map_or(false, |block| block.removable().ok() == Some(1))
}
fn is_rotational(&self) -> bool {
Block::from_path(&self.sys_block_path())
.ok()
.map_or(false, |block| block.queue_rotational().ok() == Some(1))
}
fn get_device_path(&self) -> &Path;
fn get_mount_point(&self) -> Option<&Path> { None }
fn get_device_name(&self) -> &str;
fn get_sectors(&self) -> u64 {
let size_file = sys_block_path(self.get_device_name(), "/size");
read_file::<u64>(&size_file).expect("no sector count found")
}
fn get_logical_block_size(&self) -> u64 {
let path = sys_block_path(self.get_device_name(), "/queue/logical_block_size");
read_file::<u64>(&path).expect("logical block size not found")
}
fn get_physical_block_size(&self) -> u64 {
let path = sys_block_path(self.get_device_name(), "/queue/physical_block_size");
read_file::<u64>(&path).expect("physical block size not found")
}
}
fn sys_block_path(name: &str, ppath: &str) -> PathBuf {
PathBuf::from(["/sys/class/block/", name, ppath].concat())
}
thread_local! {
static BUFFER: RefCell<String> = String::with_capacity(256).into();
}
fn read_file<T: FromStr>(path: &Path) -> io::Result<T>
where
<T as FromStr>::Err: Debug,
{
BUFFER.with(|buffer| {
let mut buffer = buffer.borrow_mut();
File::open(path)?.read_to_string(&mut buffer)?;
let value = buffer.trim().parse::<T>();
buffer.clear();
value.map_err(|why| io::Error::new(io::ErrorKind::Other, format!("{:?}", why)))
})
}