tape: add magic number to identify media catalog files
This commit is contained in:
		@ -1,6 +1,7 @@
 | 
			
		||||
use std::convert::TryFrom;
 | 
			
		||||
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::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
@ -25,6 +26,9 @@ use crate::{
 | 
			
		||||
    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
 | 
			
		||||
///
 | 
			
		||||
/// Stores what chunks and snapshots are stored on a specific media,
 | 
			
		||||
@ -109,12 +113,9 @@ impl MediaCatalog {
 | 
			
		||||
                .create(create)
 | 
			
		||||
                .open(&path)?;
 | 
			
		||||
 | 
			
		||||
            use std::os::unix::io::AsRawFd;
 | 
			
		||||
 | 
			
		||||
            let backup_user = crate::backup::backup_user()?;
 | 
			
		||||
            if let Err(err) = fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid)) {
 | 
			
		||||
                bail!("fchown on media catalog {:?} failed - {}", path, err);
 | 
			
		||||
            }
 | 
			
		||||
            fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid))
 | 
			
		||||
                .map_err(|err| format_err!("fchown failed - {}", err))?;
 | 
			
		||||
 | 
			
		||||
            let mut me = Self {
 | 
			
		||||
                uuid: uuid.clone(),
 | 
			
		||||
@ -127,7 +128,11 @@ impl MediaCatalog {
 | 
			
		||||
                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 {
 | 
			
		||||
                me.file = Some(file);
 | 
			
		||||
@ -147,15 +152,16 @@ impl MediaCatalog {
 | 
			
		||||
        log_to_stdout: bool,
 | 
			
		||||
    ) -> Result<Self, Error> {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Self::create_basedir(base_path)?;
 | 
			
		||||
 | 
			
		||||
        let uuid = &label_info.label.uuid;
 | 
			
		||||
 | 
			
		||||
        let mut tmp_path = base_path.to_owned();
 | 
			
		||||
        tmp_path.push(uuid.to_string());
 | 
			
		||||
        tmp_path.set_extension("tmp");
 | 
			
		||||
 | 
			
		||||
        let me = proxmox::try_block!({
 | 
			
		||||
 | 
			
		||||
            Self::create_basedir(base_path)?;
 | 
			
		||||
 | 
			
		||||
            let file = std::fs::OpenOptions::new()
 | 
			
		||||
                .read(true)
 | 
			
		||||
                .write(true)
 | 
			
		||||
@ -163,12 +169,9 @@ impl MediaCatalog {
 | 
			
		||||
                .truncate(true)
 | 
			
		||||
                .open(&tmp_path)?;
 | 
			
		||||
 | 
			
		||||
        use std::os::unix::io::AsRawFd;
 | 
			
		||||
 | 
			
		||||
            let backup_user = crate::backup::backup_user()?;
 | 
			
		||||
        if let Err(err) = fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid)) {
 | 
			
		||||
            bail!("fchown on media catalog {:?} failed - {}", tmp_path, err);
 | 
			
		||||
        }
 | 
			
		||||
            fchown(file.as_raw_fd(), Some(backup_user.uid), Some(backup_user.gid))
 | 
			
		||||
                .map_err(|err| format_err!("fchown failed - {}", err))?;
 | 
			
		||||
 | 
			
		||||
            let mut me = Self {
 | 
			
		||||
                uuid: uuid.clone(),
 | 
			
		||||
@ -189,8 +192,14 @@ impl MediaCatalog {
 | 
			
		||||
                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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -525,11 +534,28 @@ impl MediaCatalog {
 | 
			
		||||
        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 found_magic_number = false;
 | 
			
		||||
 | 
			
		||||
        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];
 | 
			
		||||
            match file.read_exact_or_eof(&mut entry_type) {
 | 
			
		||||
                Ok(false) => { /* EOF */ break; }
 | 
			
		||||
@ -597,7 +623,7 @@ impl MediaCatalog {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
        Ok(found_magic_number)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user