]> git.proxmox.com Git - proxmox-backup.git/commitdiff
tape: use worker tasks for media load/unload
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 18 Feb 2021 08:04:51 +0000 (09:04 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 18 Feb 2021 08:04:51 +0000 (09:04 +0100)
src/api2/tape/drive.rs
src/bin/proxmox-tape.rs

index 4d888b1f29c94a2142357891c011581aa3759b8c..8de8d39d93a5747967d410ce2867f1320ec20f7d 100644 (file)
@@ -78,21 +78,47 @@ use crate::{
             },
         },
     },
+    returns: {
+        schema: UPID_SCHEMA,
+    },
 )]
 /// Load media with specified label
 ///
 /// Issue a media load request to the associated changer device.
-pub async fn load_media(drive: String, label_text: String) -> Result<(), Error> {
+pub fn load_media(
+    drive: String,
+    label_text: String,
+    rpcenv: &mut dyn RpcEnvironment,
+) -> Result<Value, Error> {
 
     let (config, _digest) = config::drive::config()?;
+
+    // early check/lock before starting worker
     let lock_guard = lock_tape_device(&config, &drive)?;
 
-    tokio::task::spawn_blocking(move || {
-        let _lock_guard = lock_guard; // keep lock guard
+    let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
 
-        let (mut changer, _) = required_media_changer(&config, &drive)?;
-        changer.load_media(&label_text)
-    }).await?
+    let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
+
+    let job_id = format!("{}:{}", drive, label_text);
+
+    let upid_str = WorkerTask::new_thread(
+        "load-media",
+        Some(job_id),
+        auth_id,
+        to_stdout,
+        move |worker| {
+            let _lock_guard = lock_guard; // keep lock guard
+
+            task_log!(worker, "loading media '{}' into drive '{}'", label_text, drive);
+            let (mut changer, _) = required_media_changer(&config, &drive)?;
+            changer.load_media(&label_text)?;
+
+            Ok(())
+        }
+    )?;
+
+    Ok(upid_str.into())
 }
 
 #[api(
@@ -171,23 +197,42 @@ pub async fn export_media(drive: String, label_text: String) -> Result<u64, Erro
             },
         },
     },
+    returns: {
+        schema: UPID_SCHEMA,
+    },
 )]
 /// Unload media via changer
-pub async fn unload(
+pub fn unload(
     drive: String,
     target_slot: Option<u64>,
-    _param: Value,
-) -> Result<(), Error> {
+    rpcenv: &mut dyn RpcEnvironment,
+) -> Result<Value, Error> {
 
     let (config, _digest) = config::drive::config()?;
+    // early check/lock before starting worker
     let lock_guard = lock_tape_device(&config, &drive)?;
 
-    tokio::task::spawn_blocking(move || {
-        let _lock_guard = lock_guard; // keep lock guard
+    let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
 
-        let (mut changer, _) = required_media_changer(&config, &drive)?;
-        changer.unload_media(target_slot)
-    }).await?
+    let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
+
+    let upid_str = WorkerTask::new_thread(
+        "unload-media",
+        Some(drive.clone()),
+        auth_id,
+        to_stdout,
+        move |worker| {
+            let _lock_guard = lock_guard; // keep lock guard
+
+            task_log!(worker, "unloading media from drive '{}'", drive);
+
+            let (mut changer, _) = required_media_changer(&config, &drive)?;
+            changer.unload_media(target_slot)?;
+            Ok(())
+        }
+    )?;
+
+    Ok(upid_str.into())
 }
 
 #[api(
@@ -1297,7 +1342,7 @@ pub const SUBDIRS: SubdirMap = &sorted!([
     (
         "load-media",
         &Router::new()
-            .put(&API_METHOD_LOAD_MEDIA)
+            .post(&API_METHOD_LOAD_MEDIA)
     ),
     (
         "load-slot",
@@ -1332,7 +1377,7 @@ pub const SUBDIRS: SubdirMap = &sorted!([
     (
         "unload",
         &Router::new()
-            .put(&API_METHOD_UNLOAD)
+            .post(&API_METHOD_UNLOAD)
     ),
 ]);
 
index 9de976f690d96ecc0c66963b98e125683fc4dd48..eb792986e26e9abaf76ca2042fd1a4cae04eb99e 100644 (file)
@@ -206,12 +206,18 @@ async fn eject_media(mut param: Value) -> Result<(), Error> {
             "label-text": {
                 schema: MEDIA_LABEL_SCHEMA,
             },
+            "output-format": {
+                schema: OUTPUT_FORMAT,
+                optional: true,
+            },
         },
     },
 )]
 /// Load media with specified label
 async fn load_media(mut param: Value) -> Result<(), Error> {
 
+    let output_format = get_output_format(&param);
+
     let (config, _digest) = config::drive::config()?;
 
     let drive = extract_drive_name(&mut param, &config)?;
@@ -219,7 +225,9 @@ async fn load_media(mut param: Value) -> Result<(), Error> {
     let mut client = connect_to_localhost()?;
 
     let path = format!("api2/json/tape/drive/{}/load-media", drive);
-    client.put(&path, Some(param)).await?;
+    let result = client.post(&path, Some(param)).await?;
+
+    view_task_result(&mut client, result, &output_format).await?;
 
     Ok(())
 }
@@ -295,12 +303,18 @@ async fn load_media_from_slot(mut param: Value) -> Result<(), Error> {
                 minimum: 1,
                 optional: true,
             },
+            "output-format": {
+                schema: OUTPUT_FORMAT,
+                optional: true,
+            },
         },
     },
 )]
 /// Unload media via changer
 async fn unload_media(mut param: Value) -> Result<(), Error> {
 
+    let output_format = get_output_format(&param);
+
     let (config, _digest) = config::drive::config()?;
 
     let drive = extract_drive_name(&mut param, &config)?;
@@ -308,7 +322,9 @@ async fn unload_media(mut param: Value) -> Result<(), Error> {
     let mut client = connect_to_localhost()?;
 
     let path = format!("api2/json/tape/drive/{}/unload", drive);
-    client.put(&path, Some(param)).await?;
+    let result = client.post(&path, Some(param)).await?;
+
+    view_task_result(&mut client, result, &output_format).await?;
 
     Ok(())
 }