tape: fix snapshot path in catalog and snapshot_archive

both used the 'Display' trait of pbs_datastore::BackupDir, which is not
intended to be serialized anywhere. Instead, manually format the path
using the print_ns_and_snapshot helper, and conversely, parse with
'parse_ns_and_snapshot'. to be a bit safer, change the register_snapshot
signature to take a BackupNamespace and BackupDir instead of a string.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2022-05-10 16:09:42 +02:00
parent 1e4e1514d3
commit 9c65e6ab4a
6 changed files with 27 additions and 31 deletions

View File

@ -438,7 +438,7 @@ pub fn list_content(
.unwrap_or_else(|_| set.uuid.to_string());
for (store, snapshot) in media_catalog_snapshot_list(status_path, &media_id)? {
let backup_dir: pbs_api_types::BackupDir = snapshot.parse()?;
let (_, backup_dir) = pbs_api_types::parse_ns_and_snapshot(&snapshot)?;
if let Some(backup_type) = filter.backup_type {
if backup_dir.ty() != backup_type {

View File

@ -1084,7 +1084,8 @@ fn restore_archive<'a>(
Uuid::from(header.uuid),
current_file_number,
&datastore_name,
&snapshot,
&backup_ns,
&backup_dir,
)?;
catalog.commit_if_large()?;
}
@ -1102,7 +1103,8 @@ fn restore_archive<'a>(
Uuid::from(header.uuid),
current_file_number,
&datastore_name,
&snapshot,
&backup_ns,
&backup_dir,
)?;
catalog.commit_if_large()?;
}

View File

@ -22,7 +22,9 @@ pub fn tape_write_snapshot_archive<'a>(
writer: &mut (dyn TapeWrite + 'a),
snapshot_reader: &SnapshotReader,
) -> Result<Option<Uuid>, std::io::Error> {
let snapshot = snapshot_reader.snapshot().to_string();
let backup_dir = snapshot_reader.snapshot();
let snapshot =
pbs_api_types::print_ns_and_snapshot(backup_dir.backup_ns(), backup_dir.as_ref());
let store = snapshot_reader.datastore_name().to_string();
let file_list = snapshot_reader.file_list();

View File

@ -14,6 +14,8 @@ use proxmox_io::{ReadExt, WriteExt};
use proxmox_sys::fs::{create_path, fchown, CreateOptions};
use proxmox_uuid::Uuid;
use pbs_api_types::{parse_ns_and_snapshot, print_ns_and_snapshot, BackupDir, BackupNamespace};
use crate::tape::{file_formats::MediaSetLabel, MediaId};
pub struct DatastoreContent {
@ -656,7 +658,7 @@ impl MediaCatalog {
Ok(())
}
fn check_register_snapshot(&self, file_number: u64, snapshot: &str) -> Result<(), Error> {
fn check_register_snapshot(&self, file_number: u64) -> Result<(), Error> {
if self.current_archive.is_some() {
bail!("register_snapshot failed: inside chunk_archive");
}
@ -681,14 +683,6 @@ impl MediaCatalog {
);
}
if let Err(err) = snapshot.parse::<pbs_api_types::BackupDir>() {
bail!(
"register_snapshot failed: unable to parse snapshot '{}' - {}",
snapshot,
err
);
}
Ok(())
}
@ -698,25 +692,22 @@ impl MediaCatalog {
uuid: Uuid, // Uuid form MediaContentHeader
file_number: u64,
store: &str,
snapshot: &str,
ns: &BackupNamespace,
snapshot: &BackupDir,
) -> Result<(), Error> {
self.check_register_snapshot(file_number, snapshot)?;
self.check_register_snapshot(file_number)?;
let path = print_ns_and_snapshot(ns, snapshot);
let entry = SnapshotEntry {
file_number,
uuid: *uuid.as_bytes(),
store_name_len: u8::try_from(store.len())?,
name_len: u16::try_from(snapshot.len())?,
name_len: u16::try_from(path.len())?,
};
if self.log_to_stdout {
println!(
"S|{}|{}|{}:{}",
file_number,
uuid.to_string(),
store,
snapshot
);
println!("S|{}|{}|{}:{}", file_number, uuid.to_string(), store, path,);
}
self.pending.push(b'S');
@ -726,16 +717,14 @@ impl MediaCatalog {
}
self.pending.extend(store.as_bytes());
self.pending.push(b':');
self.pending.extend(snapshot.as_bytes());
self.pending.extend(path.as_bytes());
let content = self
.content
.entry(store.to_string())
.or_insert(DatastoreContent::new());
content
.snapshot_index
.insert(snapshot.to_string(), file_number);
content.snapshot_index.insert(path, file_number);
self.last_entry = Some((uuid, file_number));
@ -891,7 +880,8 @@ impl MediaCatalog {
let snapshot = file.read_exact_allocated(name_len)?;
let snapshot = std::str::from_utf8(&snapshot)?;
self.check_register_snapshot(file_number, snapshot)?;
let _ = parse_ns_and_snapshot(snapshot)?;
self.check_register_snapshot(file_number)?;
let content = self
.content

View File

@ -69,11 +69,12 @@ impl CatalogSet {
uuid: Uuid, // Uuid form MediaContentHeader
file_number: u64,
store: &str,
snapshot: &str,
ns: &pbs_api_types::BackupNamespace,
snapshot: &pbs_api_types::BackupDir,
) -> Result<(), Error> {
match self.catalog {
Some(ref mut catalog) => {
catalog.register_snapshot(uuid, file_number, store, snapshot)?;
catalog.register_snapshot(uuid, file_number, store, ns, snapshot)?;
}
None => bail!("no catalog loaded - internal error"),
}

View File

@ -420,7 +420,8 @@ impl PoolWriter {
content_uuid,
current_file_number,
&snapshot_reader.datastore_name().to_string(),
&snapshot_reader.snapshot().to_string(),
snapshot_reader.snapshot().backup_ns(),
snapshot_reader.snapshot().as_ref(),
)?;
(true, writer.bytes_written())
}