src/tools/disks.rs: add/use get_partition_type_info
This commit is contained in:
parent
8d78589969
commit
5c264c8d80
|
@ -15,7 +15,7 @@ use proxmox_backup::server;
|
|||
use proxmox_backup::tools::daemon;
|
||||
use proxmox_backup::server::{ApiConfig, rest::*};
|
||||
use proxmox_backup::auth_helpers::*;
|
||||
use proxmox_backup::tools::disks::{ DiskManage, zfs::zfs_pool_stats };
|
||||
use proxmox_backup::tools::disks::{ DiskManage, zfs_pool_stats };
|
||||
|
||||
fn main() {
|
||||
if let Err(err) = proxmox_backup::tools::runtime::main(run()) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Disk query/management utilities for.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::io;
|
||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
||||
|
@ -16,7 +16,8 @@ use proxmox::sys::error::io_err_other;
|
|||
use proxmox::sys::linux::procfs::{MountInfo, mountinfo::Device};
|
||||
use proxmox::{io_bail, io_format_err};
|
||||
|
||||
pub mod zfs;
|
||||
mod zfs;
|
||||
pub use zfs::*;
|
||||
|
||||
bitflags! {
|
||||
/// Ways a device is being used.
|
||||
|
@ -511,3 +512,42 @@ pub struct BlockDevStat {
|
|||
pub write_sectors: u64,
|
||||
pub io_ticks: u64, // milliseconds
|
||||
}
|
||||
|
||||
/// Use lsblk to read partition type uuids.
|
||||
pub fn get_partition_type_info() -> Result<HashMap<String, Vec<String>>, Error> {
|
||||
|
||||
const LSBLK_BIN_PATH: &str = "/usr/bin/lsblk";
|
||||
|
||||
let mut command = std::process::Command::new(LSBLK_BIN_PATH);
|
||||
command.args(&["--json", "-o", "path,parttype"]);
|
||||
|
||||
let output = command.output()
|
||||
.map_err(|err| format_err!("failed to execute '{}' - {}", LSBLK_BIN_PATH, err))?;
|
||||
|
||||
let output = crate::tools::command_output(output, None)
|
||||
.map_err(|err| format_err!("lsblk command failed: {}", err))?;
|
||||
|
||||
let mut res: HashMap<String, Vec<String>> = HashMap::new();
|
||||
|
||||
let output: serde_json::Value = output.parse()?;
|
||||
match output["blockdevices"].as_array() {
|
||||
Some(list) => {
|
||||
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());
|
||||
}
|
||||
}
|
||||
None => {
|
||||
|
||||
}
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::path::PathBuf;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use anyhow::{bail, Error};
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use nom::{
|
||||
error::VerboseError,
|
||||
bytes::complete::{take_while, take_while1, take_till, take_till1},
|
||||
|
@ -12,6 +15,15 @@ use nom::{
|
|||
|
||||
use super::*;
|
||||
|
||||
lazy_static!{
|
||||
static ref ZFS_UUIDS: HashSet<&'static str> = {
|
||||
let mut set = HashSet::new();
|
||||
set.insert("6a898cc3-1dd2-11b2-99a6-080020736631"); // apple
|
||||
set.insert("516e7cba-6ecf-11d6-8ff8-00022d09712b"); // bsd
|
||||
set
|
||||
};
|
||||
}
|
||||
|
||||
type IResult<I, O, E = VerboseError<I>> = Result<(I, O), nom::Err<E>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -154,7 +166,10 @@ pub fn parse_zfs_list(i: &str) -> Result<Vec<ZFSPoolStatus>, Error> {
|
|||
}
|
||||
|
||||
/// List devices used by zfs (or a specific zfs pool)
|
||||
pub fn zfs_devices(pool: Option<&OsStr>) -> Result<Vec<String>, Error> {
|
||||
pub fn zfs_devices(
|
||||
partition_type_map: &HashMap<String, Vec<String>>,
|
||||
pool: Option<&OsStr>,
|
||||
) -> Result<HashSet<String>, Error> {
|
||||
|
||||
// Note: zpools list output can include entries for 'special', 'cache' and 'logs'
|
||||
// and maybe other things.
|
||||
|
@ -172,17 +187,20 @@ pub fn zfs_devices(pool: Option<&OsStr>) -> Result<Vec<String>, Error> {
|
|||
|
||||
let list = parse_zfs_list(&output)?;
|
||||
|
||||
let mut done = std::collections::HashSet::new();
|
||||
|
||||
let mut device_list = Vec::new();
|
||||
let mut device_set = HashSet::new();
|
||||
for entry in list {
|
||||
for device in entry.devices {
|
||||
if !done.contains(&device) {
|
||||
device_list.push(device.clone());
|
||||
done.insert(device);
|
||||
}
|
||||
device_set.insert(device.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(device_list)
|
||||
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 {
|
||||
device_set.insert(device.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(device_set)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue