tape: add magic number to identify media catalog files
This commit is contained in:
parent
39478aa52c
commit
42298d5896
@ -1,6 +1,7 @@
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Write, Read, BufReader};
|
use std::io::{Write, Read, BufReader, Seek, SeekFrom};
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -25,6 +26,9 @@ use crate::{
|
|||||||
tape::drive::MediaLabelInfo,
|
tape::drive::MediaLabelInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// openssl::sha::sha256(b"Proxmox Backup Media Catalog v1.0")[0..8]
|
||||||
|
pub const PROXMOX_BACKUP_MEDIA_CATALOG_MAGIC_1_0: [u8; 8] = [221, 29, 164, 1, 59, 69, 19, 40];
|
||||||
|
|
||||||
/// The Media Catalog
|
/// The Media Catalog
|
||||||
///
|
///
|
||||||
/// Stores what chunks and snapshots are stored on a specific media,
|
/// Stores what chunks and snapshots are stored on a specific media,
|
||||||
@ -109,12 +113,9 @@ impl MediaCatalog {
|
|||||||
.create(create)
|
.create(create)
|
||||||
.open(&path)?;
|
.open(&path)?;
|
||||||
|
|
||||||
use std::os::unix::io::AsRawFd;
|
|
||||||
|
|
||||||
let backup_user = crate::backup::backup_user()?;
|
let backup_user = crate::backup::backup_user()?;
|
||||||
if let Err(err) = fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid)) {
|
fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid))
|
||||||
bail!("fchown on media catalog {:?} failed - {}", path, err);
|
.map_err(|err| format_err!("fchown failed - {}", err))?;
|
||||||
}
|
|
||||||
|
|
||||||
let mut me = Self {
|
let mut me = Self {
|
||||||
uuid: uuid.clone(),
|
uuid: uuid.clone(),
|
||||||
@ -127,7 +128,11 @@ impl MediaCatalog {
|
|||||||
pending: Vec::new(),
|
pending: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
me.load_catalog(&mut file)?;
|
let found_magic_number = me.load_catalog(&mut file)?;
|
||||||
|
|
||||||
|
if !found_magic_number {
|
||||||
|
me.pending.extend(&PROXMOX_BACKUP_MEDIA_CATALOG_MAGIC_1_0);
|
||||||
|
}
|
||||||
|
|
||||||
if write {
|
if write {
|
||||||
me.file = Some(file);
|
me.file = Some(file);
|
||||||
@ -147,49 +152,53 @@ impl MediaCatalog {
|
|||||||
log_to_stdout: bool,
|
log_to_stdout: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
||||||
|
|
||||||
Self::create_basedir(base_path)?;
|
|
||||||
|
|
||||||
let uuid = &label_info.label.uuid;
|
let uuid = &label_info.label.uuid;
|
||||||
|
|
||||||
let mut tmp_path = base_path.to_owned();
|
let mut tmp_path = base_path.to_owned();
|
||||||
tmp_path.push(uuid.to_string());
|
tmp_path.push(uuid.to_string());
|
||||||
tmp_path.set_extension("tmp");
|
tmp_path.set_extension("tmp");
|
||||||
|
|
||||||
let file = std::fs::OpenOptions::new()
|
let me = proxmox::try_block!({
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.create(true)
|
|
||||||
.truncate(true)
|
|
||||||
.open(&tmp_path)?;
|
|
||||||
|
|
||||||
use std::os::unix::io::AsRawFd;
|
Self::create_basedir(base_path)?;
|
||||||
|
|
||||||
let backup_user = crate::backup::backup_user()?;
|
let file = std::fs::OpenOptions::new()
|
||||||
if let Err(err) = fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid)) {
|
.read(true)
|
||||||
bail!("fchown on media catalog {:?} failed - {}", tmp_path, err);
|
.write(true)
|
||||||
}
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(&tmp_path)?;
|
||||||
|
|
||||||
let mut me = Self {
|
let backup_user = crate::backup::backup_user()?;
|
||||||
uuid: uuid.clone(),
|
fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid))
|
||||||
file: Some(file),
|
.map_err(|err| format_err!("fchown failed - {}", err))?;
|
||||||
log_to_stdout: false,
|
|
||||||
current_archive: None,
|
|
||||||
last_entry: None,
|
|
||||||
chunk_index: HashMap::new(),
|
|
||||||
snapshot_index: HashMap::new(),
|
|
||||||
pending: Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
me.log_to_stdout = log_to_stdout;
|
let mut me = Self {
|
||||||
|
uuid: uuid.clone(),
|
||||||
|
file: Some(file),
|
||||||
|
log_to_stdout: false,
|
||||||
|
current_archive: None,
|
||||||
|
last_entry: None,
|
||||||
|
chunk_index: HashMap::new(),
|
||||||
|
snapshot_index: HashMap::new(),
|
||||||
|
pending: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
me.register_label(&label_info.label_uuid, 0)?;
|
me.log_to_stdout = log_to_stdout;
|
||||||
|
|
||||||
if let Some((_, ref content_uuid)) = label_info.media_set_label {
|
me.register_label(&label_info.label_uuid, 0)?;
|
||||||
me.register_label(&content_uuid, 1)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
me.commit()?;
|
if let Some((_, ref content_uuid)) = label_info.media_set_label {
|
||||||
|
me.register_label(&content_uuid, 1)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
me.pending.extend(&PROXMOX_BACKUP_MEDIA_CATALOG_MAGIC_1_0);
|
||||||
|
me.commit()?;
|
||||||
|
|
||||||
|
Ok(me)
|
||||||
|
}).map_err(|err: Error| {
|
||||||
|
format_err!("unable to create temporary media catalog {:?} - {}", tmp_path, err)
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(me)
|
Ok(me)
|
||||||
}
|
}
|
||||||
@ -525,11 +534,28 @@ impl MediaCatalog {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_catalog(&mut self, file: &mut File) -> Result<(), Error> {
|
fn load_catalog(&mut self, file: &mut File) -> Result<bool, Error> {
|
||||||
|
|
||||||
let mut file = BufReader::new(file);
|
let mut file = BufReader::new(file);
|
||||||
|
let mut found_magic_number = false;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
let pos = file.seek(SeekFrom::Current(0))?;
|
||||||
|
|
||||||
|
if pos == 0 { // read/check magic number
|
||||||
|
let mut magic = [0u8; 8];
|
||||||
|
match file.read_exact_or_eof(&mut magic) {
|
||||||
|
Ok(false) => { /* EOF */ break; }
|
||||||
|
Ok(true) => { /* OK */ }
|
||||||
|
Err(err) => bail!("read failed - {}", err),
|
||||||
|
}
|
||||||
|
if magic != PROXMOX_BACKUP_MEDIA_CATALOG_MAGIC_1_0 {
|
||||||
|
bail!("wrong magic number");
|
||||||
|
}
|
||||||
|
found_magic_number = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let mut entry_type = [0u8; 1];
|
let mut entry_type = [0u8; 1];
|
||||||
match file.read_exact_or_eof(&mut entry_type) {
|
match file.read_exact_or_eof(&mut entry_type) {
|
||||||
Ok(false) => { /* EOF */ break; }
|
Ok(false) => { /* EOF */ break; }
|
||||||
@ -597,7 +623,7 @@ impl MediaCatalog {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(found_magic_number)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user