]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/tape/drive/virtual_tape.rs
typo fixes all over the place
[proxmox-backup.git] / src / tape / drive / virtual_tape.rs
index 3967388ca5a773d4318a0f1b1834894080f8758e..6dcf31fb1d1f53b9c55c9770b74cd61a545a6c95 100644 (file)
@@ -11,13 +11,17 @@ use proxmox::tools::{
 };
 
 use crate::{
+    backup::KeyConfig,
     tape::{
         TapeWrite,
         TapeRead,
-        MtxStatus,
-        DriveStatus,
-        ElementStatus,
-        changer::MediaChange,
+        changer::{
+            MediaChange,
+            MtxStatus,
+            DriveStatus,
+            ElementStatus,
+            StorageElementStatus,
+        },
         drive::{
             VirtualTapeDrive,
             TapeDriver,
@@ -26,12 +30,12 @@ use crate::{
             MediaSetLabel,
             MediaContentHeader,
             PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0,
+            BlockedReader,
+            BlockedWriter,
         },
         helpers::{
             EmulateTapeReader,
             EmulateTapeWriter,
-            BlockedReader,
-            BlockedWriter,
         },
     },
 };
@@ -40,17 +44,20 @@ impl VirtualTapeDrive {
 
     /// This needs to lock the drive
     pub fn open(&self) -> Result<VirtualTapeHandle, Error> {
-        let mut lock_path = std::path::PathBuf::from(&self.path);
-        lock_path.push(".drive.lck");
+        proxmox::try_block!({
+            let mut lock_path = std::path::PathBuf::from(&self.path);
+            lock_path.push(".drive.lck");
 
-        let timeout = std::time::Duration::new(10, 0);
-        let lock = proxmox::tools::fs::open_file_locked(&lock_path, timeout, true)?;
+            let timeout = std::time::Duration::new(10, 0);
+            let lock = proxmox::tools::fs::open_file_locked(&lock_path, timeout, true)?;
 
-        Ok(VirtualTapeHandle {
-            _lock: lock,
-            max_size: self.max_size.unwrap_or(64*1024*1024),
-            path: std::path::PathBuf::from(&self.path),
-        })
+            Ok(VirtualTapeHandle {
+                _lock: lock,
+                drive_name: self.name.clone(),
+                max_size: self.max_size.unwrap_or(64*1024*1024),
+                path: std::path::PathBuf::from(&self.path),
+            })
+        }).map_err(|err: Error| format_err!("open drive '{}' ({}) failed - {}", self.name, self.path, err))
     }
 }
 
@@ -71,6 +78,7 @@ struct TapeIndex {
 }
 
 pub struct VirtualTapeHandle {
+    drive_name: String,
     path: std::path::PathBuf,
     max_size: usize,
     _lock: File,
@@ -155,7 +163,7 @@ impl VirtualTapeHandle {
         Ok(())
     }
 
-    fn online_media_changer_ids(&self) -> Result<Vec<String>, Error> {
+    fn online_media_label_texts(&self) -> Result<Vec<String>, Error> {
         let mut list = Vec::new();
         for entry in std::fs::read_dir(&self.path)? {
             let entry = entry?;
@@ -163,8 +171,8 @@ impl VirtualTapeHandle {
             if path.is_file() && path.extension() == Some(std::ffi::OsStr::new("json")) {
                 if let Some(name) = path.file_stem() {
                     if let Some(name) = name.to_str() {
-                        if name.starts_with("tape-") {
-                            list.push(name[5..].to_string());
+                        if let Some(label) = name.strip_prefix("tape-") {
+                            list.push(label.to_string());
                         }
                     }
                 }
@@ -321,7 +329,17 @@ impl TapeDriver for VirtualTapeHandle {
         }
     }
 
-    fn write_media_set_label(&mut self, media_set_label: &MediaSetLabel) -> Result<(), Error> {
+    fn write_media_set_label(
+        &mut self,
+        media_set_label: &MediaSetLabel,
+        key_config: Option<&KeyConfig>,
+    ) -> Result<(), Error> {
+
+        self.set_encryption(None)?;
+
+        if key_config.is_some() {
+            bail!("encryption is not implemented - internal error");
+        }
 
         let mut status = self.load_status()?;
         match status.current_tape {
@@ -362,6 +380,14 @@ impl TapeDriver for VirtualTapeHandle {
 
 impl MediaChange for VirtualTapeHandle {
 
+    fn drive_number(&self) -> u64 {
+        0
+    }
+
+    fn drive_name(&self) -> &str {
+        &self.drive_name
+    }
+
     fn status(&mut self) -> Result<MtxStatus, Error> {
 
         let drive_status = self.load_status()?;
@@ -372,50 +398,63 @@ impl MediaChange for VirtualTapeHandle {
             drives.push(DriveStatus {
                 loaded_slot: None,
                 status: ElementStatus::VolumeTag(current_tape.name.clone()),
-            });
+                drive_serial_number: None,
+                vendor: None,
+                model: None,
+                element_address: 0,
+           });
         }
 
         // This implementation is lame, because we do not have fixed
         // slot-assignment here.
 
         let mut slots = Vec::new();
-        let changer_ids = self.online_media_changer_ids()?;
-        let max_slots = ((changer_ids.len() + 7)/8) * 8;
+        let label_texts = self.online_media_label_texts()?;
+        let max_slots = ((label_texts.len() + 7)/8) * 8;
 
         for i in 0..max_slots {
-            if let Some(changer_id) = changer_ids.get(i) {
-                slots.push((false,  ElementStatus::VolumeTag(changer_id.clone())));
+            let status = if let Some(label_text) = label_texts.get(i) {
+                ElementStatus::VolumeTag(label_text.clone())
             } else {
-                slots.push((false,  ElementStatus::Empty));
-            }
+                ElementStatus::Empty
+            };
+            slots.push(StorageElementStatus {
+                import_export: false,
+                status,
+                element_address: (i + 1) as u16,
+            });
         }
 
-        Ok(MtxStatus { drives, slots })
+        Ok(MtxStatus { drives, slots, transports: Vec::new() })
+    }
+
+    fn transfer_media(&mut self, _from: u64, _to: u64) -> Result<MtxStatus, Error> {
+        bail!("media transfer is not implemented!");
     }
 
-    fn transfer(&mut self, from: u64, to: u64) -> Result<(), Error> {
-        bail!("medfia tranfer is not implemented!");
+    fn export_media(&mut self, _label_text: &str) -> Result<Option<u64>, Error> {
+        bail!("media export is not implemented!");
     }
 
-    fn load_media_from_slot(&mut self, slot: u64) -> Result<(), Error> {
+    fn load_media_from_slot(&mut self, slot: u64) -> Result<MtxStatus, Error> {
         if slot < 1 {
             bail!("invalid slot ID {}", slot);
         }
 
-        let changer_ids = self.online_media_changer_ids()?;
+        let label_texts = self.online_media_label_texts()?;
 
-        if slot > changer_ids.len() as u64 {
+        if slot > label_texts.len() as u64 {
             bail!("slot {} is empty", slot);
         }
 
-        self.load_media(&changer_ids[slot as usize - 1])
+        self.load_media(&label_texts[slot as usize - 1])
     }
 
     /// Try to load media
     ///
     /// We automatically create an empty virtual tape here (if it does
     /// not exist already)
-    fn load_media(&mut self, label: &str) -> Result<(), Error> {
+    fn load_media(&mut self, label: &str) -> Result<MtxStatus, Error> {
         let name = format!("tape-{}.json", label);
         let mut path = self.path.clone();
         path.push(&name);
@@ -431,63 +470,70 @@ impl MediaChange for VirtualTapeHandle {
                 pos: 0,
             }),
         };
-        self.store_status(&status)
+        self.store_status(&status)?;
+
+        self.status()
     }
 
-    fn unload_media(&mut self, _target_slot: Option<u64>) -> Result<(), Error> {
+    fn unload_media(&mut self, _target_slot: Option<u64>) -> Result<MtxStatus, Error> {
         // Note: we currently simply ignore target_slot
         self.eject_media()?;
-        Ok(())
+        self.status()
     }
 
-    fn eject_on_unload(&self) -> bool {
-        true
-    }
-
-    fn clean_drive(&mut self) -> Result<(), Error> {
-        Ok(())
+    fn clean_drive(&mut self) -> Result<MtxStatus, Error> {
+        // do nothing
+        self.status()
     }
 }
 
 impl MediaChange for VirtualTapeDrive {
 
+    fn drive_number(&self) -> u64 {
+        0
+    }
+
+    fn drive_name(&self) -> &str {
+        &self.name
+    }
+
     fn status(&mut self) -> Result<MtxStatus, Error> {
         let mut handle = self.open()?;
         handle.status()
     }
 
-    fn transfer(&mut self, from: u64, to: u64) -> Result<(), Error> {
+    fn transfer_media(&mut self, from: u64, to: u64) -> Result<MtxStatus, Error> {
         let mut handle = self.open()?;
-        handle.transfer(from, to)
+        handle.transfer_media(from, to)
     }
 
-    fn load_media_from_slot(&mut self, slot: u64) -> Result<(), Error> {
+    fn export_media(&mut self, label_text: &str) -> Result<Option<u64>, Error> {
         let mut handle = self.open()?;
-        handle.load_media_from_slot(slot)
+        handle.export_media(label_text)
     }
 
-    fn load_media(&mut self, changer_id: &str) -> Result<(), Error> {
+    fn load_media_from_slot(&mut self, slot: u64) -> Result<MtxStatus, Error> {
         let mut handle = self.open()?;
-        handle.load_media(changer_id)
+        handle.load_media_from_slot(slot)
     }
 
-    fn unload_media(&mut self, target_slot: Option<u64>) -> Result<(), Error> {
+    fn load_media(&mut self, label_text: &str) -> Result<MtxStatus, Error> {
         let mut handle = self.open()?;
-        handle.unload_media(target_slot)?;
-        Ok(())
+        handle.load_media(label_text)
     }
 
-    fn eject_on_unload(&self) -> bool {
-        true
+    fn unload_media(&mut self, target_slot: Option<u64>) -> Result<MtxStatus, Error> {
+        let mut handle = self.open()?;
+        handle.unload_media(target_slot)
     }
 
-    fn online_media_changer_ids(&mut self) -> Result<Vec<String>, Error> {
+    fn online_media_label_texts(&mut self) -> Result<Vec<String>, Error> {
         let handle = self.open()?;
-        handle.online_media_changer_ids()
+        handle.online_media_label_texts()
     }
 
-    fn clean_drive(&mut self) -> Result<(), Error> {
-        Ok(())
+    fn clean_drive(&mut self) -> Result<MtxStatus, Error> {
+        let mut handle = self.open()?;
+        handle.clean_drive()
     }
-
 }