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