[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