From: Stefan Reiter <s.reiter@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup 2/3] file-restore-daemon: disk: allow arbitrary component count per bucket
Date: Mon, 17 May 2021 14:31:36 +0200 [thread overview]
Message-ID: <20210517123137.25547-2-s.reiter@proxmox.com> (raw)
In-Reply-To: <20210517123137.25547-1-s.reiter@proxmox.com>
A bucket might contain multiple (or 0) layers of components in its path
specification, so allow a mapping between bucket type strings and
expected component depth. For partitions, this is 1, as there is only
the partition number layer below the "part" node.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
---
src/bin/proxmox_restore_daemon/disk.rs | 83 ++++++++++++++++++--------
1 file changed, 59 insertions(+), 24 deletions(-)
diff --git a/src/bin/proxmox_restore_daemon/disk.rs b/src/bin/proxmox_restore_daemon/disk.rs
index a59d6360..8ad270fa 100644
--- a/src/bin/proxmox_restore_daemon/disk.rs
+++ b/src/bin/proxmox_restore_daemon/disk.rs
@@ -68,12 +68,17 @@ impl Bucket {
fn filter_mut<'a, A: AsRef<str>, B: AsRef<str>>(
haystack: &'a mut Vec<Bucket>,
ty: A,
- comp: B,
+ comp: &[B],
) -> Option<&'a mut Bucket> {
let ty = ty.as_ref();
- let comp = comp.as_ref();
haystack.iter_mut().find(|b| match b {
- Bucket::Partition(data) => ty == "part" && comp.parse::<i32>().unwrap() == data.number,
+ Bucket::Partition(data) => {
+ if let Some(comp) = comp.get(0) {
+ ty == "part" && comp.as_ref().parse::<i32>().unwrap() == data.number
+ } else {
+ false
+ }
+ }
})
}
@@ -83,10 +88,26 @@ impl Bucket {
}
}
- fn component_string(&self) -> String {
- match self {
- Bucket::Partition(data) => data.number.to_string(),
+ fn component_string(&self, idx: usize) -> Result<String, Error> {
+ let max_depth = Self::component_depth(self.type_string())?;
+ if idx >= max_depth {
+ bail!(
+ "internal error: component index out of range {}/{} ({})",
+ idx,
+ max_depth,
+ self.type_string()
+ );
}
+ Ok(match self {
+ Bucket::Partition(data) => data.number.to_string(),
+ })
+ }
+
+ fn component_depth(type_string: &str) -> Result<usize, Error> {
+ Ok(match type_string {
+ "part" => 1,
+ _ => bail!("invalid bucket type for component depth: {}", type_string),
+ })
}
fn size(&self) -> u64 {
@@ -299,27 +320,41 @@ impl DiskState {
}
};
- let component = match cmp.next() {
- Some(Component::Normal(x)) => x.to_string_lossy(),
- Some(c) => bail!("invalid bucket component in path: {:?}", c),
- None => {
- // list bucket components available
- let comps = buckets
- .iter()
- .filter(|b| b.type_string() == bucket_type)
- .map(|b| (b.component_string(), b.size()))
- .collect();
- return Ok(ResolveResult::BucketComponents(comps));
- }
- };
+ let mut components = Vec::new();
+ let component_count = Bucket::component_depth(&bucket_type)?;
- let mut bucket = match Bucket::filter_mut(buckets, &bucket_type, &component) {
+ while components.len() < component_count {
+ let component = match cmp.next() {
+ Some(Component::Normal(x)) => x.to_string_lossy(),
+ Some(c) => bail!("invalid bucket component in path: {:?}", c),
+ None => {
+ // list bucket components available at this level
+ let 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())),
+ Err(_) => None,
+ }
+ })
+ .collect();
+ return Ok(ResolveResult::BucketComponents(comps));
+ }
+ };
+
+ components.push(component);
+ }
+
+ let mut bucket = match Bucket::filter_mut(buckets, &bucket_type, &components) {
Some(bucket) => bucket,
None => bail!(
- "bucket/component path not found: {}/{}/{}",
+ "bucket/component path not found: {}/{}/{:?}",
req_fidx,
bucket_type,
- component
+ components
),
};
@@ -329,10 +364,10 @@ impl DiskState {
.ensure_mounted(&mut bucket)
.map_err(|err| {
format_err!(
- "mounting '{}/{}/{}' failed: {}",
+ "mounting '{}/{}/{:?}' failed: {}",
req_fidx,
bucket_type,
- component,
+ components,
err
)
})?;
--
2.20.1
next prev parent reply other threads:[~2021-05-17 12:31 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-17 12:31 [pbs-devel] [PATCH proxmox-backup 1/3] file-restore-daemon: disk: ignore "invalid fs" error Stefan Reiter
2021-05-17 12:31 ` Stefan Reiter [this message]
2021-05-17 12:31 ` [pbs-devel] [PATCH proxmox-backup 3/3] file-restore-daemon: disk: add RawFs bucket type Stefan Reiter
2021-05-25 5:55 ` [pbs-devel] applied-series: [PATCH proxmox-backup 1/3] file-restore-daemon: disk: ignore "invalid fs" error 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=20210517123137.25547-2-s.reiter@proxmox.com \
--to=s.reiter@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.