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
,
24 LinuxDriveAndMediaStatus
,
27 mam_extract_media_usage
,
30 open_linux_tape_device
,
31 check_tape_is_linux_tape_device
,
36 fn get_tape_handle(device
: Option
<String
>) -> Result
<LinuxTapeHandle
, Error
> {
38 let file
= if let Some(device
) = device
{
39 open_linux_tape_device(&device
)?
41 let fd
= std
::io
::stdin().as_raw_fd();
42 let file
= unsafe { File::from_raw_fd(fd) }
;
43 check_tape_is_linux_tape_device(&file
)?
;
46 Ok(LinuxTapeHandle
::new(file
))
53 schema
: LINUX_DRIVE_PATH_SCHEMA
,
61 device
: Option
<String
>,
62 ) -> Result
<(), Error
> {
64 let result
= proxmox
::try_block
!({
65 let mut handle
= get_tape_handle(device
)?
;
67 let drive_status
= handle
.get_drive_status()?
;
69 let mam
= handle
.cartridge_memory()?
;
71 let usage
= mam_extract_media_usage(&mam
)?
;
73 Ok(LinuxDriveAndMediaStatus
{
74 blocksize
: drive_status
.blocksize
,
75 density
: drive_status
.density
,
76 status
: format
!("{:?}", drive_status
.status
),
77 file_number
: drive_status
.file_number
,
78 block_number
: drive_status
.block_number
,
79 manufactured
: usage
.manufactured
,
80 bytes_read
: usage
.bytes_read
,
81 bytes_written
: usage
.bytes_written
,
83 }).map_err(|err
: Error
| err
.to_string());
85 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
94 schema
: LINUX_DRIVE_PATH_SCHEMA
,
100 /// Read Cartridge Memory (Medium auxiliary memory attributes)
102 device
: Option
<String
>,
103 ) -> Result
<(), Error
> {
105 let result
= proxmox
::try_block
!({
106 let mut handle
= get_tape_handle(device
)?
;
108 handle
.cartridge_memory()
109 }).map_err(|err
| err
.to_string());
111 println
!("{}", serde_json
::to_string_pretty(&result
)?
);
116 fn main() -> Result
<(), Error
> {
118 // check if we are user root or backup
119 let backup_uid
= proxmox_backup
::backup
::backup_user()?
.uid
;
120 let backup_gid
= proxmox_backup
::backup
::backup_group()?
.gid
;
121 let running_uid
= nix
::unistd
::Uid
::current();
122 let running_gid
= nix
::unistd
::Gid
::current();
124 let effective_uid
= nix
::unistd
::Uid
::effective();
125 if !effective_uid
.is_root() {
126 bail
!("this program needs to be run with setuid root");
129 if !running_uid
.is_root() {
130 if running_uid
!= backup_uid
|| running_gid
!= backup_gid
{
132 "Not running as backup user or group (got uid {} gid {})",
133 running_uid
, running_gid
,
138 let cmd_def
= CliCommandMap
::new()
141 CliCommand
::new(&API_METHOD_STATUS
)
145 CliCommand
::new(&API_METHOD_CARTRIDGE_MEMORY
)
149 let mut rpcenv
= CliEnvironment
::new();
150 rpcenv
.set_auth_id(Some(String
::from("root@pam")));
152 run_cli_command(cmd_def
, rpcenv
, None
);