type: bool,
optional: true,
},
+ "export-media-set": {
+ description: "Export media set upon job completion.",
+ type: bool,
+ optional: true,
+ },
},
},
returns: {
store: String,
pool: String,
eject_media: Option<bool>,
+ export_media_set: Option<bool>,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let eject_media = eject_media.unwrap_or(false);
+ let export_media_set = export_media_set.unwrap_or(false);
let upid_str = WorkerTask::new_thread(
"tape-backup",
auth_id,
to_stdout,
move |worker| {
- backup_worker(&worker, datastore, &pool_config, eject_media)?;
+ backup_worker(&worker, datastore, &pool_config, eject_media, export_media_set)?;
Ok(())
}
)?;
datastore: Arc<DataStore>,
pool_config: &MediaPoolConfig,
eject_media: bool,
+ export_media_set: bool,
) -> Result<(), Error> {
let status_path = Path::new(TAPE_STATUS_DIR);
pool_writer.commit()?;
- if eject_media {
+ if export_media_set {
+ worker.log(format!("exporting current media set"));
+ pool_writer.export_media_set(worker)?;
+ } else if eject_media {
worker.log(format!("ejection backup media"));
pool_writer.eject_media()?;
}
let (drive_config, _digest) = crate::config::drive::config()?;
if let Some((mut changer, _)) = media_changer(&drive_config, &self.drive_name)? {
+ drop(status); // close drive
changer.unload_media(None)?;
} else {
status.drive.eject_media()?;
Ok(())
}
+ /// Export current media set and drop PoolWriterState (close drive)
+ pub fn export_media_set(&mut self, worker: &WorkerTask) -> Result<(), Error> {
+ let mut status = self.status.take();
+
+ let (drive_config, _digest) = crate::config::drive::config()?;
+
+ if let Some((mut changer, _)) = media_changer(&drive_config, &self.drive_name)? {
+ drop(status); // close drive
+
+ changer.unload_media(None)?;
+
+ for media_uuid in self.pool.current_media_list()? {
+ let media = self.pool.lookup_media(media_uuid)?;
+ let changer_id = media.changer_id();
+ if let Some(slot) = changer.export_media(changer_id)? {
+ worker.log(format!("exported media '{}' to import/export slot {}", changer_id, slot));
+ } else {
+ worker.warn(format!("export failed - media '{}' is not online", changer_id));
+ }
+ }
+
+ } else {
+ worker.log("standalone drive - ejecting media instead of export");
+ if let Some(mut status) = status {
+ status.drive.eject_media()?;
+ }
+ }
+
+ Ok(())
+ }
+
/// commit changes to tape and catalog
///
/// This is done automatically during a backupsession, but needs to