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
use {
super::*,
lazy_regex::*,
};
/// what we have most looking like a physical device
#[derive(Debug, Clone)]
pub struct Disk {
/// a name, like "sda", "sdc", "nvme0n1", etc.
pub name: String,
/// true for HDD, false for SSD, None for unknown.
/// This information isn't reliable for USB devices
pub rotational: Option<bool>,
/// whether the system thinks the media is removable.
/// Seems reliable when not mapped
pub removable: Option<bool>,
/// whether it's a RAM disk
pub ram: bool,
/// whether it's on LVM
pub lvm: bool,
/// whether it's a crypted disk
pub crypted: bool,
}
impl Disk {
pub fn new(name: String) -> Self {
let rotational = sys::read_file_as_bool(&format!("/sys/block/{}/queue/rotational", name));
let removable = sys::read_file_as_bool(&format!("/sys/block/{}/removable", name));
let ram = regex_is_match!(r#"^zram\d*$"#, &name);
let dm_uuid = sys::read_file(&format!("/sys/block/{}/dm/uuid", name)).ok();
let crypted = dm_uuid
.as_ref()
.map_or(false, |uuid| uuid.starts_with("CRYPT-"));
let lvm = dm_uuid.map_or(false, |uuid| uuid.starts_with("LVM-"));
Self {
name,
rotational,
removable,
ram,
lvm,
crypted,
}
}
/// a synthetic code trying to express the essence of the type of media,
/// an empty str being returned when information couldn't be gathered.
/// This code is for humans and may change in future minor versions.
pub fn disk_type(&self) -> &'static str {
if self.ram {
"RAM"
} else if self.crypted {
"crypt"
} else if self.lvm {
"LVM"
} else {
match (self.removable, self.rotational) {
(Some(true), _) => "remov",
(Some(false), Some(true)) => "HDD",
(Some(false), Some(false)) => "SSD",
_ => "",
}
}
}
}