src/tools/disks.rs: use dev_t to index zfs/lvm device sets
This commit is contained in:
		@ -4,6 +4,7 @@ use std::collections::{HashMap, HashSet};
 | 
			
		||||
use std::ffi::{OsStr, OsString};
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
 | 
			
		||||
use std::os::unix::fs::MetadataExt;
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
@ -82,8 +83,6 @@ impl DiskManage {
 | 
			
		||||
 | 
			
		||||
    /// Get a `Disk` from a device node (eg. `/dev/sda`).
 | 
			
		||||
    pub fn disk_by_node<P: AsRef<Path>>(self: Arc<Self>, devnode: P) -> io::Result<Disk> {
 | 
			
		||||
        use std::os::unix::fs::MetadataExt;
 | 
			
		||||
 | 
			
		||||
        let devnode = devnode.as_ref();
 | 
			
		||||
 | 
			
		||||
        let meta = std::fs::metadata(devnode)?;
 | 
			
		||||
@ -121,8 +120,6 @@ impl DiskManage {
 | 
			
		||||
 | 
			
		||||
    /// Gather information about mounted disks:
 | 
			
		||||
    fn mounted_devices(&self) -> Result<&HashSet<dev_t>, Error> {
 | 
			
		||||
        use std::os::unix::fs::MetadataExt;
 | 
			
		||||
 | 
			
		||||
        self.mounted_devices
 | 
			
		||||
            .get_or_try_init(|| -> Result<_, Error> {
 | 
			
		||||
                let mut mounted = HashSet::new();
 | 
			
		||||
@ -645,8 +642,8 @@ pub struct DiskUsageInfo {
 | 
			
		||||
 | 
			
		||||
fn scan_partitions(
 | 
			
		||||
    disk_manager: Arc<DiskManage>,
 | 
			
		||||
    lvm_devices: &HashSet<String>,
 | 
			
		||||
    zfs_devices: &HashSet<String>,
 | 
			
		||||
    lvm_devices: &HashSet<u64>,
 | 
			
		||||
    zfs_devices: &HashSet<u64>,
 | 
			
		||||
    device: &str,
 | 
			
		||||
) -> Result<DiskUsageType, Error> {
 | 
			
		||||
 | 
			
		||||
@ -676,7 +673,9 @@ fn scan_partitions(
 | 
			
		||||
 | 
			
		||||
        let data = disk_manager.clone().disk_by_sys_path(&part_path)?;
 | 
			
		||||
 | 
			
		||||
        if lvm_devices.contains(name) {
 | 
			
		||||
        let devnum = data.devnum()?;
 | 
			
		||||
 | 
			
		||||
        if lvm_devices.contains(&devnum) {
 | 
			
		||||
            found_lvm = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -688,9 +687,9 @@ fn scan_partitions(
 | 
			
		||||
            found_dm = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if zfs_devices.contains(name) {
 | 
			
		||||
         if zfs_devices.contains(&devnum) {
 | 
			
		||||
            found_zfs = true;
 | 
			
		||||
        }
 | 
			
		||||
         }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if found_mountpoints {
 | 
			
		||||
@ -763,6 +762,8 @@ pub fn get_disks(
 | 
			
		||||
 | 
			
		||||
        let disk = disk_manager.clone().disk_by_sys_path(&sys_path)?;
 | 
			
		||||
 | 
			
		||||
        let devnum = disk.devnum()?;
 | 
			
		||||
 | 
			
		||||
        let size = match disk.size() {
 | 
			
		||||
            Ok(size) => size,
 | 
			
		||||
            Err(_) => continue, // skip devices with unreadable size
 | 
			
		||||
@ -775,7 +776,7 @@ pub fn get_disks(
 | 
			
		||||
 | 
			
		||||
        let mut usage = DiskUsageType::Unused;
 | 
			
		||||
 | 
			
		||||
        if lvm_devices.contains(&name) {
 | 
			
		||||
        if lvm_devices.contains(&devnum) {
 | 
			
		||||
            usage = DiskUsageType::LVM;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -785,7 +786,7 @@ pub fn get_disks(
 | 
			
		||||
            Err(_) => continue, // skip devices with undetectable mount status
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if zfs_devices.contains(&name) {
 | 
			
		||||
        if zfs_devices.contains(&devnum) {
 | 
			
		||||
            usage = DiskUsageType::ZFS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -799,6 +800,7 @@ pub fn get_disks(
 | 
			
		||||
        let devpath =  disk.device_path().map(|p| p.to_owned())
 | 
			
		||||
            .map(|p| p.to_string_lossy().to_string());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        let wwn = disk.wwn().map(|s| s.to_string_lossy().into_owned());
 | 
			
		||||
 | 
			
		||||
        if usage != DiskUsageType::Mounted {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
use std::collections::{HashSet, HashMap};
 | 
			
		||||
use std::os::unix::fs::MetadataExt;
 | 
			
		||||
 | 
			
		||||
use anyhow::{format_err, Error};
 | 
			
		||||
use serde_json::Value;
 | 
			
		||||
@ -12,10 +13,10 @@ lazy_static!{
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get list of devices used by LVM (pvs).
 | 
			
		||||
/// Get set of devices used by LVM (pvs).
 | 
			
		||||
pub fn get_lvm_devices(
 | 
			
		||||
    partition_type_map: &HashMap<String, Vec<String>>,
 | 
			
		||||
) -> Result<HashSet<String>, Error> {
 | 
			
		||||
) -> Result<HashSet<u64>, Error> {
 | 
			
		||||
 | 
			
		||||
    const PVS_BIN_PATH: &str = "/sbin/pvs";
 | 
			
		||||
 | 
			
		||||
@ -28,13 +29,14 @@ pub fn get_lvm_devices(
 | 
			
		||||
    let output = crate::tools::command_output(output, None)
 | 
			
		||||
        .map_err(|err| format_err!("pvs command failed: {}", err))?;
 | 
			
		||||
 | 
			
		||||
    let mut device_set: HashSet<String> = HashSet::new();
 | 
			
		||||
    let mut device_set: HashSet<u64> = HashSet::new();
 | 
			
		||||
 | 
			
		||||
    for device_list in partition_type_map.iter()
 | 
			
		||||
        .filter_map(|(uuid, list)| if LVM_UUIDS.contains(uuid.as_str()) { Some(list) } else { None })
 | 
			
		||||
    {
 | 
			
		||||
        for device in device_list {
 | 
			
		||||
            device_set.insert(device.clone());
 | 
			
		||||
            let meta = std::fs::metadata(device)?;
 | 
			
		||||
            device_set.insert(meta.rdev());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,7 +46,8 @@ pub fn get_lvm_devices(
 | 
			
		||||
        Some(list) => {
 | 
			
		||||
            for info in list {
 | 
			
		||||
                if let Some(pv_name) = info["pv_name"].as_str() {
 | 
			
		||||
                    device_set.insert(pv_name.to_string());
 | 
			
		||||
                    let meta = std::fs::metadata(pv_name)?;
 | 
			
		||||
                    device_set.insert(meta.rdev());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
use std::collections::{HashMap, HashSet};
 | 
			
		||||
use std::os::unix::fs::MetadataExt;
 | 
			
		||||
 | 
			
		||||
use anyhow::{bail, Error};
 | 
			
		||||
use lazy_static::lazy_static;
 | 
			
		||||
@ -168,11 +169,13 @@ pub fn parse_zfs_list(i: &str) -> Result<Vec<ZFSPoolStatus>, Error> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// List devices used by zfs (or a specific zfs pool)
 | 
			
		||||
/// Get set of devices used by zfs (or a specific zfs pool)
 | 
			
		||||
///
 | 
			
		||||
/// The set is indexed by using the unix raw device number (dev_t is u64)
 | 
			
		||||
pub fn zfs_devices(
 | 
			
		||||
    partition_type_map: &HashMap<String, Vec<String>>,
 | 
			
		||||
    pool: Option<&OsStr>,
 | 
			
		||||
) -> Result<HashSet<String>, Error> {
 | 
			
		||||
) -> Result<HashSet<u64>, Error> {
 | 
			
		||||
 | 
			
		||||
    // Note: zpools list  output can include entries for 'special', 'cache' and 'logs'
 | 
			
		||||
    // and maybe other things.
 | 
			
		||||
@ -193,7 +196,8 @@ pub fn zfs_devices(
 | 
			
		||||
    let mut device_set = HashSet::new();
 | 
			
		||||
    for entry in list {
 | 
			
		||||
        for device in entry.devices {
 | 
			
		||||
            device_set.insert(device.clone());
 | 
			
		||||
            let meta = std::fs::metadata(device)?;
 | 
			
		||||
            device_set.insert(meta.rdev());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -201,7 +205,8 @@ pub fn zfs_devices(
 | 
			
		||||
        .filter_map(|(uuid, list)| if ZFS_UUIDS.contains(uuid.as_str()) { Some(list) } else { None })
 | 
			
		||||
    {
 | 
			
		||||
        for device in device_list {
 | 
			
		||||
            device_set.insert(device.clone());
 | 
			
		||||
            let meta = std::fs::metadata(device)?;
 | 
			
		||||
            device_set.insert(meta.rdev());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user