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::tools::daemon;
|
||||||
use proxmox_backup::server::{ApiConfig, rest::*};
|
use proxmox_backup::server::{ApiConfig, rest::*};
|
||||||
use proxmox_backup::auth_helpers::*;
|
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() {
|
fn main() {
|
||||||
if let Err(err) = proxmox_backup::tools::runtime::main(run()) {
|
if let Err(err) = proxmox_backup::tools::runtime::main(run()) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Disk query/management utilities for.
|
//! Disk query/management utilities for.
|
||||||
|
|
||||||
use std::collections::HashSet;
|
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};
|
||||||
|
@ -16,7 +16,8 @@ use proxmox::sys::error::io_err_other;
|
||||||
use proxmox::sys::linux::procfs::{MountInfo, mountinfo::Device};
|
use proxmox::sys::linux::procfs::{MountInfo, mountinfo::Device};
|
||||||
use proxmox::{io_bail, io_format_err};
|
use proxmox::{io_bail, io_format_err};
|
||||||
|
|
||||||
pub mod zfs;
|
mod zfs;
|
||||||
|
pub use zfs::*;
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Ways a device is being used.
|
/// Ways a device is being used.
|
||||||
|
@ -511,3 +512,42 @@ pub struct BlockDevStat {
|
||||||
pub write_sectors: u64,
|
pub write_sectors: u64,
|
||||||
pub io_ticks: u64, // milliseconds
|
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::path::PathBuf;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, Error};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use nom::{
|
use nom::{
|
||||||
error::VerboseError,
|
error::VerboseError,
|
||||||
bytes::complete::{take_while, take_while1, take_till, take_till1},
|
bytes::complete::{take_while, take_while1, take_till, take_till1},
|
||||||
|
@ -12,6 +15,15 @@ use nom::{
|
||||||
|
|
||||||
use super::*;
|
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>>;
|
type IResult<I, O, E = VerboseError<I>> = Result<(I, O), nom::Err<E>>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[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)
|
/// 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'
|
// Note: zpools list output can include entries for 'special', 'cache' and 'logs'
|
||||||
// and maybe other things.
|
// 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 list = parse_zfs_list(&output)?;
|
||||||
|
|
||||||
let mut done = std::collections::HashSet::new();
|
let mut device_set = HashSet::new();
|
||||||
|
|
||||||
let mut device_list = Vec::new();
|
|
||||||
for entry in list {
|
for entry in list {
|
||||||
for device in entry.devices {
|
for device in entry.devices {
|
||||||
if !done.contains(&device) {
|
device_set.insert(device.clone());
|
||||||
device_list.push(device.clone());
|
|
||||||
done.insert(device);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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