2020-06-04 07:12:19 +00:00
|
|
|
use std::collections::{HashSet, HashMap};
|
2020-06-08 07:01:34 +00:00
|
|
|
use std::os::unix::fs::MetadataExt;
|
2020-06-04 07:12:19 +00:00
|
|
|
|
2020-06-16 07:46:06 +00:00
|
|
|
use anyhow::{Error};
|
2020-06-04 07:12:19 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-06-08 07:01:34 +00:00
|
|
|
/// Get set of devices used by LVM (pvs).
|
2020-06-08 15:27:13 +00:00
|
|
|
///
|
|
|
|
/// The set is indexed by using the unix raw device number (dev_t is u64)
|
2020-06-04 07:12:19 +00:00
|
|
|
pub fn get_lvm_devices(
|
|
|
|
partition_type_map: &HashMap<String, Vec<String>>,
|
2020-06-08 07:01:34 +00:00
|
|
|
) -> Result<HashSet<u64>, Error> {
|
2020-06-04 07:12:19 +00:00
|
|
|
|
2020-06-15 09:16:11 +00:00
|
|
|
const PVS_BIN_PATH: &str = "pvs";
|
2020-06-04 07:12:19 +00:00
|
|
|
|
|
|
|
let mut command = std::process::Command::new(PVS_BIN_PATH);
|
|
|
|
command.args(&["--reportformat", "json", "--noheadings", "--readonly", "-o", "pv_name"]);
|
|
|
|
|
2020-06-16 05:53:23 +00:00
|
|
|
let output = crate::tools::run_command(command, None)?;
|
2020-06-04 07:12:19 +00:00
|
|
|
|
2020-06-08 07:01:34 +00:00
|
|
|
let mut device_set: HashSet<u64> = HashSet::new();
|
2020-06-04 07:12:19 +00:00
|
|
|
|
|
|
|
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 {
|
2020-06-08 07:01:34 +00:00
|
|
|
let meta = std::fs::metadata(device)?;
|
|
|
|
device_set.insert(meta.rdev());
|
2020-06-04 07:12:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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() {
|
2020-06-08 07:01:34 +00:00
|
|
|
let meta = std::fs::metadata(pv_name)?;
|
|
|
|
device_set.insert(meta.rdev());
|
2020-06-04 07:12:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => return Ok(device_set),
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(device_set)
|
|
|
|
}
|