From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id D5B4874754 for ; Fri, 9 Jul 2021 12:33:17 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C964723EFF for ; Fri, 9 Jul 2021 12:32:47 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id EDC5623EF6 for ; Fri, 9 Jul 2021 12:32:46 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id AFE2140EFB for ; Fri, 9 Jul 2021 12:32:40 +0200 (CEST) From: Fabian Ebner To: pbs-devel@lists.proxmox.com Date: Fri, 9 Jul 2021 12:32:33 +0200 Message-Id: <20210709103235.79800-1-f.ebner@proxmox.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.529 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [mod.rs, zfs.rs, lvm.rs] Subject: [pbs-devel] [PATCH v3 proxmox-backup 1/3] disks: refactor partition type handling X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Jul 2021 10:33:17 -0000 in preparation to also get the file system type from lsblk. Co-developed-by: Wolfgang Bumiller Signed-off-by: Fabian Ebner --- 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>, + lsblk_info: &[LsblkInfo], ) -> Result, Error> { const PVS_BIN_PATH: &str = "pvs"; @@ -29,12 +31,12 @@ pub fn get_lvm_devices( 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 { - 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>, } +/// 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, +} + impl DiskManage { /// Create a new disk management context. pub fn new() -> Arc { @@ -556,31 +566,16 @@ pub struct BlockDevStat { } /// Use lsblk to read partition type uuids. -pub fn get_partition_type_info() -> Result>, Error> { +pub fn get_lsblk_info() -> Result, 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> = 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, Error> { + let zfs_devices = zfs_devices(&lsblk_info, None).or_else(|err| -> Result, 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, 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>, + lsblk_info: &[LsblkInfo], pool: Option, ) -> Result, 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