tape: improve media request/load
This commit is contained in:
parent
2fb1bdda20
commit
ff58c51919
@ -178,7 +178,7 @@ pub fn backup_snapshot(
|
||||
break;
|
||||
}
|
||||
|
||||
let uuid = pool_writer.load_writable_media()?;
|
||||
let uuid = pool_writer.load_writable_media(worker)?;
|
||||
|
||||
let (leom, _bytes) = pool_writer.append_chunk_archive(&datastore, &mut chunk_iter)?;
|
||||
|
||||
@ -187,7 +187,7 @@ pub fn backup_snapshot(
|
||||
}
|
||||
}
|
||||
|
||||
let uuid = pool_writer.load_writable_media()?;
|
||||
let uuid = pool_writer.load_writable_media(worker)?;
|
||||
|
||||
let (done, _bytes) = pool_writer.append_snapshot_archive(&snapshot_reader)?;
|
||||
|
||||
@ -195,7 +195,7 @@ pub fn backup_snapshot(
|
||||
// does not fit on tape, so we try on next volume
|
||||
pool_writer.set_media_status_full(&uuid)?;
|
||||
|
||||
pool_writer.load_writable_media()?;
|
||||
pool_writer.load_writable_media(worker)?;
|
||||
let (done, _bytes) = pool_writer.append_snapshot_archive(&snapshot_reader)?;
|
||||
|
||||
if !done {
|
||||
|
@ -67,7 +67,7 @@ pub fn request_and_restore_media(
|
||||
Some(ref set) => &set.uuid,
|
||||
};
|
||||
|
||||
let (mut drive, info) = request_and_load_media(&drive_config, &drive_name, &media_id.label)?;
|
||||
let (mut drive, info) = request_and_load_media(worker, &drive_config, &drive_name, &media_id.label)?;
|
||||
|
||||
match info.media_set_label {
|
||||
None => {
|
||||
|
@ -19,6 +19,7 @@ use crate::{
|
||||
VirtualTapeDrive,
|
||||
LinuxTapeDrive,
|
||||
},
|
||||
server::WorkerTask,
|
||||
tape::{
|
||||
TapeWrite,
|
||||
TapeRead,
|
||||
@ -223,6 +224,7 @@ pub fn open_drive(
|
||||
///
|
||||
/// Returns a handle to the opened drive and the media labels.
|
||||
pub fn request_and_load_media(
|
||||
worker: &WorkerTask,
|
||||
config: &SectionConfigData,
|
||||
drive: &str,
|
||||
label: &MediaLabel,
|
||||
@ -231,51 +233,97 @@ pub fn request_and_load_media(
|
||||
MediaId,
|
||||
), Error> {
|
||||
|
||||
let check_label = |handle: &mut dyn TapeDriver, uuid: &proxmox::tools::Uuid| {
|
||||
if let Ok(Some(media_id)) = handle.read_label() {
|
||||
println!("found media label {} ({})", media_id.label.changer_id, media_id.label.uuid.to_string());
|
||||
if media_id.label.uuid == *uuid {
|
||||
return Ok(media_id);
|
||||
}
|
||||
}
|
||||
bail!("read label failed (please label all tapes first)");
|
||||
};
|
||||
|
||||
match config.sections.get(drive) {
|
||||
Some((section_type_name, config)) => {
|
||||
match section_type_name.as_ref() {
|
||||
"virtual" => {
|
||||
let mut drive = VirtualTapeDrive::deserialize(config)?;
|
||||
let mut tape = VirtualTapeDrive::deserialize(config)?;
|
||||
|
||||
let changer_id = label.changer_id.clone();
|
||||
|
||||
drive.load_media(&changer_id)?;
|
||||
tape.load_media(&changer_id)?;
|
||||
|
||||
let mut handle = drive.open()?;
|
||||
let mut handle: Box<dyn TapeDriver> = Box::new(tape.open()?);
|
||||
|
||||
if let Ok(Some(media_id)) = handle.read_label() {
|
||||
println!("found media label {} ({})", media_id.label.changer_id, media_id.label.uuid.to_string());
|
||||
if media_id.label.uuid == label.uuid {
|
||||
return Ok((Box::new(handle), media_id));
|
||||
}
|
||||
}
|
||||
bail!("read label failed (label all tapes first)");
|
||||
let media_id = check_label(handle.as_mut(), &label.uuid)?;
|
||||
|
||||
return Ok((handle, media_id));
|
||||
}
|
||||
"linux" => {
|
||||
let tape = LinuxTapeDrive::deserialize(config)?;
|
||||
let mut tape = LinuxTapeDrive::deserialize(config)?;
|
||||
|
||||
let id = label.changer_id.clone();
|
||||
let changer_id = label.changer_id.clone();
|
||||
|
||||
println!("Please insert media '{}' into drive '{}'", id, drive);
|
||||
if tape.changer.is_some() {
|
||||
|
||||
tape.load_media(&changer_id)?;
|
||||
|
||||
let mut handle: Box<dyn TapeDriver> = Box::new(tape.open()?);
|
||||
|
||||
let media_id = check_label(handle.as_mut(), &label.uuid)?;
|
||||
|
||||
return Ok((handle, media_id));
|
||||
}
|
||||
|
||||
worker.log(format!("Please insert media '{}' into drive '{}'", changer_id, drive));
|
||||
|
||||
let to = "root@localhost"; // fixme
|
||||
let mut changer = ChangeMediaEmail::new(drive, to);
|
||||
|
||||
changer.load_media(&changer_id)?; // semd email
|
||||
|
||||
let mut last_media_uuid = None;
|
||||
|
||||
loop {
|
||||
let mut handle = match tape.open() {
|
||||
Ok(handle) => handle,
|
||||
Err(_) => {
|
||||
eprintln!("tape open failed - test again in 5 secs");
|
||||
//eprintln!("tape open failed - test again in 5 secs");
|
||||
std::thread::sleep(std::time::Duration::from_millis(5_000));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Ok(Some(media_id)) = handle.read_label() {
|
||||
println!("found media label {} ({})", media_id.label.changer_id, media_id.label.uuid.to_string());
|
||||
if media_id.label.uuid == label.uuid {
|
||||
return Ok((Box::new(handle), media_id));
|
||||
match handle.read_label() {
|
||||
Ok(Some(media_id)) => {
|
||||
if media_id.label.uuid == label.uuid {
|
||||
worker.log(format!(
|
||||
"found media label {} ({})",
|
||||
media_id.label.changer_id,
|
||||
media_id.label.uuid.to_string(),
|
||||
));
|
||||
return Ok((Box::new(handle), media_id));
|
||||
} else {
|
||||
if Some(media_id.label.uuid.clone()) != last_media_uuid {
|
||||
worker.log(format!(
|
||||
"wrong media label {} ({})",
|
||||
media_id.label.changer_id,
|
||||
media_id.label.uuid.to_string(),
|
||||
));
|
||||
last_media_uuid = Some(media_id.label.uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
if last_media_uuid.is_some() {
|
||||
worker.log(format!("found empty media without label (please label all tapes first)"));
|
||||
last_media_uuid = None;
|
||||
}
|
||||
}
|
||||
Err(_) => { /* test again */ }
|
||||
}
|
||||
|
||||
println!("read label failed - test again in 5 secs");
|
||||
// eprintln!("read label failed - test again in 5 secs");
|
||||
std::thread::sleep(std::time::Duration::from_millis(5_000));
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use crate::{
|
||||
backup::{
|
||||
DataStore,
|
||||
},
|
||||
server::WorkerTask,
|
||||
tape::{
|
||||
TAPE_STATUS_DIR,
|
||||
MAX_CHUNK_ARCHIVE_SIZE,
|
||||
@ -118,7 +119,7 @@ impl PoolWriter {
|
||||
}
|
||||
|
||||
/// Load a writable media into the drive
|
||||
pub fn load_writable_media(&mut self) -> Result<Uuid, Error> {
|
||||
pub fn load_writable_media(&mut self, worker: &WorkerTask) -> Result<Uuid, Error> {
|
||||
let last_media_uuid = match self.status {
|
||||
Some(PoolWriterState { ref catalog, .. }) => Some(catalog.uuid().clone()),
|
||||
None => None,
|
||||
@ -147,7 +148,7 @@ impl PoolWriter {
|
||||
}
|
||||
|
||||
let (drive_config, _digest) = crate::config::drive::config()?;
|
||||
let (drive, catalog) = drive_load_and_label_media(&drive_config, &self.drive_name, &media.id())?;
|
||||
let (drive, catalog) = drive_load_and_label_media(worker, &drive_config, &self.drive_name, &media.id())?;
|
||||
self.status = Some(PoolWriterState { drive, catalog, at_eom: false, bytes_written: 0 });
|
||||
|
||||
Ok(media_uuid)
|
||||
@ -333,13 +334,14 @@ fn write_chunk_archive<'a>(
|
||||
// set label. If the tabe is empty, or the existing set label does not
|
||||
// match the expected media set, overwrite the media set label.
|
||||
fn drive_load_and_label_media(
|
||||
worker: &WorkerTask,
|
||||
drive_config: &SectionConfigData,
|
||||
drive_name: &str,
|
||||
media_id: &MediaId,
|
||||
) -> Result<(Box<dyn TapeDriver>, MediaCatalog), Error> {
|
||||
|
||||
let (mut tmp_drive, info) =
|
||||
request_and_load_media(&drive_config, &drive_name, &media_id.label)?;
|
||||
request_and_load_media(worker, &drive_config, &drive_name, &media_id.label)?;
|
||||
|
||||
let media_catalog;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user