From: Fabian Ebner <f.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH v3 proxmox-backup 1/3] disks: refactor partition type handling
Date: Fri, 9 Jul 2021 12:32:33 +0200 [thread overview]
Message-ID: <20210709103235.79800-1-f.ebner@proxmox.com> (raw)
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>
---
Changes from v2:
* rebase because of moved file
src/tools/disks/lvm.rs | 18 ++++++++++--------
src/tools/disks/mod.rs | 37 ++++++++++++++++---------------------
src/tools/disks/zfs.rs | 17 ++++++++---------
3 files changed, 34 insertions(+), 38 deletions(-)
diff --git a/src/tools/disks/lvm.rs b/src/tools/disks/lvm.rs
index 1e8f825d..1a81cea0 100644
--- a/src/tools/disks/lvm.rs
+++ b/src/tools/disks/lvm.rs
@@ -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());
+ }
}
}
diff --git a/src/tools/disks/mod.rs b/src/tools/disks/mod.rs
index 1a72a6c8..6e68954c 100644
--- a/src/tools/disks/mod.rs
+++ b/src/tools/disks/mod.rs
@@ -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
diff --git a/src/tools/disks/zfs.rs b/src/tools/disks/zfs.rs
index e0084939..55e0aa30 100644
--- a/src/tools/disks/zfs.rs
+++ b/src/tools/disks/zfs.rs
@@ -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());
+ }
}
}
--
2.30.2
next reply other threads:[~2021-07-09 10:33 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-09 10:32 Fabian Ebner [this message]
2021-07-09 10:32 ` [pbs-devel] [PATCH v3 proxmox-backup 2/3] disks: also check for file systems with lsblk Fabian Ebner
2021-07-09 10:32 ` [pbs-devel] [PATCH v3 proxmox-backup 3/3] api: disk list: sort by name Fabian Ebner
2021-07-09 11:02 ` [pbs-devel] applied-series: [PATCH v3 proxmox-backup 1/3] disks: refactor partition type handling Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210709103235.79800-1-f.ebner@proxmox.com \
--to=f.ebner@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal