From 620911b426a7ccba9095ad2f002b8111d7ceebb7 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 4 Jun 2020 09:12:19 +0200 Subject: [PATCH] src/tools/disks/lvm.rs: implement get_lvm_devices() --- src/tools/disks.rs | 2 ++ src/tools/disks/lvm.rs | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/tools/disks/lvm.rs diff --git a/src/tools/disks.rs b/src/tools/disks.rs index edf32272..5596d449 100644 --- a/src/tools/disks.rs +++ b/src/tools/disks.rs @@ -18,6 +18,8 @@ use proxmox::{io_bail, io_format_err}; mod zfs; pub use zfs::*; +mod lvm; +pub use lvm::*; bitflags! { /// Ways a device is being used. diff --git a/src/tools/disks/lvm.rs b/src/tools/disks/lvm.rs new file mode 100644 index 00000000..86b2a616 --- /dev/null +++ b/src/tools/disks/lvm.rs @@ -0,0 +1,55 @@ +use std::collections::{HashSet, HashMap}; + +use anyhow::{format_err, Error}; +use serde_json::Value; +use lazy_static::lazy_static; + +lazy_static!{ + static ref LVM_UUIDS: HashSet<&'static str> = { + let mut set = HashSet::new(); + set.insert("e6d6d379-f507-44c2-a23c-238f2a3df928"); + set + }; +} + +/// Get list of devices used by LVM (pvs). +pub fn get_lvm_devices( + partition_type_map: &HashMap>, +) -> Result, Error> { + + const PVS_BIN_PATH: &str = "/sbin/pvs"; + + let mut command = std::process::Command::new(PVS_BIN_PATH); + command.args(&["--reportformat", "json", "--noheadings", "--readonly", "-o", "pv_name"]); + + let output = command.output() + .map_err(|err| format_err!("failed to execute '{}' - {}", PVS_BIN_PATH, err))?; + + let output = crate::tools::command_output(output, None) + .map_err(|err| format_err!("pvs command failed: {}", err))?; + + let mut device_set: HashSet = 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 output: Value = output.parse()?; + + match output["report"][0]["pv"].as_array() { + Some(list) => { + for info in list { + if let Some(pv_name) = info["pv_name"].as_str() { + device_set.insert(pv_name.to_string()); + } + } + } + None => return Ok(device_set), + } + + Ok(device_set) +}