From 0dda88399440858970602768e8ba7d7adb6cfefb Mon Sep 17 00:00:00 2001 From: Stefan Reiter Date: Wed, 30 Jun 2021 17:57:56 +0200 Subject: [PATCH] file-restore-daemon/disk: dedup BucketComponents and make size optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support nested BucketComponents, it is necessary to dedup them, as otherwise two components like: /foo/bar /foo/baz will result in /foo being shown twice at the first hierarchy. Also make the size property based on index and optional, as for example /foo in the example above might not have a size, and bar/baz might have differing sizes. Signed-off-by: Stefan Reiter Reviewed-By: Fabian Grünbichler --- src/bin/proxmox_restore_daemon/api.rs | 2 +- src/bin/proxmox_restore_daemon/disk.rs | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/bin/proxmox_restore_daemon/api.rs b/src/bin/proxmox_restore_daemon/api.rs index 42328fb7..d7355370 100644 --- a/src/bin/proxmox_restore_daemon/api.rs +++ b/src/bin/proxmox_restore_daemon/api.rs @@ -208,7 +208,7 @@ fn list( &c_path[..], // this marks the beginning of a filesystem, i.e. '/', so this is a Directory Some(&DirEntryAttribute::Directory { start: 0 }), - Some(c.1), + c.1, )); } } diff --git a/src/bin/proxmox_restore_daemon/disk.rs b/src/bin/proxmox_restore_daemon/disk.rs index 9d0cbe32..b90d2a28 100644 --- a/src/bin/proxmox_restore_daemon/disk.rs +++ b/src/bin/proxmox_restore_daemon/disk.rs @@ -44,7 +44,7 @@ lazy_static! { pub enum ResolveResult { Path(PathBuf), BucketTypes(Vec<&'static str>), - BucketComponents(Vec<(String, u64)>), + BucketComponents(Vec<(String, Option)>), } #[derive(Clone)] @@ -59,7 +59,7 @@ struct PartitionBucketData { struct ZFSBucketData { name: String, mountpoint: Option, - size: u64, + size: Option, } /// A "Bucket" represents a mapping found on a disk, e.g. a partition, a zfs dataset or an LV. A @@ -139,9 +139,9 @@ impl Bucket { }) } - fn size(&self) -> u64 { + fn size(&self, idx: usize) -> Option { match self { - Bucket::Partition(data) | Bucket::RawFs(data) => data.size, + Bucket::Partition(data) | Bucket::RawFs(data) => Some(data.size), Bucket::ZPool(data) => data.size, } } @@ -261,7 +261,7 @@ impl Filesystems { cmd.args(["list", "-o", "size", "-Hp", &data.name].iter()); let size = run_command(cmd, None)?; if let Ok(size) = size.trim().parse::() { - data.size = size; + data.size = Some(size); } let mp = PathBuf::from(mntpath); @@ -409,7 +409,7 @@ impl DiskState { for (pool, disks) in Self::parse_zpool_import(&result) { let mut bucket = Bucket::ZPool(ZFSBucketData { name: pool.clone(), - size: 0, + size: None, mountpoint: None, }); @@ -418,11 +418,11 @@ impl DiskState { if disks.len() <= 5 { let mp = filesystems.ensure_mounted(&mut bucket); info!( - "zpool '{}' (on: {:?}) auto-mounted at '{:?}' (size: {}B)", + "zpool '{}' (on: {:?}) auto-mounted at '{:?}' (size: {:?})", &pool, &disks, mp, - bucket.size() + bucket.size(0) ); } else { info!( @@ -503,18 +503,20 @@ impl DiskState { Some(c) => bail!("invalid bucket component in path: {:?}", c), None => { // list bucket components available at this level - let comps = buckets + let mut comps = buckets .iter() .filter_map(|b| { if b.type_string() != bucket_type { return None; } match b.component_string(components.len()) { - Ok(cs) => Some((cs.to_owned(), b.size())), + Ok(cs) => Some((cs.to_owned(), b.size(components.len()))), Err(_) => None, } }) - .collect(); + .collect::)>>(); + comps.sort_by(|a, b| a.0.cmp(&b.0)); + comps.dedup(); return Ok(ResolveResult::BucketComponents(comps)); } };