[pbs-devel] [PATCH/RFC proxmox-backup 2/2] disks: also check for file systems with lsblk

Fabian Ebner f.ebner at proxmox.com
Tue Apr 20 11:53:45 CEST 2021


so that whole disks with a file system that are not mounted are still detected
as in-use.

Reported-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---

Ideally, we'd also show the type in the result, but the api macro complained
when I tried using
    FileSystem(String)
    Mounted(String) // showing the fs type here would also be nice
in the enum. Is there a good way to do this? An alternative would be replacing
the DiskUsageType with a String in the DiskUsage struct, but that's not very
nice...

 src/tools/disks.rs | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/tools/disks.rs b/src/tools/disks.rs
index d374df0e..5eed723b 100644
--- a/src/tools/disks.rs
+++ b/src/tools/disks.rs
@@ -52,6 +52,8 @@ pub struct LsblkInfo {
     path: String,
     /// Partition type GUID.
     partition_type: Option<String>,
+    /// File system label.
+    file_system_type: Option<String>,
 }
 
 impl DiskManage {
@@ -563,11 +565,11 @@ pub struct BlockDevStat {
     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> {
 
     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)?;
 
@@ -582,9 +584,11 @@ pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> {
                 None => continue,
             };
             let partition_type = info["parttype"].as_str().map(|t| t.to_string());
+            let file_system_type = info["fstype"].as_str().map(|t| t.to_string());
             res.push(LsblkInfo {
                 path,
                 partition_type,
+                file_system_type,
             });
         }
     }
@@ -592,6 +596,25 @@ pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> {
     Ok(res)
 }
 
+/// 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()]
 #[derive(Debug, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all="lowercase")]
@@ -608,6 +631,8 @@ pub enum DiskUsageType {
     DeviceMapper,
     /// Disk has partitions
     Partitions,
+    /// Disk contains a file system label
+    FileSystem,
 }
 
 #[api(
@@ -754,6 +779,8 @@ pub fn get_disks(
 
     let lvm_devices = get_lvm_devices(&lsblk_info)?;
 
+    let file_system_devices = get_file_system_devices(&lsblk_info)?;
+
     // fixme: ceph journals/volumes
 
     let mut result = HashMap::new();
@@ -829,6 +856,10 @@ pub fn get_disks(
             };
         }
 
+        if usage == DiskUsageType::Unused && file_system_devices.contains(&devnum) {
+            usage = DiskUsageType::FileSystem;
+        }
+
         if usage == DiskUsageType::Unused && disk.has_holders()? {
             usage = DiskUsageType::DeviceMapper;
         }
-- 
2.20.1






More information about the pbs-devel mailing list