mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-08-08 08:52:06 +00:00
datastore: add helper method to open index reader from path
Refactor the archive type and index file reader opening with its error handling into a helper method for better reusability. This allows to use the same logic for both, expected image paths and unexpected image paths when iterating trough the datastore in a hierarchical manner. Improve error handling by switching to anyhow's error context. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
0b016e1efe
commit
c9bd214555
@ -1023,10 +1023,47 @@ impl DataStore {
|
|||||||
Ok(list)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Similar to open index, but ignore index files with blob or unknown archive type.
|
||||||
|
// Further, do not fail if file vanished.
|
||||||
|
fn open_index_reader(&self, absolute_path: &Path) -> Result<Option<Box<dyn IndexFile>>, Error> {
|
||||||
|
let archive_type = match ArchiveType::from_path(absolute_path) {
|
||||||
|
Ok(archive_type) => archive_type,
|
||||||
|
// ignore archives with unknown archive type
|
||||||
|
Err(_) => return Ok(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
if absolute_path.is_relative() {
|
||||||
|
bail!("expected absolute path, got '{absolute_path:?}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = match std::fs::File::open(absolute_path) {
|
||||||
|
Ok(file) => file,
|
||||||
|
// ignore vanished files
|
||||||
|
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None),
|
||||||
|
Err(err) => {
|
||||||
|
return Err(Error::from(err).context(format!("can't open file '{absolute_path:?}'")))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match archive_type {
|
||||||
|
ArchiveType::FixedIndex => {
|
||||||
|
let reader = FixedIndexReader::new(file)
|
||||||
|
.with_context(|| format!("can't open fixed index '{absolute_path:?}'"))?;
|
||||||
|
Ok(Some(Box::new(reader)))
|
||||||
|
}
|
||||||
|
ArchiveType::DynamicIndex => {
|
||||||
|
let reader = DynamicIndexReader::new(file)
|
||||||
|
.with_context(|| format!("can't open dynamic index '{absolute_path:?}'"))?;
|
||||||
|
Ok(Some(Box::new(reader)))
|
||||||
|
}
|
||||||
|
ArchiveType::Blob => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// mark chunks used by ``index`` as used
|
// mark chunks used by ``index`` as used
|
||||||
fn index_mark_used_chunks<I: IndexFile>(
|
fn index_mark_used_chunks(
|
||||||
&self,
|
&self,
|
||||||
index: I,
|
index: Box<dyn IndexFile>,
|
||||||
file_name: &Path, // only used for error reporting
|
file_name: &Path, // only used for error reporting
|
||||||
status: &mut GarbageCollectionStatus,
|
status: &mut GarbageCollectionStatus,
|
||||||
worker: &dyn WorkerTaskContext,
|
worker: &dyn WorkerTaskContext,
|
||||||
@ -1084,24 +1121,8 @@ impl DataStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match std::fs::File::open(&img) {
|
if let Some(index) = self.open_index_reader(&img)? {
|
||||||
Ok(file) => {
|
self.index_mark_used_chunks(index, &img, status, worker)?;
|
||||||
if let Ok(archive_type) = ArchiveType::from_path(&img) {
|
|
||||||
if archive_type == ArchiveType::FixedIndex {
|
|
||||||
let index = FixedIndexReader::new(file).map_err(|e| {
|
|
||||||
format_err!("can't read index '{}' - {}", img.to_string_lossy(), e)
|
|
||||||
})?;
|
|
||||||
self.index_mark_used_chunks(index, &img, status, worker)?;
|
|
||||||
} else if archive_type == ArchiveType::DynamicIndex {
|
|
||||||
let index = DynamicIndexReader::new(file).map_err(|e| {
|
|
||||||
format_err!("can't read index '{}' - {}", img.to_string_lossy(), e)
|
|
||||||
})?;
|
|
||||||
self.index_mark_used_chunks(index, &img, status, worker)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) if err.kind() == io::ErrorKind::NotFound => (), // ignore vanished files
|
|
||||||
Err(err) => bail!("can't open index {} - {}", img.to_string_lossy(), err),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let percentage = (i + 1) * 100 / image_count;
|
let percentage = (i + 1) * 100 / image_count;
|
||||||
@ -1167,7 +1188,8 @@ impl DataStore {
|
|||||||
|
|
||||||
info!("Start GC phase1 (mark used chunks)");
|
info!("Start GC phase1 (mark used chunks)");
|
||||||
|
|
||||||
self.mark_used_chunks(&mut gc_status, worker)?;
|
self.mark_used_chunks(&mut gc_status, worker)
|
||||||
|
.context("marking used chunks failed")?;
|
||||||
|
|
||||||
info!("Start GC phase2 (sweep unused chunks)");
|
info!("Start GC phase2 (sweep unused chunks)");
|
||||||
self.inner.chunk_store.sweep_unused_chunks(
|
self.inner.chunk_store.sweep_unused_chunks(
|
||||||
|
Loading…
Reference in New Issue
Block a user