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

Fabian Ebner f.ebner at proxmox.com
Mon May 3 09:44:08 CEST 2021


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

Changes from v1:
    * add serde handling for the file system type too

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 | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/tools/disks.rs b/src/tools/disks.rs
index 885edf47..0fd45331 100644
--- a/src/tools/disks.rs
+++ b/src/tools/disks.rs
@@ -54,6 +54,9 @@ pub struct LsblkInfo {
     /// Partition type GUID.
     #[serde(rename = "parttype")]
     partition_type: Option<String>,
+    /// File system label.
+    #[serde(rename = "fstype")]
+    file_system_type: Option<String>,
 }
 
 impl DiskManage {
@@ -565,11 +568,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)?;
 
@@ -578,6 +581,25 @@ pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> {
     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()]
 #[derive(Debug, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all="lowercase")]
@@ -594,6 +616,8 @@ pub enum DiskUsageType {
     DeviceMapper,
     /// Disk has partitions
     Partitions,
+    /// Disk contains a file system label
+    FileSystem,
 }
 
 #[api(
@@ -740,6 +764,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();
@@ -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()? {
             usage = DiskUsageType::DeviceMapper;
         }
-- 
2.20.1






More information about the pbs-devel mailing list