disks: refactor partition type handling
in preparation to also get the file system type from lsblk. Co-developed-by: Wolfgang Bumiller <w.bumiller@proxmox.com> Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
This commit is contained in:
parent
b81818b6ad
commit
364299740f
|
@ -1,10 +1,12 @@
|
|||
use std::collections::{HashSet, HashMap};
|
||||
use std::collections::HashSet;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
use anyhow::{Error};
|
||||
use serde_json::Value;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use super::LsblkInfo;
|
||||
|
||||
lazy_static!{
|
||||
static ref LVM_UUIDS: HashSet<&'static str> = {
|
||||
let mut set = HashSet::new();
|
||||
|
@ -17,7 +19,7 @@ lazy_static!{
|
|||
///
|
||||
/// The set is indexed by using the unix raw device number (dev_t is u64)
|
||||
pub fn get_lvm_devices(
|
||||
partition_type_map: &HashMap<String, Vec<String>>,
|
||||
lsblk_info: &[LsblkInfo],
|
||||
) -> Result<HashSet<u64>, Error> {
|
||||
|
||||
const PVS_BIN_PATH: &str = "pvs";
|
||||
|
@ -29,12 +31,12 @@ pub fn get_lvm_devices(
|
|||
|
||||
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 {
|
||||
let meta = std::fs::metadata(device)?;
|
||||
device_set.insert(meta.rdev());
|
||||
for info in lsblk_info.iter() {
|
||||
if let Some(partition_type) = &info.partition_type {
|
||||
if LVM_UUIDS.contains(partition_type.as_str()) {
|
||||
let meta = std::fs::metadata(&info.path)?;
|
||||
device_set.insert(meta.rdev());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,16 @@ pub struct DiskManage {
|
|||
mounted_devices: OnceCell<HashSet<dev_t>>,
|
||||
}
|
||||
|
||||
/// Information for a device as returned by lsblk.
|
||||
#[derive(Deserialize)]
|
||||
pub struct LsblkInfo {
|
||||
/// Path to the device.
|
||||
path: String,
|
||||
/// Partition type GUID.
|
||||
#[serde(rename = "parttype")]
|
||||
partition_type: Option<String>,
|
||||
}
|
||||
|
||||
impl DiskManage {
|
||||
/// Create a new disk management context.
|
||||
pub fn new() -> Arc<Self> {
|
||||
|
@ -556,31 +566,16 @@ pub struct BlockDevStat {
|
|||
}
|
||||
|
||||
/// Use lsblk to read partition type uuids.
|
||||
pub fn get_partition_type_info() -> Result<HashMap<String, Vec<String>>, Error> {
|
||||
pub fn get_lsblk_info() -> Result<Vec<LsblkInfo>, Error> {
|
||||
|
||||
let mut command = std::process::Command::new("lsblk");
|
||||
command.args(&["--json", "-o", "path,parttype"]);
|
||||
|
||||
let output = crate::tools::run_command(command, None)?;
|
||||
|
||||
let mut res: HashMap<String, Vec<String>> = HashMap::new();
|
||||
let mut output: serde_json::Value = output.parse()?;
|
||||
|
||||
let output: serde_json::Value = output.parse()?;
|
||||
if let Some(list) = output["blockdevices"].as_array() {
|
||||
for info in list {
|
||||
let path = match info["path"].as_str() {
|
||||
Some(p) => p,
|
||||
None => continue,
|
||||
};
|
||||
let partition_type = match info["parttype"].as_str() {
|
||||
Some(t) => t.to_owned(),
|
||||
None => continue,
|
||||
};
|
||||
let devices = res.entry(partition_type).or_insert(Vec::new());
|
||||
devices.push(path.to_string());
|
||||
}
|
||||
}
|
||||
Ok(res)
|
||||
Ok(serde_json::from_value(output["blockdevices"].take())?)
|
||||
}
|
||||
|
||||
#[api()]
|
||||
|
@ -736,14 +731,14 @@ pub fn get_disks(
|
|||
|
||||
let disk_manager = DiskManage::new();
|
||||
|
||||
let partition_type_map = get_partition_type_info()?;
|
||||
let lsblk_info = get_lsblk_info()?;
|
||||
|
||||
let zfs_devices = zfs_devices(&partition_type_map, None).or_else(|err| -> Result<HashSet<u64>, Error> {
|
||||
let zfs_devices = zfs_devices(&lsblk_info, None).or_else(|err| -> Result<HashSet<u64>, Error> {
|
||||
eprintln!("error getting zfs devices: {}", err);
|
||||
Ok(HashSet::new())
|
||||
})?;
|
||||
|
||||
let lvm_devices = get_lvm_devices(&partition_type_map)?;
|
||||
let lvm_devices = get_lvm_devices(&lsblk_info)?;
|
||||
|
||||
// fixme: ceph journals/volumes
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::path::PathBuf;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashSet;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
use anyhow::{bail, Error};
|
||||
|
@ -67,12 +67,11 @@ pub fn zfs_pool_stats(pool: &OsStr) -> Result<Option<BlockDevStat>, Error> {
|
|||
Ok(Some(stat))
|
||||
}
|
||||
|
||||
|
||||
/// 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>>,
|
||||
lsblk_info: &[LsblkInfo],
|
||||
pool: Option<String>,
|
||||
) -> Result<HashSet<u64>, Error> {
|
||||
|
||||
|
@ -86,12 +85,12 @@ pub fn zfs_devices(
|
|||
}
|
||||
}
|
||||
|
||||
for device_list in partition_type_map.iter()
|
||||
.filter_map(|(uuid, list)| if ZFS_UUIDS.contains(uuid.as_str()) { Some(list) } else { None })
|
||||
{
|
||||
for device in device_list {
|
||||
let meta = std::fs::metadata(device)?;
|
||||
device_set.insert(meta.rdev());
|
||||
for info in lsblk_info.iter() {
|
||||
if let Some(partition_type) = &info.partition_type {
|
||||
if ZFS_UUIDS.contains(partition_type.as_str()) {
|
||||
let meta = std::fs::metadata(&info.path)?;
|
||||
device_set.insert(meta.rdev());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue