mirror of
git://git.proxmox.com/git/proxmox-backup.git
synced 2025-02-04 17:47:19 +03:00
tape: replace '&Path' with 'AsRef<Path>' in function parameters
this way we can omit the pattern ``` let status_path = Path::new(TAPE_STATUS_DIR); some_function(status_path); ``` and give the TAPE_STATUS_DIR directly. In some instances we now have to give TAPE_STATUS_DIR more often, but most often we save a few intermediary Paths. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
de7f180dab
commit
3921deb29a
@ -1,4 +1,3 @@
|
|||||||
use std::path::Path;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
@ -88,7 +87,6 @@ pub fn list_tape_backup_jobs(
|
|||||||
});
|
});
|
||||||
|
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
let current_time = proxmox_time::epoch_i64();
|
let current_time = proxmox_time::epoch_i64();
|
||||||
|
|
||||||
for job in job_list_iter {
|
for job in job_list_iter {
|
||||||
@ -111,7 +109,8 @@ pub fn list_tape_backup_jobs(
|
|||||||
if let Ok(Some((_, name))) = media_changer(&drive_config, &job.setup.drive) {
|
if let Ok(Some((_, name))) = media_changer(&drive_config, &job.setup.drive) {
|
||||||
changer_name = Some(name);
|
changer_name = Some(name);
|
||||||
}
|
}
|
||||||
if let Ok(mut pool) = MediaPool::with_config(status_path, &pool, changer_name, true) {
|
if let Ok(mut pool) = MediaPool::with_config(TAPE_STATUS_DIR, &pool, changer_name, true)
|
||||||
|
{
|
||||||
if pool.start_write_session(next_run, false).is_ok() {
|
if pool.start_write_session(next_run, false).is_ok() {
|
||||||
if let Ok(media_id) = pool.guess_next_writable_media(next_run) {
|
if let Ok(media_id) = pool.guess_next_writable_media(next_run) {
|
||||||
next_media_label = Some(media_id.label.label_text);
|
next_media_label = Some(media_id.label.label_text);
|
||||||
@ -391,7 +390,6 @@ fn backup_worker(
|
|||||||
summary: &mut TapeBackupJobSummary,
|
summary: &mut TapeBackupJobSummary,
|
||||||
force_media_set: bool,
|
force_media_set: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
task_log!(worker, "update media online status");
|
task_log!(worker, "update media online status");
|
||||||
@ -400,7 +398,7 @@ fn backup_worker(
|
|||||||
let root_namespace = setup.ns.clone().unwrap_or_default();
|
let root_namespace = setup.ns.clone().unwrap_or_default();
|
||||||
let ns_magic = !root_namespace.is_root() || setup.max_depth != Some(0);
|
let ns_magic = !root_namespace.is_root() || setup.max_depth != Some(0);
|
||||||
|
|
||||||
let pool = MediaPool::with_config(status_path, pool_config, changer_name, false)?;
|
let pool = MediaPool::with_config(TAPE_STATUS_DIR, pool_config, changer_name, false)?;
|
||||||
|
|
||||||
let mut pool_writer =
|
let mut pool_writer =
|
||||||
PoolWriter::new(pool, &setup.drive, worker, email, force_media_set, ns_magic)?;
|
PoolWriter::new(pool, &setup.drive, worker, email, force_media_set, ns_magic)?;
|
||||||
@ -584,8 +582,7 @@ fn update_media_online_status(drive: &str) -> Result<Option<String>, Error> {
|
|||||||
if let Ok(Some((mut changer, changer_name))) = media_changer(&config, drive) {
|
if let Ok(Some((mut changer, changer_name))) = media_changer(&config, drive) {
|
||||||
let label_text_list = changer.online_media_label_texts()?;
|
let label_text_list = changer.online_media_label_texts()?;
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let mut inventory = Inventory::load(status_path)?;
|
|
||||||
|
|
||||||
update_changer_online_status(&config, &mut inventory, &changer_name, &label_text_list)?;
|
update_changer_online_status(&config, &mut inventory, &changer_name, &label_text_list)?;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@ -55,8 +54,7 @@ pub async fn get_status(name: String, cache: bool) -> Result<Vec<MtxStatusEntry>
|
|||||||
|
|
||||||
let status = tokio::task::spawn_blocking(move || changer_config.status(cache)).await??;
|
let status = tokio::task::spawn_blocking(move || changer_config.status(cache)).await??;
|
||||||
|
|
||||||
let state_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let mut inventory = Inventory::load(state_path)?;
|
|
||||||
|
|
||||||
let mut map = OnlineStatusMap::new(&config)?;
|
let mut map = OnlineStatusMap::new(&config)?;
|
||||||
let online_set = mtx_status_to_online_set(&status, &inventory);
|
let online_set = mtx_status_to_online_set(&status, &inventory);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::panic::UnwindSafe;
|
use std::panic::UnwindSafe;
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
@ -345,20 +344,19 @@ pub fn format_media(
|
|||||||
media_id.label.uuid,
|
media_id.label.uuid,
|
||||||
);
|
);
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::new(TAPE_STATUS_DIR);
|
||||||
let mut inventory = Inventory::new(status_path);
|
|
||||||
|
|
||||||
if let Some(MediaSetLabel {
|
if let Some(MediaSetLabel {
|
||||||
ref pool, ref uuid, ..
|
ref pool, ref uuid, ..
|
||||||
}) = media_id.media_set_label
|
}) = media_id.media_set_label
|
||||||
{
|
{
|
||||||
let _pool_lock = lock_media_pool(status_path, pool)?;
|
let _pool_lock = lock_media_pool(TAPE_STATUS_DIR, pool)?;
|
||||||
let _media_set_lock = lock_media_set(status_path, uuid, None)?;
|
let _media_set_lock = lock_media_set(TAPE_STATUS_DIR, uuid, None)?;
|
||||||
MediaCatalog::destroy(status_path, &media_id.label.uuid)?;
|
MediaCatalog::destroy(TAPE_STATUS_DIR, &media_id.label.uuid)?;
|
||||||
inventory.remove_media(&media_id.label.uuid)?;
|
inventory.remove_media(&media_id.label.uuid)?;
|
||||||
} else {
|
} else {
|
||||||
let _lock = lock_unassigned_media_pool(status_path)?;
|
let _lock = lock_unassigned_media_pool(TAPE_STATUS_DIR)?;
|
||||||
MediaCatalog::destroy(status_path, &media_id.label.uuid)?;
|
MediaCatalog::destroy(TAPE_STATUS_DIR, &media_id.label.uuid)?;
|
||||||
inventory.remove_media(&media_id.label.uuid)?;
|
inventory.remove_media(&media_id.label.uuid)?;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -522,9 +520,6 @@ fn write_media_label(
|
|||||||
pool: Option<String>,
|
pool: Option<String>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
drive.label_tape(&label)?;
|
drive.label_tape(&label)?;
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let media_id = if let Some(ref pool) = pool {
|
let media_id = if let Some(ref pool) = pool {
|
||||||
// assign media to pool by writing special media set label
|
// assign media to pool by writing special media set label
|
||||||
task_log!(
|
task_log!(
|
||||||
@ -543,9 +538,9 @@ fn write_media_label(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create the media catalog
|
// Create the media catalog
|
||||||
MediaCatalog::overwrite(status_path, &media_id, false)?;
|
MediaCatalog::overwrite(TAPE_STATUS_DIR, &media_id, false)?;
|
||||||
|
|
||||||
let mut inventory = Inventory::new(status_path);
|
let mut inventory = Inventory::new(TAPE_STATUS_DIR);
|
||||||
inventory.store(media_id.clone(), false)?;
|
inventory.store(media_id.clone(), false)?;
|
||||||
|
|
||||||
media_id
|
media_id
|
||||||
@ -562,9 +557,9 @@ fn write_media_label(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create the media catalog
|
// Create the media catalog
|
||||||
MediaCatalog::overwrite(status_path, &media_id, false)?;
|
MediaCatalog::overwrite(TAPE_STATUS_DIR, &media_id, false)?;
|
||||||
|
|
||||||
let mut inventory = Inventory::new(status_path);
|
let mut inventory = Inventory::new(TAPE_STATUS_DIR);
|
||||||
inventory.store(media_id.clone(), false)?;
|
inventory.store(media_id.clone(), false)?;
|
||||||
|
|
||||||
media_id
|
media_id
|
||||||
@ -698,20 +693,19 @@ pub async fn read_label(drive: String, inventorize: Option<bool>) -> Result<Medi
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(true) = inventorize {
|
if let Some(true) = inventorize {
|
||||||
let state_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::new(TAPE_STATUS_DIR);
|
||||||
let mut inventory = Inventory::new(state_path);
|
|
||||||
|
|
||||||
if let Some(MediaSetLabel {
|
if let Some(MediaSetLabel {
|
||||||
ref pool, ref uuid, ..
|
ref pool, ref uuid, ..
|
||||||
}) = media_id.media_set_label
|
}) = media_id.media_set_label
|
||||||
{
|
{
|
||||||
let _pool_lock = lock_media_pool(state_path, pool)?;
|
let _pool_lock = lock_media_pool(TAPE_STATUS_DIR, pool)?;
|
||||||
let _lock = lock_media_set(state_path, uuid, None)?;
|
let _lock = lock_media_set(TAPE_STATUS_DIR, uuid, None)?;
|
||||||
MediaCatalog::destroy_unrelated_catalog(state_path, &media_id)?;
|
MediaCatalog::destroy_unrelated_catalog(TAPE_STATUS_DIR, &media_id)?;
|
||||||
inventory.store(media_id, false)?;
|
inventory.store(media_id, false)?;
|
||||||
} else {
|
} else {
|
||||||
let _lock = lock_unassigned_media_pool(state_path)?;
|
let _lock = lock_unassigned_media_pool(TAPE_STATUS_DIR)?;
|
||||||
MediaCatalog::destroy(state_path, &media_id.label.uuid)?;
|
MediaCatalog::destroy(TAPE_STATUS_DIR, &media_id.label.uuid)?;
|
||||||
inventory.store(media_id, false)?;
|
inventory.store(media_id, false)?;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -813,9 +807,7 @@ pub async fn inventory(drive: String) -> Result<Vec<LabelUuidMap>, Error> {
|
|||||||
|
|
||||||
let label_text_list = changer.online_media_label_texts()?;
|
let label_text_list = changer.online_media_label_texts()?;
|
||||||
|
|
||||||
let state_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
|
|
||||||
let mut inventory = Inventory::load(state_path)?;
|
|
||||||
|
|
||||||
update_changer_online_status(&config, &mut inventory, &changer_name, &label_text_list)?;
|
update_changer_online_status(&config, &mut inventory, &changer_name, &label_text_list)?;
|
||||||
|
|
||||||
@ -894,9 +886,7 @@ pub fn update_inventory(
|
|||||||
task_log!(worker, "changer device does not list any media labels");
|
task_log!(worker, "changer device does not list any media labels");
|
||||||
}
|
}
|
||||||
|
|
||||||
let state_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
|
|
||||||
let mut inventory = Inventory::load(state_path)?;
|
|
||||||
|
|
||||||
update_changer_online_status(&config, &mut inventory, &changer_name, &label_text_list)?;
|
update_changer_online_status(&config, &mut inventory, &changer_name, &label_text_list)?;
|
||||||
|
|
||||||
@ -954,13 +944,13 @@ pub fn update_inventory(
|
|||||||
ref pool, ref uuid, ..
|
ref pool, ref uuid, ..
|
||||||
}) = media_id.media_set_label
|
}) = media_id.media_set_label
|
||||||
{
|
{
|
||||||
let _pool_lock = lock_media_pool(state_path, pool)?;
|
let _pool_lock = lock_media_pool(TAPE_STATUS_DIR, pool)?;
|
||||||
let _lock = lock_media_set(state_path, uuid, None)?;
|
let _lock = lock_media_set(TAPE_STATUS_DIR, uuid, None)?;
|
||||||
MediaCatalog::destroy_unrelated_catalog(state_path, &media_id)?;
|
MediaCatalog::destroy_unrelated_catalog(TAPE_STATUS_DIR, &media_id)?;
|
||||||
inventory.store(media_id, false)?;
|
inventory.store(media_id, false)?;
|
||||||
} else {
|
} else {
|
||||||
let _lock = lock_unassigned_media_pool(state_path)?;
|
let _lock = lock_unassigned_media_pool(TAPE_STATUS_DIR)?;
|
||||||
MediaCatalog::destroy(state_path, &media_id.label.uuid)?;
|
MediaCatalog::destroy(TAPE_STATUS_DIR, &media_id.label.uuid)?;
|
||||||
inventory.store(media_id, false)?;
|
inventory.store(media_id, false)?;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1031,9 +1021,7 @@ fn barcode_label_media_worker(
|
|||||||
// make sure we label them in the right order
|
// make sure we label them in the right order
|
||||||
label_text_list.sort();
|
label_text_list.sort();
|
||||||
|
|
||||||
let state_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
|
|
||||||
let mut inventory = Inventory::load(state_path)?;
|
|
||||||
|
|
||||||
update_changer_online_status(
|
update_changer_online_status(
|
||||||
drive_config,
|
drive_config,
|
||||||
@ -1275,15 +1263,13 @@ pub fn catalog_media(
|
|||||||
(None, _) => bail!("media is empty (no media label found)"),
|
(None, _) => bail!("media is empty (no media label found)"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::new(TAPE_STATUS_DIR);
|
||||||
|
|
||||||
let mut inventory = Inventory::new(status_path);
|
|
||||||
|
|
||||||
let (_media_set_lock, media_set_uuid) = match media_id.media_set_label {
|
let (_media_set_lock, media_set_uuid) = match media_id.media_set_label {
|
||||||
None => {
|
None => {
|
||||||
task_log!(worker, "media is empty");
|
task_log!(worker, "media is empty");
|
||||||
let _lock = lock_unassigned_media_pool(status_path)?;
|
let _lock = lock_unassigned_media_pool(TAPE_STATUS_DIR)?;
|
||||||
MediaCatalog::destroy(status_path, &media_id.label.uuid)?;
|
MediaCatalog::destroy(TAPE_STATUS_DIR, &media_id.label.uuid)?;
|
||||||
inventory.store(media_id.clone(), false)?;
|
inventory.store(media_id.clone(), false)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -1291,8 +1277,8 @@ pub fn catalog_media(
|
|||||||
if set.uuid.as_ref() == [0u8; 16] {
|
if set.uuid.as_ref() == [0u8; 16] {
|
||||||
// media is empty
|
// media is empty
|
||||||
task_log!(worker, "media is empty");
|
task_log!(worker, "media is empty");
|
||||||
let _lock = lock_unassigned_media_pool(status_path)?;
|
let _lock = lock_unassigned_media_pool(TAPE_STATUS_DIR)?;
|
||||||
MediaCatalog::destroy(status_path, &media_id.label.uuid)?;
|
MediaCatalog::destroy(TAPE_STATUS_DIR, &media_id.label.uuid)?;
|
||||||
inventory.store(media_id.clone(), false)?;
|
inventory.store(media_id.clone(), false)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -1303,10 +1289,10 @@ pub fn catalog_media(
|
|||||||
|
|
||||||
drive.set_encryption(encrypt_fingerprint)?;
|
drive.set_encryption(encrypt_fingerprint)?;
|
||||||
|
|
||||||
let _pool_lock = lock_media_pool(status_path, &set.pool)?;
|
let _pool_lock = lock_media_pool(TAPE_STATUS_DIR, &set.pool)?;
|
||||||
let media_set_lock = lock_media_set(status_path, &set.uuid, None)?;
|
let media_set_lock = lock_media_set(TAPE_STATUS_DIR, &set.uuid, None)?;
|
||||||
|
|
||||||
MediaCatalog::destroy_unrelated_catalog(status_path, &media_id)?;
|
MediaCatalog::destroy_unrelated_catalog(TAPE_STATUS_DIR, &media_id)?;
|
||||||
|
|
||||||
inventory.store(media_id.clone(), false)?;
|
inventory.store(media_id.clone(), false)?;
|
||||||
|
|
||||||
@ -1314,7 +1300,7 @@ pub fn catalog_media(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if MediaCatalog::exists(status_path, &media_id.label.uuid) && !force {
|
if MediaCatalog::exists(TAPE_STATUS_DIR, &media_id.label.uuid) && !force {
|
||||||
bail!("media catalog exists (please use --force to overwrite)");
|
bail!("media catalog exists (please use --force to overwrite)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
|
||||||
@ -41,8 +40,6 @@ pub async fn list_media_sets(
|
|||||||
|
|
||||||
let (config, _digest) = pbs_config::media_pool::config()?;
|
let (config, _digest) = pbs_config::media_pool::config()?;
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let mut media_sets: HashSet<Uuid> = HashSet::new();
|
let mut media_sets: HashSet<Uuid> = HashSet::new();
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
@ -60,7 +57,7 @@ pub async fn list_media_sets(
|
|||||||
let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
|
let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
|
||||||
|
|
||||||
let changer_name = None; // assume standalone drive
|
let changer_name = None; // assume standalone drive
|
||||||
let pool = MediaPool::with_config(status_path, &config, changer_name, true)?;
|
let pool = MediaPool::with_config(TAPE_STATUS_DIR, &config, changer_name, true)?;
|
||||||
|
|
||||||
for media in pool.list_media() {
|
for media in pool.list_media() {
|
||||||
if let Some(label) = media.media_set_label() {
|
if let Some(label) = media.media_set_label() {
|
||||||
@ -130,18 +127,18 @@ pub async fn list_media(
|
|||||||
|
|
||||||
let (config, _digest) = pbs_config::media_pool::config()?;
|
let (config, _digest) = pbs_config::media_pool::config()?;
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let catalogs = tokio::task::spawn_blocking(move || {
|
let catalogs = tokio::task::spawn_blocking(move || {
|
||||||
if update_status {
|
if update_status {
|
||||||
// update online media status
|
// update online media status
|
||||||
if let Err(err) = update_online_status(status_path, update_status_changer.as_deref()) {
|
if let Err(err) =
|
||||||
|
update_online_status(TAPE_STATUS_DIR, update_status_changer.as_deref())
|
||||||
|
{
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
eprintln!("update online media status failed - using old state");
|
eprintln!("update online media status failed - using old state");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// test what catalog files we have
|
// test what catalog files we have
|
||||||
MediaCatalog::media_with_catalogs(status_path)
|
MediaCatalog::media_with_catalogs(TAPE_STATUS_DIR)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
@ -166,7 +163,7 @@ pub async fn list_media(
|
|||||||
let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
|
let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
|
||||||
|
|
||||||
let changer_name = None; // assume standalone drive
|
let changer_name = None; // assume standalone drive
|
||||||
let mut pool = MediaPool::with_config(status_path, &config, changer_name, true)?;
|
let mut pool = MediaPool::with_config(TAPE_STATUS_DIR, &config, changer_name, true)?;
|
||||||
|
|
||||||
let current_time = proxmox_time::epoch_i64();
|
let current_time = proxmox_time::epoch_i64();
|
||||||
|
|
||||||
@ -211,7 +208,7 @@ pub async fn list_media(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inventory = Inventory::load(status_path)?;
|
let inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
|
|
||||||
let privs = user_info.lookup_privs(&auth_id, &["tape", "pool"]);
|
let privs = user_info.lookup_privs(&auth_id, &["tape", "pool"]);
|
||||||
if (privs & PRIV_TAPE_AUDIT) != 0 && pool.is_none() {
|
if (privs & PRIV_TAPE_AUDIT) != 0 && pool.is_none() {
|
||||||
@ -295,8 +292,7 @@ pub async fn list_media(
|
|||||||
)]
|
)]
|
||||||
/// Change Tape location to vault (if given), or offline.
|
/// Change Tape location to vault (if given), or offline.
|
||||||
pub fn move_tape(label_text: String, vault_name: Option<String>) -> Result<(), Error> {
|
pub fn move_tape(label_text: String, vault_name: Option<String>) -> Result<(), Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let mut inventory = Inventory::load(status_path)?;
|
|
||||||
|
|
||||||
let uuid = inventory
|
let uuid = inventory
|
||||||
.find_media_by_label_text(&label_text)
|
.find_media_by_label_text(&label_text)
|
||||||
@ -332,8 +328,7 @@ pub fn move_tape(label_text: String, vault_name: Option<String>) -> Result<(), E
|
|||||||
pub fn destroy_media(label_text: String, force: Option<bool>) -> Result<(), Error> {
|
pub fn destroy_media(label_text: String, force: Option<bool>) -> Result<(), Error> {
|
||||||
let force = force.unwrap_or(false);
|
let force = force.unwrap_or(false);
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let mut inventory = Inventory::load(status_path)?;
|
|
||||||
|
|
||||||
let media_id = inventory
|
let media_id = inventory
|
||||||
.find_media_by_label_text(&label_text)
|
.find_media_by_label_text(&label_text)
|
||||||
@ -389,8 +384,7 @@ pub fn list_content(
|
|||||||
|
|
||||||
let (config, _digest) = pbs_config::media_pool::config()?;
|
let (config, _digest) = pbs_config::media_pool::config()?;
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let inventory = Inventory::load(status_path)?;
|
|
||||||
|
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
@ -435,7 +429,7 @@ pub fn list_content(
|
|||||||
.generate_media_set_name(&set.uuid, template)
|
.generate_media_set_name(&set.uuid, template)
|
||||||
.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(TAPE_STATUS_DIR, &media_id)? {
|
||||||
let (_, backup_dir) = pbs_api_types::parse_ns_and_snapshot(&snapshot)?;
|
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 {
|
||||||
@ -478,8 +472,7 @@ pub fn list_content(
|
|||||||
)]
|
)]
|
||||||
/// Get current media status
|
/// Get current media status
|
||||||
pub fn get_media_status(uuid: Uuid) -> Result<MediaStatus, Error> {
|
pub fn get_media_status(uuid: Uuid) -> Result<MediaStatus, Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let inventory = Inventory::load(status_path)?;
|
|
||||||
|
|
||||||
let (status, _location) = inventory.status_and_location(&uuid);
|
let (status, _location) = inventory.status_and_location(&uuid);
|
||||||
|
|
||||||
@ -504,8 +497,7 @@ pub fn get_media_status(uuid: Uuid) -> Result<MediaStatus, Error> {
|
|||||||
/// It is not allowed to set status to 'writable' or 'unknown' (those
|
/// It is not allowed to set status to 'writable' or 'unknown' (those
|
||||||
/// are internally managed states).
|
/// are internally managed states).
|
||||||
pub fn update_media_status(uuid: Uuid, status: Option<MediaStatus>) -> Result<(), Error> {
|
pub fn update_media_status(uuid: Uuid, status: Option<MediaStatus>) -> Result<(), Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
let mut inventory = Inventory::load(status_path)?;
|
|
||||||
|
|
||||||
match status {
|
match status {
|
||||||
None => inventory.clear_media_status(&uuid)?,
|
None => inventory.clear_media_status(&uuid)?,
|
||||||
|
@ -362,11 +362,10 @@ pub fn restore(
|
|||||||
user_info.check_privs(&auth_id, &["tape", "drive", &drive], PRIV_TAPE_READ, false)?;
|
user_info.check_privs(&auth_id, &["tape", "drive", &drive], PRIV_TAPE_READ, false)?;
|
||||||
|
|
||||||
let media_set_uuid = media_set.parse()?;
|
let media_set_uuid = media_set.parse()?;
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let _lock = lock_media_set(status_path, &media_set_uuid, None)?;
|
let _lock = lock_media_set(TAPE_STATUS_DIR, &media_set_uuid, None)?;
|
||||||
|
|
||||||
let inventory = Inventory::load(status_path)?;
|
let inventory = Inventory::load(TAPE_STATUS_DIR)?;
|
||||||
|
|
||||||
let pool = inventory.lookup_media_set_pool(&media_set_uuid)?;
|
let pool = inventory.lookup_media_set_pool(&media_set_uuid)?;
|
||||||
user_info.check_privs(&auth_id, &["tape", "pool", &pool], PRIV_TAPE_READ, false)?;
|
user_info.check_privs(&auth_id, &["tape", "pool", &pool], PRIV_TAPE_READ, false)?;
|
||||||
@ -945,8 +944,6 @@ fn get_media_set_catalog(
|
|||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
media_set_uuid: &Uuid,
|
media_set_uuid: &Uuid,
|
||||||
) -> Result<MediaSetCatalog, Error> {
|
) -> Result<MediaSetCatalog, Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let members = inventory.compute_media_set_members(media_set_uuid)?;
|
let members = inventory.compute_media_set_members(media_set_uuid)?;
|
||||||
let media_list = members.media_list();
|
let media_list = members.media_list();
|
||||||
let mut catalog = MediaSetCatalog::new();
|
let mut catalog = MediaSetCatalog::new();
|
||||||
@ -958,7 +955,7 @@ fn get_media_set_catalog(
|
|||||||
}
|
}
|
||||||
Some(media_uuid) => {
|
Some(media_uuid) => {
|
||||||
let media_id = inventory.lookup_media(media_uuid).unwrap();
|
let media_id = inventory.lookup_media(media_uuid).unwrap();
|
||||||
let media_catalog = MediaCatalog::open(status_path, media_id, false, false)?;
|
let media_catalog = MediaCatalog::open(TAPE_STATUS_DIR, media_id, false, false)?;
|
||||||
catalog.append_catalog(media_catalog)?;
|
catalog.append_catalog(media_catalog)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1295,8 +1292,7 @@ pub fn restore_media(
|
|||||||
verbose: bool,
|
verbose: bool,
|
||||||
auth_id: &Authid,
|
auth_id: &Authid,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut catalog = MediaCatalog::create_temporary_database(TAPE_STATUS_DIR, media_id, false)?;
|
||||||
let mut catalog = MediaCatalog::create_temporary_database(status_path, media_id, false)?;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let current_file_number = drive.current_file_number()?;
|
let current_file_number = drive.current_file_number()?;
|
||||||
@ -1333,7 +1329,7 @@ pub fn restore_media(
|
|||||||
|
|
||||||
catalog.commit()?;
|
catalog.commit()?;
|
||||||
|
|
||||||
MediaCatalog::finish_temporary_database(status_path, &media_id.label.uuid, true)?;
|
MediaCatalog::finish_temporary_database(TAPE_STATUS_DIR, &media_id.label.uuid, true)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1820,8 +1816,6 @@ pub fn fast_catalog_restore(
|
|||||||
media_set: &MediaSet,
|
media_set: &MediaSet,
|
||||||
uuid: &Uuid, // current media Uuid
|
uuid: &Uuid, // current media Uuid
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let current_file_number = drive.current_file_number()?;
|
let current_file_number = drive.current_file_number()?;
|
||||||
if current_file_number != 2 {
|
if current_file_number != 2 {
|
||||||
bail!("fast_catalog_restore: wrong media position - internal error");
|
bail!("fast_catalog_restore: wrong media position - internal error");
|
||||||
@ -1902,7 +1896,7 @@ pub fn fast_catalog_restore(
|
|||||||
// always restore and overwrite catalog
|
// always restore and overwrite catalog
|
||||||
} else {
|
} else {
|
||||||
// only restore if catalog does not exist
|
// only restore if catalog does not exist
|
||||||
if MediaCatalog::exists(status_path, catalog_uuid) {
|
if MediaCatalog::exists(TAPE_STATUS_DIR, catalog_uuid) {
|
||||||
task_log!(
|
task_log!(
|
||||||
worker,
|
worker,
|
||||||
"catalog for media '{}' already exists",
|
"catalog for media '{}' already exists",
|
||||||
@ -1914,7 +1908,7 @@ pub fn fast_catalog_restore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut file =
|
let mut file =
|
||||||
MediaCatalog::create_temporary_database_file(status_path, catalog_uuid)?;
|
MediaCatalog::create_temporary_database_file(TAPE_STATUS_DIR, catalog_uuid)?;
|
||||||
|
|
||||||
std::io::copy(&mut reader, &mut file)?;
|
std::io::copy(&mut reader, &mut file)?;
|
||||||
|
|
||||||
@ -1939,7 +1933,11 @@ pub fn fast_catalog_restore(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaCatalog::finish_temporary_database(status_path, &media_uuid, true)?;
|
MediaCatalog::finish_temporary_database(
|
||||||
|
TAPE_STATUS_DIR,
|
||||||
|
&media_uuid,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
|
||||||
if catalog_uuid == uuid {
|
if catalog_uuid == uuid {
|
||||||
task_log!(worker, "successfully restored catalog");
|
task_log!(worker, "successfully restored catalog");
|
||||||
|
@ -119,8 +119,8 @@ pub fn mtx_status_to_online_set(status: &MtxStatus, inventory: &Inventory) -> Ha
|
|||||||
/// Update online media status
|
/// Update online media status
|
||||||
///
|
///
|
||||||
/// For a single 'changer', or else simply ask all changer devices.
|
/// For a single 'changer', or else simply ask all changer devices.
|
||||||
pub fn update_online_status(
|
pub fn update_online_status<P: AsRef<Path>>(
|
||||||
state_path: &Path,
|
state_path: P,
|
||||||
changer: Option<&str>,
|
changer: Option<&str>,
|
||||||
) -> Result<OnlineStatusMap, Error> {
|
) -> Result<OnlineStatusMap, Error> {
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -89,11 +89,11 @@ impl Inventory {
|
|||||||
pub const MEDIA_INVENTORY_LOCKFILE: &'static str = ".inventory.lck";
|
pub const MEDIA_INVENTORY_LOCKFILE: &'static str = ".inventory.lck";
|
||||||
|
|
||||||
/// Create empty instance, no data loaded
|
/// Create empty instance, no data loaded
|
||||||
pub fn new(base_path: &Path) -> Self {
|
pub fn new<P: AsRef<Path>>(base_path: P) -> Self {
|
||||||
let mut inventory_path = base_path.to_owned();
|
let mut inventory_path = base_path.as_ref().to_owned();
|
||||||
inventory_path.push(Self::MEDIA_INVENTORY_FILENAME);
|
inventory_path.push(Self::MEDIA_INVENTORY_FILENAME);
|
||||||
|
|
||||||
let mut lockfile_path = base_path.to_owned();
|
let mut lockfile_path = base_path.as_ref().to_owned();
|
||||||
lockfile_path.push(Self::MEDIA_INVENTORY_LOCKFILE);
|
lockfile_path.push(Self::MEDIA_INVENTORY_LOCKFILE);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -104,7 +104,7 @@ impl Inventory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(base_path: &Path) -> Result<Self, Error> {
|
pub fn load<P: AsRef<Path>>(base_path: P) -> Result<Self, Error> {
|
||||||
let mut me = Self::new(base_path);
|
let mut me = Self::new(base_path);
|
||||||
me.reload()?;
|
me.reload()?;
|
||||||
Ok(me)
|
Ok(me)
|
||||||
@ -751,8 +751,8 @@ impl Inventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Lock a media pool
|
/// Lock a media pool
|
||||||
pub fn lock_media_pool(base_path: &Path, name: &str) -> Result<BackupLockGuard, Error> {
|
pub fn lock_media_pool<P: AsRef<Path>>(base_path: P, name: &str) -> Result<BackupLockGuard, Error> {
|
||||||
let mut path = base_path.to_owned();
|
let mut path = base_path.as_ref().to_owned();
|
||||||
path.push(format!(".pool-{}", name));
|
path.push(format!(".pool-{}", name));
|
||||||
path.set_extension("lck");
|
path.set_extension("lck");
|
||||||
|
|
||||||
@ -760,7 +760,7 @@ pub fn lock_media_pool(base_path: &Path, name: &str) -> Result<BackupLockGuard,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Lock for media not assigned to any pool
|
/// Lock for media not assigned to any pool
|
||||||
pub fn lock_unassigned_media_pool(base_path: &Path) -> Result<BackupLockGuard, Error> {
|
pub fn lock_unassigned_media_pool<P: AsRef<Path>>(base_path: P) -> Result<BackupLockGuard, Error> {
|
||||||
// lock artificial "__UNASSIGNED__" pool to avoid races
|
// lock artificial "__UNASSIGNED__" pool to avoid races
|
||||||
lock_media_pool(base_path, "__UNASSIGNED__")
|
lock_media_pool(base_path, "__UNASSIGNED__")
|
||||||
}
|
}
|
||||||
@ -768,12 +768,12 @@ pub fn lock_unassigned_media_pool(base_path: &Path) -> Result<BackupLockGuard, E
|
|||||||
/// Lock a media set
|
/// Lock a media set
|
||||||
///
|
///
|
||||||
/// Timeout is 10 seconds by default
|
/// Timeout is 10 seconds by default
|
||||||
pub fn lock_media_set(
|
pub fn lock_media_set<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
media_set_uuid: &Uuid,
|
media_set_uuid: &Uuid,
|
||||||
timeout: Option<Duration>,
|
timeout: Option<Duration>,
|
||||||
) -> Result<BackupLockGuard, Error> {
|
) -> Result<BackupLockGuard, Error> {
|
||||||
let mut path = base_path.to_owned();
|
let mut path = base_path.as_ref().to_owned();
|
||||||
path.push(format!(".media-set-{}", media_set_uuid));
|
path.push(format!(".media-set-{}", media_set_uuid));
|
||||||
path.set_extension("lck");
|
path.set_extension("lck");
|
||||||
|
|
||||||
@ -784,7 +784,7 @@ pub fn lock_media_set(
|
|||||||
|
|
||||||
/// List of known media uuids
|
/// List of known media uuids
|
||||||
pub fn complete_media_uuid(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
pub fn complete_media_uuid(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
||||||
let inventory = match Inventory::load(Path::new(TAPE_STATUS_DIR)) {
|
let inventory = match Inventory::load(TAPE_STATUS_DIR) {
|
||||||
Ok(inventory) => inventory,
|
Ok(inventory) => inventory,
|
||||||
Err(_) => return Vec::new(),
|
Err(_) => return Vec::new(),
|
||||||
};
|
};
|
||||||
@ -794,7 +794,7 @@ pub fn complete_media_uuid(_arg: &str, _param: &HashMap<String, String>) -> Vec<
|
|||||||
|
|
||||||
/// List of known media sets
|
/// List of known media sets
|
||||||
pub fn complete_media_set_uuid(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
pub fn complete_media_set_uuid(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
||||||
let inventory = match Inventory::load(Path::new(TAPE_STATUS_DIR)) {
|
let inventory = match Inventory::load(TAPE_STATUS_DIR) {
|
||||||
Ok(inventory) => inventory,
|
Ok(inventory) => inventory,
|
||||||
Err(_) => return Vec::new(),
|
Err(_) => return Vec::new(),
|
||||||
};
|
};
|
||||||
@ -809,7 +809,7 @@ pub fn complete_media_set_uuid(_arg: &str, _param: &HashMap<String, String>) ->
|
|||||||
|
|
||||||
/// List of known media labels (barcodes)
|
/// List of known media labels (barcodes)
|
||||||
pub fn complete_media_label_text(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
pub fn complete_media_label_text(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
||||||
let inventory = match Inventory::load(Path::new(TAPE_STATUS_DIR)) {
|
let inventory = match Inventory::load(TAPE_STATUS_DIR) {
|
||||||
Ok(inventory) => inventory,
|
Ok(inventory) => inventory,
|
||||||
Err(_) => return Vec::new(),
|
Err(_) => return Vec::new(),
|
||||||
};
|
};
|
||||||
@ -826,8 +826,7 @@ pub fn complete_media_set_snapshots(_arg: &str, param: &HashMap<String, String>)
|
|||||||
Some(uuid) => uuid,
|
Some(uuid) => uuid,
|
||||||
None => return Vec::new(),
|
None => return Vec::new(),
|
||||||
};
|
};
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let inventory = match Inventory::load(TAPE_STATUS_DIR) {
|
||||||
let inventory = match Inventory::load(status_path) {
|
|
||||||
Ok(inventory) => inventory,
|
Ok(inventory) => inventory,
|
||||||
Err(_) => return Vec::new(),
|
Err(_) => return Vec::new(),
|
||||||
};
|
};
|
||||||
@ -843,7 +842,7 @@ pub fn complete_media_set_snapshots(_arg: &str, param: &HashMap<String, String>)
|
|||||||
});
|
});
|
||||||
|
|
||||||
for media_id in media_ids {
|
for media_id in media_ids {
|
||||||
let catalog = match MediaCatalog::open(status_path, &media_id, false, false) {
|
let catalog = match MediaCatalog::open(TAPE_STATUS_DIR, &media_id, false, false) {
|
||||||
Ok(catalog) => catalog,
|
Ok(catalog) => catalog,
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
};
|
};
|
||||||
|
@ -66,10 +66,10 @@ impl MediaCatalog {
|
|||||||
[76, 142, 232, 193, 32, 168, 137, 113];
|
[76, 142, 232, 193, 32, 168, 137, 113];
|
||||||
|
|
||||||
/// List media with catalogs
|
/// List media with catalogs
|
||||||
pub fn media_with_catalogs(base_path: &Path) -> Result<HashSet<Uuid>, Error> {
|
pub fn media_with_catalogs<P: AsRef<Path>>(base_path: P) -> Result<HashSet<Uuid>, Error> {
|
||||||
let mut catalogs = HashSet::new();
|
let mut catalogs = HashSet::new();
|
||||||
|
|
||||||
for entry in read_subdir(libc::AT_FDCWD, base_path)? {
|
for entry in read_subdir(libc::AT_FDCWD, base_path.as_ref())? {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
let name = unsafe { entry.file_name_utf8_unchecked() };
|
let name = unsafe { entry.file_name_utf8_unchecked() };
|
||||||
if !name.ends_with(".log") {
|
if !name.ends_with(".log") {
|
||||||
@ -83,27 +83,27 @@ impl MediaCatalog {
|
|||||||
Ok(catalogs)
|
Ok(catalogs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn catalog_path(base_path: &Path, uuid: &Uuid) -> PathBuf {
|
fn catalog_path<P: AsRef<Path>>(base_path: P, uuid: &Uuid) -> PathBuf {
|
||||||
let mut path = base_path.to_owned();
|
let mut path = base_path.as_ref().to_owned();
|
||||||
path.push(uuid.to_string());
|
path.push(uuid.to_string());
|
||||||
path.set_extension("log");
|
path.set_extension("log");
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tmp_catalog_path(base_path: &Path, uuid: &Uuid) -> PathBuf {
|
fn tmp_catalog_path<P: AsRef<Path>>(base_path: P, uuid: &Uuid) -> PathBuf {
|
||||||
let mut path = base_path.to_owned();
|
let mut path = base_path.as_ref().to_owned();
|
||||||
path.push(uuid.to_string());
|
path.push(uuid.to_string());
|
||||||
path.set_extension("tmp");
|
path.set_extension("tmp");
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test if a catalog exists
|
/// Test if a catalog exists
|
||||||
pub fn exists(base_path: &Path, uuid: &Uuid) -> bool {
|
pub fn exists<P: AsRef<Path>>(base_path: P, uuid: &Uuid) -> bool {
|
||||||
Self::catalog_path(base_path, uuid).exists()
|
Self::catalog_path(base_path, uuid).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy the media catalog (remove all files)
|
/// Destroy the media catalog (remove all files)
|
||||||
pub fn destroy(base_path: &Path, uuid: &Uuid) -> Result<(), Error> {
|
pub fn destroy<P: AsRef<Path>>(base_path: P, uuid: &Uuid) -> Result<(), Error> {
|
||||||
let path = Self::catalog_path(base_path, uuid);
|
let path = Self::catalog_path(base_path, uuid);
|
||||||
|
|
||||||
match std::fs::remove_file(path) {
|
match std::fs::remove_file(path) {
|
||||||
@ -114,7 +114,10 @@ impl MediaCatalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy the media catalog if media_set uuid does not match
|
/// Destroy the media catalog if media_set uuid does not match
|
||||||
pub fn destroy_unrelated_catalog(base_path: &Path, media_id: &MediaId) -> Result<(), Error> {
|
pub fn destroy_unrelated_catalog<P: AsRef<Path>>(
|
||||||
|
base_path: P,
|
||||||
|
media_id: &MediaId,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let uuid = &media_id.label.uuid;
|
let uuid = &media_id.label.uuid;
|
||||||
|
|
||||||
let path = Self::catalog_path(base_path, uuid);
|
let path = Self::catalog_path(base_path, uuid);
|
||||||
@ -165,7 +168,7 @@ impl MediaCatalog {
|
|||||||
self.log_to_stdout = enable;
|
self.log_to_stdout = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_basedir(base_path: &Path) -> Result<(), Error> {
|
fn create_basedir<P: AsRef<Path>>(base_path: P) -> Result<(), Error> {
|
||||||
let backup_user = pbs_config::backup_user()?;
|
let backup_user = pbs_config::backup_user()?;
|
||||||
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640);
|
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640);
|
||||||
let opts = CreateOptions::new()
|
let opts = CreateOptions::new()
|
||||||
@ -179,15 +182,15 @@ impl MediaCatalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Open a catalog database, load into memory
|
/// Open a catalog database, load into memory
|
||||||
pub fn open(
|
pub fn open<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
media_id: &MediaId,
|
media_id: &MediaId,
|
||||||
write: bool,
|
write: bool,
|
||||||
create: bool,
|
create: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let uuid = &media_id.label.uuid;
|
let uuid = &media_id.label.uuid;
|
||||||
|
|
||||||
let path = Self::catalog_path(base_path, uuid);
|
let path = Self::catalog_path(&base_path, uuid);
|
||||||
|
|
||||||
let me = proxmox_lang::try_block!({
|
let me = proxmox_lang::try_block!({
|
||||||
Self::create_basedir(base_path)?;
|
Self::create_basedir(base_path)?;
|
||||||
@ -239,8 +242,11 @@ impl MediaCatalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a temporary empty catalog file
|
/// Creates a temporary empty catalog file
|
||||||
pub fn create_temporary_database_file(base_path: &Path, uuid: &Uuid) -> Result<File, Error> {
|
pub fn create_temporary_database_file<P: AsRef<Path>>(
|
||||||
Self::create_basedir(base_path)?;
|
base_path: P,
|
||||||
|
uuid: &Uuid,
|
||||||
|
) -> Result<File, Error> {
|
||||||
|
Self::create_basedir(&base_path)?;
|
||||||
|
|
||||||
let tmp_path = Self::tmp_catalog_path(base_path, uuid);
|
let tmp_path = Self::tmp_catalog_path(base_path, uuid);
|
||||||
|
|
||||||
@ -270,14 +276,14 @@ impl MediaCatalog {
|
|||||||
/// Creates a temporary, empty catalog database
|
/// Creates a temporary, empty catalog database
|
||||||
///
|
///
|
||||||
/// Creates a new catalog file using a ".tmp" file extension.
|
/// Creates a new catalog file using a ".tmp" file extension.
|
||||||
pub fn create_temporary_database(
|
pub fn create_temporary_database<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
media_id: &MediaId,
|
media_id: &MediaId,
|
||||||
log_to_stdout: bool,
|
log_to_stdout: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let uuid = &media_id.label.uuid;
|
let uuid = &media_id.label.uuid;
|
||||||
|
|
||||||
let tmp_path = Self::tmp_catalog_path(base_path, uuid);
|
let tmp_path = Self::tmp_catalog_path(&base_path, uuid);
|
||||||
|
|
||||||
let me = proxmox_lang::try_block!({
|
let me = proxmox_lang::try_block!({
|
||||||
let file = Self::create_temporary_database_file(base_path, uuid)?;
|
let file = Self::create_temporary_database_file(base_path, uuid)?;
|
||||||
@ -322,8 +328,8 @@ impl MediaCatalog {
|
|||||||
///
|
///
|
||||||
/// With commit set, we rename the ".tmp" file extension to
|
/// With commit set, we rename the ".tmp" file extension to
|
||||||
/// ".log". When commit is false, we remove the ".tmp" file.
|
/// ".log". When commit is false, we remove the ".tmp" file.
|
||||||
pub fn finish_temporary_database(
|
pub fn finish_temporary_database<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
uuid: &Uuid,
|
uuid: &Uuid,
|
||||||
commit: bool,
|
commit: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@ -397,14 +403,14 @@ impl MediaCatalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy existing catalog, opens a new one
|
/// Destroy existing catalog, opens a new one
|
||||||
pub fn overwrite(
|
pub fn overwrite<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
media_id: &MediaId,
|
media_id: &MediaId,
|
||||||
log_to_stdout: bool,
|
log_to_stdout: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let uuid = &media_id.label.uuid;
|
let uuid = &media_id.label.uuid;
|
||||||
|
|
||||||
let me = Self::create_temporary_database(base_path, media_id, log_to_stdout)?;
|
let me = Self::create_temporary_database(&base_path, media_id, log_to_stdout)?;
|
||||||
|
|
||||||
Self::finish_temporary_database(base_path, uuid, true)?;
|
Self::finish_temporary_database(base_path, uuid, true)?;
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ use crate::tape::{MediaCatalog, MediaId};
|
|||||||
///
|
///
|
||||||
/// To speedup things for large catalogs, we cache the list of
|
/// To speedup things for large catalogs, we cache the list of
|
||||||
/// snapshots into a separate file.
|
/// snapshots into a separate file.
|
||||||
pub fn media_catalog_snapshot_list(
|
pub fn media_catalog_snapshot_list<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
media_id: &MediaId,
|
media_id: &MediaId,
|
||||||
) -> Result<Vec<(String, String)>, Error> {
|
) -> Result<Vec<(String, String)>, Error> {
|
||||||
let uuid = &media_id.label.uuid;
|
let uuid = &media_id.label.uuid;
|
||||||
|
|
||||||
let mut cache_path = base_path.to_owned();
|
let mut cache_path = base_path.as_ref().to_owned();
|
||||||
cache_path.push(uuid.to_string());
|
cache_path.push(uuid.to_string());
|
||||||
let mut catalog_path = cache_path.clone();
|
let mut catalog_path = cache_path.clone();
|
||||||
cache_path.set_extension("index");
|
cache_path.set_extension("index");
|
||||||
@ -42,7 +42,7 @@ pub fn media_catalog_snapshot_list(
|
|||||||
Some(Ok(id)) => {
|
Some(Ok(id)) => {
|
||||||
if id != cache_id {
|
if id != cache_id {
|
||||||
// cache is outdated - rewrite
|
// cache is outdated - rewrite
|
||||||
return write_snapshot_cache(base_path, media_id, &cache_path, &cache_id);
|
return write_snapshot_cache(&base_path, media_id, &cache_path, &cache_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => bail!("unable to read catalog cache firstline {:?}", cache_path),
|
_ => bail!("unable to read catalog cache firstline {:?}", cache_path),
|
||||||
@ -69,8 +69,8 @@ pub fn media_catalog_snapshot_list(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_snapshot_cache(
|
fn write_snapshot_cache<P: AsRef<Path>>(
|
||||||
base_path: &Path,
|
base_path: P,
|
||||||
media_id: &MediaId,
|
media_id: &MediaId,
|
||||||
cache_path: &Path,
|
cache_path: &Path,
|
||||||
cache_id: &str,
|
cache_id: &str,
|
||||||
|
@ -56,9 +56,9 @@ impl MediaPool {
|
|||||||
/// `changer`, all offline media is considered available (backups
|
/// `changer`, all offline media is considered available (backups
|
||||||
/// to standalone drives may not use media from inside a tape
|
/// to standalone drives may not use media from inside a tape
|
||||||
/// library).
|
/// library).
|
||||||
pub fn new(
|
pub fn new<P: AsRef<Path>>(
|
||||||
name: &str,
|
name: &str,
|
||||||
state_path: &Path,
|
state_path: P,
|
||||||
media_set_policy: MediaSetPolicy,
|
media_set_policy: MediaSetPolicy,
|
||||||
retention: RetentionPolicy,
|
retention: RetentionPolicy,
|
||||||
changer_name: Option<String>,
|
changer_name: Option<String>,
|
||||||
@ -68,10 +68,10 @@ impl MediaPool {
|
|||||||
let _pool_lock = if no_media_set_locking {
|
let _pool_lock = if no_media_set_locking {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(lock_media_pool(state_path, name)?)
|
Some(lock_media_pool(&state_path, name)?)
|
||||||
};
|
};
|
||||||
|
|
||||||
let inventory = Inventory::load(state_path)?;
|
let inventory = Inventory::load(&state_path)?;
|
||||||
|
|
||||||
let current_media_set = match inventory.latest_media_set(name) {
|
let current_media_set = match inventory.latest_media_set(name) {
|
||||||
Some(set_uuid) => inventory.compute_media_set_members(&set_uuid)?,
|
Some(set_uuid) => inventory.compute_media_set_members(&set_uuid)?,
|
||||||
@ -81,12 +81,12 @@ impl MediaPool {
|
|||||||
let current_media_set_lock = if no_media_set_locking {
|
let current_media_set_lock = if no_media_set_locking {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(lock_media_set(state_path, current_media_set.uuid(), None)?)
|
Some(lock_media_set(&state_path, current_media_set.uuid(), None)?)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(MediaPool {
|
Ok(MediaPool {
|
||||||
name: String::from(name),
|
name: String::from(name),
|
||||||
state_path: state_path.to_owned(),
|
state_path: state_path.as_ref().to_owned(),
|
||||||
media_set_policy,
|
media_set_policy,
|
||||||
retention,
|
retention,
|
||||||
changer_name,
|
changer_name,
|
||||||
@ -112,8 +112,8 @@ impl MediaPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new instance using the media pool configuration
|
/// Creates a new instance using the media pool configuration
|
||||||
pub fn with_config(
|
pub fn with_config<P: AsRef<Path>>(
|
||||||
state_path: &Path,
|
state_path: P,
|
||||||
config: &MediaPoolConfig,
|
config: &MediaPoolConfig,
|
||||||
changer_name: Option<String>,
|
changer_name: Option<String>,
|
||||||
no_media_set_locking: bool, // for list_media()
|
no_media_set_locking: bool, // for list_media()
|
||||||
|
@ -6,7 +6,7 @@ pub use new_chunks_iterator::*;
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
@ -77,8 +77,7 @@ impl PoolWriter {
|
|||||||
// load all catalogs read-only at start
|
// load all catalogs read-only at start
|
||||||
for media_uuid in pool.current_media_list()? {
|
for media_uuid in pool.current_media_list()? {
|
||||||
let media_info = pool.lookup_media(media_uuid).unwrap();
|
let media_info = pool.lookup_media(media_uuid).unwrap();
|
||||||
let media_catalog =
|
let media_catalog = MediaCatalog::open(TAPE_STATUS_DIR, media_info.id(), false, false)?;
|
||||||
MediaCatalog::open(Path::new(TAPE_STATUS_DIR), media_info.id(), false, false)?;
|
|
||||||
catalog_set.append_read_only_catalog(media_catalog)?;
|
catalog_set.append_read_only_catalog(media_catalog)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,8 +296,7 @@ impl PoolWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_catalog_file(uuid: &Uuid) -> Result<File, Error> {
|
fn open_catalog_file(uuid: &Uuid) -> Result<File, Error> {
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let mut path = PathBuf::from(TAPE_STATUS_DIR);
|
||||||
let mut path = status_path.to_owned();
|
|
||||||
path.push(uuid.to_string());
|
path.push(uuid.to_string());
|
||||||
path.set_extension("log");
|
path.set_extension("log");
|
||||||
|
|
||||||
@ -634,13 +632,11 @@ fn update_media_set_label(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
|
||||||
|
|
||||||
let new_media = match old_set {
|
let new_media = match old_set {
|
||||||
None => {
|
None => {
|
||||||
task_log!(worker, "writing new media set label");
|
task_log!(worker, "writing new media set label");
|
||||||
drive.write_media_set_label(new_set, key_config.as_ref())?;
|
drive.write_media_set_label(new_set, key_config.as_ref())?;
|
||||||
media_catalog = MediaCatalog::overwrite(status_path, media_id, false)?;
|
media_catalog = MediaCatalog::overwrite(TAPE_STATUS_DIR, media_id, false)?;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Some(media_set_label) => {
|
Some(media_set_label) => {
|
||||||
@ -656,7 +652,7 @@ fn update_media_set_label(
|
|||||||
{
|
{
|
||||||
bail!("detected changed encryption fingerprint - internal error");
|
bail!("detected changed encryption fingerprint - internal error");
|
||||||
}
|
}
|
||||||
media_catalog = MediaCatalog::open(status_path, media_id, true, false)?;
|
media_catalog = MediaCatalog::open(TAPE_STATUS_DIR, media_id, true, false)?;
|
||||||
|
|
||||||
// todo: verify last content/media_catalog somehow?
|
// todo: verify last content/media_catalog somehow?
|
||||||
|
|
||||||
@ -670,7 +666,7 @@ fn update_media_set_label(
|
|||||||
);
|
);
|
||||||
|
|
||||||
drive.write_media_set_label(new_set, key_config.as_ref())?;
|
drive.write_media_set_label(new_set, key_config.as_ref())?;
|
||||||
media_catalog = MediaCatalog::overwrite(status_path, media_id, false)?;
|
media_catalog = MediaCatalog::overwrite(TAPE_STATUS_DIR, media_id, false)?;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user