mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-10-04 22:02:47 +00:00

If the `notification-mode` parameter is set to `legacy-sendmail`, then we still use the new infrastructure, but don't consider the notification config and use a hard-coded sendmail endpoint directly. Signed-off-by: Lukas Wagner <l.wagner@proxmox.com> Tested-by: Gabriel Goller <g.goller@proxmox.com> Reviewed-by: Gabriel Goller <g.goller@proxmox.com> Tested-by: Maximiliano Sandoval <m.sandoval@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
158 lines
4.9 KiB
Rust
158 lines
4.9 KiB
Rust
//! Magnetic tape backup
|
|
|
|
use anyhow::{format_err, Error};
|
|
use proxmox_auth_api::types::Userid;
|
|
|
|
use proxmox_sys::fs::{create_path, CreateOptions};
|
|
|
|
use pbs_buildcfg::{PROXMOX_BACKUP_RUN_DIR_M, PROXMOX_BACKUP_STATE_DIR_M};
|
|
|
|
#[cfg(test)]
|
|
mod test;
|
|
|
|
pub mod file_formats;
|
|
|
|
mod media_set;
|
|
pub use media_set::*;
|
|
|
|
mod inventory;
|
|
pub use inventory::*;
|
|
|
|
pub mod changer;
|
|
pub mod drive;
|
|
pub mod encryption_keys;
|
|
|
|
mod media_pool;
|
|
pub use media_pool::*;
|
|
|
|
mod media_catalog;
|
|
pub use media_catalog::*;
|
|
|
|
mod media_catalog_cache;
|
|
pub use media_catalog_cache::*;
|
|
use pbs_api_types::{NotificationMode, TapeBackupJobSetup};
|
|
|
|
mod pool_writer;
|
|
pub use pool_writer::*;
|
|
|
|
/// Directory path where we store all tape status information
|
|
pub const TAPE_STATUS_DIR: &str = concat!(PROXMOX_BACKUP_STATE_DIR_M!(), "/tape");
|
|
|
|
/// Directory path where we store drive lock file
|
|
pub const DRIVE_LOCK_DIR: &str = concat!(PROXMOX_BACKUP_RUN_DIR_M!(), "/drive-lock");
|
|
|
|
/// Directory path where we store temporary drive state
|
|
pub const DRIVE_STATE_DIR: &str = concat!(PROXMOX_BACKUP_RUN_DIR_M!(), "/drive-state");
|
|
|
|
/// Directory path where we store cached changer state
|
|
pub const CHANGER_STATE_DIR: &str = concat!(PROXMOX_BACKUP_RUN_DIR_M!(), "/changer-state");
|
|
|
|
/// We limit chunk archive size, so that we can faster restore a
|
|
/// specific chunk (The catalog only store file numbers, so we
|
|
/// need to read the whole archive to restore a single chunk)
|
|
pub const MAX_CHUNK_ARCHIVE_SIZE: usize = 4 * 1024 * 1024 * 1024; // 4GB for now
|
|
|
|
/// To improve performance, we need to avoid tape drive buffer flush.
|
|
pub const COMMIT_BLOCK_SIZE: usize = 128 * 1024 * 1024 * 1024; // 128 GiB
|
|
|
|
/// Create tape status dir with correct permission
|
|
pub fn create_tape_status_dir() -> Result<(), Error> {
|
|
let backup_user = pbs_config::backup_user()?;
|
|
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0750);
|
|
let options = CreateOptions::new()
|
|
.perm(mode)
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
let parent_opts = CreateOptions::new()
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
create_path(TAPE_STATUS_DIR, Some(parent_opts), Some(options))
|
|
.map_err(|err: Error| format_err!("unable to create tape status dir - {}", err))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Create drive lock dir with correct permission
|
|
pub fn create_drive_lock_dir() -> Result<(), Error> {
|
|
let backup_user = pbs_config::backup_user()?;
|
|
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0750);
|
|
let options = CreateOptions::new()
|
|
.perm(mode)
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
let parent_opts = CreateOptions::new()
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
create_path(DRIVE_LOCK_DIR, Some(parent_opts), Some(options))
|
|
.map_err(|err: Error| format_err!("unable to create drive state dir - {}", err))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Create drive state dir with correct permission
|
|
pub fn create_drive_state_dir() -> Result<(), Error> {
|
|
let backup_user = pbs_config::backup_user()?;
|
|
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0750);
|
|
let options = CreateOptions::new()
|
|
.perm(mode)
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
let parent_opts = CreateOptions::new()
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
create_path(DRIVE_STATE_DIR, Some(parent_opts), Some(options))
|
|
.map_err(|err: Error| format_err!("unable to create drive state dir - {}", err))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Create changer state cache dir with correct permission
|
|
pub fn create_changer_state_dir() -> Result<(), Error> {
|
|
let backup_user = pbs_config::backup_user()?;
|
|
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0750);
|
|
let options = CreateOptions::new()
|
|
.perm(mode)
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
let parent_opts = CreateOptions::new()
|
|
.owner(backup_user.uid)
|
|
.group(backup_user.gid);
|
|
|
|
create_path(CHANGER_STATE_DIR, Some(parent_opts), Some(options))
|
|
.map_err(|err: Error| format_err!("unable to create changer state dir - {}", err))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub enum TapeNotificationMode {
|
|
LegacySendmail { notify_user: Userid },
|
|
NotificationSystem,
|
|
}
|
|
|
|
impl From<&TapeBackupJobSetup> for TapeNotificationMode {
|
|
fn from(value: &TapeBackupJobSetup) -> Self {
|
|
Self::from((value.notify_user.clone(), value.notification_mode.clone()))
|
|
}
|
|
}
|
|
|
|
impl From<(Option<Userid>, Option<NotificationMode>)> for TapeNotificationMode {
|
|
fn from(value: (Option<Userid>, Option<NotificationMode>)) -> Self {
|
|
match value.1.as_ref().unwrap_or(&Default::default()) {
|
|
NotificationMode::LegacySendmail => {
|
|
let notify_user = value.0.as_ref().unwrap_or(Userid::root_userid()).clone();
|
|
|
|
Self::LegacySendmail { notify_user }
|
|
}
|
|
NotificationMode::NotificationSystem => Self::NotificationSystem,
|
|
}
|
|
}
|
|
}
|