disks: also check for file systems with lsblk

Reported-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
(cherry picked from commit 20429238e0)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Fabian Ebner 2021-07-09 12:32:34 +02:00 committed by Thomas Lamprecht
parent f98c02cbc6
commit dd749b0e47
1 changed files with 32 additions and 2 deletions

View File

@ -54,6 +54,9 @@ pub struct LsblkInfo {
/// Partition type GUID. /// Partition type GUID.
#[serde(rename = "parttype")] #[serde(rename = "parttype")]
partition_type: Option<String>, partition_type: Option<String>,
/// File system label.
#[serde(rename = "fstype")]
file_system_type: Option<String>,
} }
impl DiskManage { impl DiskManage {
@ -565,11 +568,11 @@ pub struct BlockDevStat {
pub io_ticks: u64, // milliseconds pub io_ticks: u64, // milliseconds
} }
/// Use lsblk to read partition type uuids. /// Use lsblk to read partition type uuids and file system types.
pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> { pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> {
let mut command = std::process::Command::new("lsblk"); let mut command = std::process::Command::new("lsblk");
command.args(&["--json", "-o", "path,parttype"]); command.args(&["--json", "-o", "path,parttype,fstype"]);
let output = crate::tools::run_command(command, None)?; let output = crate::tools::run_command(command, None)?;
@ -578,6 +581,25 @@ pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> {
Ok(serde_json::from_value(output["blockdevices"].take())?) Ok(serde_json::from_value(output["blockdevices"].take())?)
} }
/// Get set of devices with a file system label.
///
/// The set is indexed by using the unix raw device number (dev_t is u64)
fn get_file_system_devices(
lsblk_info: &[LsblkInfo],
) -> Result<HashSet<u64>, Error> {
let mut device_set: HashSet<u64> = HashSet::new();
for info in lsblk_info.iter() {
if info.file_system_type.is_some() {
let meta = std::fs::metadata(&info.path)?;
device_set.insert(meta.rdev());
}
}
Ok(device_set)
}
#[api()] #[api()]
#[derive(Debug, Serialize, Deserialize, PartialEq)] #[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all="lowercase")] #[serde(rename_all="lowercase")]
@ -594,6 +616,8 @@ pub enum DiskUsageType {
DeviceMapper, DeviceMapper,
/// Disk has partitions /// Disk has partitions
Partitions, Partitions,
/// Disk contains a file system label
FileSystem,
} }
#[api( #[api(
@ -740,6 +764,8 @@ pub fn get_disks(
let lvm_devices = get_lvm_devices(&lsblk_info)?; let lvm_devices = get_lvm_devices(&lsblk_info)?;
let file_system_devices = get_file_system_devices(&lsblk_info)?;
// fixme: ceph journals/volumes // fixme: ceph journals/volumes
let mut result = HashMap::new(); let mut result = HashMap::new();
@ -815,6 +841,10 @@ pub fn get_disks(
}; };
} }
if usage == DiskUsageType::Unused && file_system_devices.contains(&devnum) {
usage = DiskUsageType::FileSystem;
}
if usage == DiskUsageType::Unused && disk.has_holders()? { if usage == DiskUsageType::Unused && disk.has_holders()? {
usage = DiskUsageType::DeviceMapper; usage = DiskUsageType::DeviceMapper;
} }