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()); .unwrap_or_else(|_| set.uuid.to_string());
for (store, snapshot) in media_catalog_snapshot_list(status_path, &media_id)? { 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 let Some(backup_type) = filter.backup_type {
if backup_dir.ty() != backup_type { if backup_dir.ty() != backup_type {

View File

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

View File

@ -22,7 +22,9 @@ pub fn tape_write_snapshot_archive<'a>(
writer: &mut (dyn TapeWrite + 'a), writer: &mut (dyn TapeWrite + 'a),
snapshot_reader: &SnapshotReader, snapshot_reader: &SnapshotReader,
) -> Result<Option<Uuid>, std::io::Error> { ) -> 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 store = snapshot_reader.datastore_name().to_string();
let file_list = snapshot_reader.file_list(); 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_sys::fs::{create_path, fchown, CreateOptions};
use proxmox_uuid::Uuid; 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}; use crate::tape::{file_formats::MediaSetLabel, MediaId};
pub struct DatastoreContent { pub struct DatastoreContent {
@ -656,7 +658,7 @@ impl MediaCatalog {
Ok(()) 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() { if self.current_archive.is_some() {
bail!("register_snapshot failed: inside chunk_archive"); 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(()) Ok(())
} }
@ -698,25 +692,22 @@ impl MediaCatalog {
uuid: Uuid, // Uuid form MediaContentHeader uuid: Uuid, // Uuid form MediaContentHeader
file_number: u64, file_number: u64,
store: &str, store: &str,
snapshot: &str, ns: &BackupNamespace,
snapshot: &BackupDir,
) -> Result<(), Error> { ) -> 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 { let entry = SnapshotEntry {
file_number, file_number,
uuid: *uuid.as_bytes(), uuid: *uuid.as_bytes(),
store_name_len: u8::try_from(store.len())?, 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 { if self.log_to_stdout {
println!( println!("S|{}|{}|{}:{}", file_number, uuid.to_string(), store, path,);
"S|{}|{}|{}:{}",
file_number,
uuid.to_string(),
store,
snapshot
);
} }
self.pending.push(b'S'); self.pending.push(b'S');
@ -726,16 +717,14 @@ impl MediaCatalog {
} }
self.pending.extend(store.as_bytes()); self.pending.extend(store.as_bytes());
self.pending.push(b':'); self.pending.push(b':');
self.pending.extend(snapshot.as_bytes()); self.pending.extend(path.as_bytes());
let content = self let content = self
.content .content
.entry(store.to_string()) .entry(store.to_string())
.or_insert(DatastoreContent::new()); .or_insert(DatastoreContent::new());
content content.snapshot_index.insert(path, file_number);
.snapshot_index
.insert(snapshot.to_string(), file_number);
self.last_entry = Some((uuid, 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 = file.read_exact_allocated(name_len)?;
let snapshot = std::str::from_utf8(&snapshot)?; 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 let content = self
.content .content

View File

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

View File

@ -420,7 +420,8 @@ impl PoolWriter {
content_uuid, content_uuid,
current_file_number, current_file_number,
&snapshot_reader.datastore_name().to_string(), &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()) (true, writer.bytes_written())
} }