1 use anyhow
::{bail, Error}
;
4 use proxmox
::api
::{api, Router, SubdirMap}
;
5 use proxmox
::{sortable, identity, list_subdirs_api_method}
;
20 linux_tape_device_list
,
30 schema
: DRIVE_ID_SCHEMA
,
33 description
: "Source slot number",
39 /// Load media via changer from slot
44 ) -> Result
<(), Error
> {
46 let (config
, _digest
) = config
::drive
::config()?
;
48 let drive_config
: LinuxTapeDrive
= config
.lookup("linux", &drive
)?
;
50 let changer
: ScsiTapeChanger
= match drive_config
.changer
{
51 Some(ref changer
) => config
.lookup("changer", changer
)?
,
52 None
=> bail
!("drive '{}' has no associated changer", drive
),
55 let drivenum
= drive_config
.changer_drive_id
.unwrap_or(0);
57 mtx_load(&changer
.path
, slot
, drivenum
)
64 schema
: DRIVE_ID_SCHEMA
,
67 schema
: MEDIA_LABEL_SCHEMA
,
72 /// Load media with specified label
74 /// Issue a media load request to the associated changer device.
75 pub fn load_media(drive
: String
, changer_id
: String
) -> Result
<(), Error
> {
77 let (config
, _digest
) = config
::drive
::config()?
;
79 let (mut changer
, _
) = media_changer(&config
, &drive
, false)?
;
81 changer
.load_media(&changer_id
)?
;
90 schema
: DRIVE_ID_SCHEMA
,
93 description
: "Target slot number. If omitted, defaults to the slot that the drive was loaded from.",
100 /// Unload media via changer
105 ) -> Result
<(), Error
> {
107 let (config
, _digest
) = config
::drive
::config()?
;
109 let mut drive_config
: LinuxTapeDrive
= config
.lookup("linux", &drive
)?
;
111 let changer
: ScsiTapeChanger
= match drive_config
.changer
{
112 Some(ref changer
) => config
.lookup("changer", changer
)?
,
113 None
=> bail
!("drive '{}' has no associated changer", drive
),
116 let drivenum
: u64 = 0;
118 if let Some(slot
) = slot
{
119 mtx_unload(&changer
.path
, slot
, drivenum
)
121 drive_config
.unload_media()
130 description
: "The list of autodetected tape drives.",
133 type: TapeDeviceInfo
,
138 pub fn scan_drives(_param
: Value
) -> Result
<Vec
<TapeDeviceInfo
>, Error
> {
140 let list
= linux_tape_device_list();
149 schema
: DRIVE_ID_SCHEMA
,
152 description
: "Use fast erase.",
161 pub fn erase_media(drive
: String
, fast
: Option
<bool
>) -> Result
<(), Error
> {
163 let (config
, _digest
) = config
::drive
::config()?
;
165 let mut drive
= open_drive(&config
, &drive
)?
;
167 drive
.erase_media(fast
.unwrap_or(true))?
;
176 schema
: DRIVE_ID_SCHEMA
,
182 pub fn rewind(drive
: String
) -> Result
<(), Error
> {
184 let (config
, _digest
) = config
::drive
::config()?
;
186 let mut drive
= open_drive(&config
, &drive
)?
;
197 schema
: DRIVE_ID_SCHEMA
,
202 /// Eject/Unload drive media
203 pub fn eject_media(drive
: String
) -> Result
<(), Error
> {
205 let (config
, _digest
) = config
::drive
::config()?
;
207 let (mut changer
, _
) = media_changer(&config
, &drive
, false)?
;
209 if !changer
.eject_on_unload() {
210 let mut drive
= open_drive(&config
, &drive
)?
;
211 drive
.eject_media()?
;
214 changer
.unload_media()?
;
220 pub const SUBDIRS
: SubdirMap
= &sorted
!([
224 .put(&API_METHOD_EJECT_MEDIA
)
229 .put(&API_METHOD_ERASE_MEDIA
)
234 .put(&API_METHOD_LOAD_SLOT
)
239 .put(&API_METHOD_REWIND
)
244 .get(&API_METHOD_SCAN_DRIVES
)
249 .put(&API_METHOD_UNLOAD
)
253 pub const ROUTER
: Router
= Router
::new()
254 .get(&list_subdirs_api_method
!(SUBDIRS
))