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
,
29 open_linux_tape_device
,
30 check_tape_is_linux_tape_device
,
35 fn get_tape_handle(device
: Option
<String
>) -> Result
<LinuxTapeHandle
, Error
> {
37 let file
= if let Some(device
) = device
{
38 open_linux_tape_device(&device
)?
40 let fd
= std
::io
::stdin().as_raw_fd();
41 let file
= unsafe { File::from_raw_fd(fd) }
;
42 check_tape_is_linux_tape_device(&file
)?
;
45 Ok(LinuxTapeHandle
::new(file
))
52 schema
: LINUX_DRIVE_PATH_SCHEMA
,
60 device
: Option
<String
>,
61 ) -> Result
<(), Error
> {
63 let result
= proxmox
::try_block
!({
64 let mut handle
= get_tape_handle(device
)?
;
65 handle
.get_drive_and_media_status()
66 }).map_err(|err
: Error
| err
.to_string());
68 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
77 schema
: LINUX_DRIVE_PATH_SCHEMA
,
83 /// Read Cartridge Memory (Medium auxiliary memory attributes)
85 device
: Option
<String
>,
86 ) -> Result
<(), Error
> {
88 let result
= proxmox
::try_block
!({
89 let mut handle
= get_tape_handle(device
)?
;
91 handle
.cartridge_memory()
92 }).map_err(|err
| err
.to_string());
94 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
103 schema
: LINUX_DRIVE_PATH_SCHEMA
,
109 /// Read Tape Alert Flags
111 device
: Option
<String
>,
112 ) -> Result
<(), Error
> {
114 let result
= proxmox
::try_block
!({
115 let mut handle
= get_tape_handle(device
)?
;
117 let flags
= handle
.tape_alert_flags()?
;
119 }).map_err(|err
: Error
| err
.to_string());
121 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
130 schema
: LINUX_DRIVE_PATH_SCHEMA
,
136 /// Read volume statistics
137 fn volume_statistics(
138 device
: Option
<String
>,
139 ) -> Result
<(), Error
> {
141 let result
= proxmox
::try_block
!({
142 let mut handle
= get_tape_handle(device
)?
;
143 handle
.volume_statistics()
144 }).map_err(|err
: Error
| err
.to_string());
146 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
151 fn main() -> Result
<(), Error
> {
153 // check if we are user root or backup
154 let backup_uid
= proxmox_backup
::backup
::backup_user()?
.uid
;
155 let backup_gid
= proxmox_backup
::backup
::backup_group()?
.gid
;
156 let running_uid
= nix
::unistd
::Uid
::current();
157 let running_gid
= nix
::unistd
::Gid
::current();
159 let effective_uid
= nix
::unistd
::Uid
::effective();
160 if !effective_uid
.is_root() {
161 bail
!("this program needs to be run with setuid root");
164 if !running_uid
.is_root() {
165 if running_uid
!= backup_uid
|| running_gid
!= backup_gid
{
167 "Not running as backup user or group (got uid {} gid {})",
168 running_uid
, running_gid
,
173 let cmd_def
= CliCommandMap
::new()
176 CliCommand
::new(&API_METHOD_STATUS
)
180 CliCommand
::new(&API_METHOD_CARTRIDGE_MEMORY
)
184 CliCommand
::new(&API_METHOD_TAPE_ALERT_FLAGS
)
188 CliCommand
::new(&API_METHOD_VOLUME_STATISTICS
)
192 let mut rpcenv
= CliEnvironment
::new();
193 rpcenv
.set_auth_id(Some(String
::from("root@pam")));
195 run_cli_command(cmd_def
, rpcenv
, None
);