1 use { 2 super::*, 3 lazy_regex::*, 4 }; 5 6 /// what we have most looking like a physical device 7 #[derive(Debug, Clone)] 8 pub struct Disk { 9 /// a name, like "sda", "sdc", "nvme0n1", etc. 10 pub name: String, 11 12 /// true for HDD, false for SSD, None for unknown. 13 /// This information isn't reliable for USB devices 14 pub rotational: Option<bool>, 15 16 /// whether the system thinks the media is removable. 17 /// Seems reliable when not mapped 18 pub removable: Option<bool>, 19 20 /// whether it's a RAM disk 21 pub ram: bool, 22 23 /// whether it's on LVM 24 pub lvm: bool, 25 26 /// whether it's a crypted disk 27 pub crypted: bool, 28 } 29 30 impl Disk { new(name: String) -> Self31 pub fn new(name: String) -> Self { 32 let rotational = sys::read_file_as_bool(&format!("/sys/block/{}/queue/rotational", name)); 33 let removable = sys::read_file_as_bool(&format!("/sys/block/{}/removable", name)); 34 let ram = regex_is_match!(r#"^zram\d*$"#, &name); 35 let dm_uuid = sys::read_file(&format!("/sys/block/{}/dm/uuid", name)).ok(); 36 let crypted = dm_uuid.as_ref().map_or(false, |uuid| uuid.starts_with("CRYPT-")); 37 let lvm = dm_uuid.map_or(false, |uuid| uuid.starts_with("LVM-")); 38 Self { name, rotational, removable , ram, lvm, crypted } 39 } 40 /// a synthetic code trying to express the essence of the type of media, 41 /// an empty str being returned when information couldn't be gathered. 42 /// This code is for humans and may change in future minor versions. disk_type(&self) -> &'static str43 pub fn disk_type(&self) -> &'static str { 44 if self.ram { 45 "RAM" 46 } else if self.crypted { 47 "crypt" 48 } else if self.lvm { 49 "LVM" 50 } else { 51 match (self.removable, self.rotational) { 52 (Some(true), _) => "remov", 53 (Some(false), Some(true)) => "HDD", 54 (Some(false), Some(false)) => "SSD", 55 _ => "", 56 } 57 } 58 } 59 } 60 61