1 /// Tape command implemented using scsi-generic raw commands
3 /// SCSI-generic command needs root priviledges, so this binary need
6 /// This command can use STDIN as tape device handle.
9 use std
::os
::unix
::io
::{AsRawFd, FromRawFd}
;
11 use anyhow
::{bail, Error}
;
23 LINUX_DRIVE_PATH_SCHEMA
,
28 open_linux_tape_device
,
29 check_tape_is_linux_tape_device
,
34 fn get_tape_handle(device
: Option
<String
>) -> Result
<LinuxTapeHandle
, Error
> {
36 let file
= if let Some(device
) = device
{
37 open_linux_tape_device(&device
)?
39 let fd
= std
::io
::stdin().as_raw_fd();
40 let file
= unsafe { File::from_raw_fd(fd) }
;
41 check_tape_is_linux_tape_device(&file
)?
;
44 Ok(LinuxTapeHandle
::new(file
))
51 schema
: LINUX_DRIVE_PATH_SCHEMA
,
59 device
: Option
<String
>,
60 ) -> Result
<(), Error
> {
62 let result
= proxmox
::try_block
!({
63 let mut handle
= get_tape_handle(device
)?
;
64 handle
.get_drive_and_media_status()
65 }).map_err(|err
: Error
| err
.to_string());
67 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
76 schema
: LINUX_DRIVE_PATH_SCHEMA
,
82 /// Read Cartridge Memory (Medium auxiliary memory attributes)
84 device
: Option
<String
>,
85 ) -> Result
<(), Error
> {
87 let result
= proxmox
::try_block
!({
88 let mut handle
= get_tape_handle(device
)?
;
90 handle
.cartridge_memory()
91 }).map_err(|err
| err
.to_string());
93 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
102 schema
: LINUX_DRIVE_PATH_SCHEMA
,
108 /// Read Tape Alert Flags
110 device
: Option
<String
>,
111 ) -> Result
<(), Error
> {
113 let result
= proxmox
::try_block
!({
114 let mut handle
= get_tape_handle(device
)?
;
116 let flags
= handle
.tape_alert_flags()?
;
118 }).map_err(|err
: Error
| err
.to_string());
120 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
129 schema
: LINUX_DRIVE_PATH_SCHEMA
,
135 /// Read volume statistics
136 fn volume_statistics(
137 device
: Option
<String
>,
138 ) -> Result
<(), Error
> {
140 let result
= proxmox
::try_block
!({
141 let mut handle
= get_tape_handle(device
)?
;
142 handle
.volume_statistics()
143 }).map_err(|err
: Error
| err
.to_string());
145 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
150 fn main() -> Result
<(), Error
> {
152 // check if we are user root or backup
153 let backup_uid
= proxmox_backup
::backup
::backup_user()?
.uid
;
154 let backup_gid
= proxmox_backup
::backup
::backup_group()?
.gid
;
155 let running_uid
= nix
::unistd
::Uid
::current();
156 let running_gid
= nix
::unistd
::Gid
::current();
158 let effective_uid
= nix
::unistd
::Uid
::effective();
159 if !effective_uid
.is_root() {
160 bail
!("this program needs to be run with setuid root");
163 if !running_uid
.is_root() {
164 if running_uid
!= backup_uid
|| running_gid
!= backup_gid
{
166 "Not running as backup user or group (got uid {} gid {})",
167 running_uid
, running_gid
,
172 let cmd_def
= CliCommandMap
::new()
175 CliCommand
::new(&API_METHOD_STATUS
)
179 CliCommand
::new(&API_METHOD_CARTRIDGE_MEMORY
)
183 CliCommand
::new(&API_METHOD_TAPE_ALERT_FLAGS
)
187 CliCommand
::new(&API_METHOD_VOLUME_STATISTICS
)
191 let mut rpcenv
= CliEnvironment
::new();
192 rpcenv
.set_auth_id(Some(String
::from("root@pam")));
194 run_cli_command(cmd_def
, rpcenv
, None
);