Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Oleg Borisenko
tapebackup
Commits
e05467d0
Commit
e05467d0
authored
May 12, 2021
by
Oleg Borisenko
Browse files
fixed logics for grabbing new tape correctly
parent
537f092d
Changes
1
Hide whitespace changes
Inline
Side-by-side
tapebackup/utils/tapemanager.py
View file @
e05467d0
...
...
@@ -33,7 +33,7 @@ class TapeManager:
def
__init__
(
self
,
dbsession
):
self
.
changer_device
=
'/dev/sg4'
self
.
tape_drive_device
=
'/dev/sg3'
self
.
mkltfs_binary
=
'/usr/local/bin/mkltfs
'
self
.
mkltfs_binary
=
'/usr/local/bin/mkltfs'
# canonical mount "/usr/local/bin/ltfs /mnt/tape/ -o devname=/dev/sg3"
self
.
mountpoint
=
None
self
.
mountpoint_base
=
"/srv_mount_dont_go_here/tapes/"
...
...
@@ -57,9 +57,8 @@ class TapeManager:
return
label
,
is_data_tape
def
disk_usage
(
self
):
if
self
.
mountcheck
():
self
.
mountpoint
=
mountpoint
=
self
.
mountpoint_base
+
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
]
else
:
if
not
self
.
mountcheck
():
self
.
mountpoint
=
None
self
.
df
=
0
return
total
,
used
,
free
=
shutil
.
disk_usage
(
self
.
mountpoint
)
...
...
@@ -75,17 +74,24 @@ class TapeManager:
self
.
df
=
really_free
def
mountcheck
(
self
):
self
.
mountpoint
=
self
.
mountpoint_base
+
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
]
if
os
.
path
.
ismount
(
self
.
mountpoint
):
if
self
.
drives
[
0
].
get
(
self
.
PRIMARY_VOLUME_TAG
):
mountpoint
=
self
.
mountpoint_base
+
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
]
else
:
self
.
mountpoint
=
None
return
False
if
os
.
path
.
ismount
(
mountpoint
):
log
.
info
(
"Tape %s is mounted to %s"
%
(
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
],
mountpoint
))
self
.
mountpoint
=
mountpoint
return
True
else
:
self
.
mountpoint
=
None
return
False
# return true for successful mount, false for unsuccessful
def
mount
(
self
):
if
self
.
drive_state
!=
DriveState
.
data_tape_inside
:
raise
Exception
(
"Trying to mount without data tape inside"
)
# NOTE: caution, don't try to have here "self.mountpoint", it's illegal
mountpoint
=
self
.
mountpoint_base
+
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
]
mkdir_completed
=
subprocess
.
run
([
"mkdir"
,
"-p"
,
"-v"
,
mountpoint
],
capture_output
=
True
,
shell
=
False
)
if
mkdir_completed
.
returncode
!=
0
:
...
...
@@ -103,7 +109,11 @@ class TapeManager:
def
format
(
self
):
if
self
.
drive_state
!=
DriveState
.
data_tape_inside
:
raise
Exception
(
"Trying to mount without data tape inside"
)
mkltfs_completed
=
subprocess
.
run
([
self
.
mkltfs_binary
,
self
.
tape_drive_device
],
capture_output
=
True
,
shell
=
False
)
vol_name
=
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
]
mkltfs_completed
=
subprocess
.
run
([
self
.
mkltfs_binary
,
'-d'
,
self
.
tape_drive_device
,
'-n'
,
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
],
'--syslogtrace'
],
capture_output
=
True
,
shell
=
False
)
return
True
if
mkltfs_completed
.
returncode
==
0
else
False
def
finalize_tape
(
self
):
...
...
@@ -114,7 +124,7 @@ class TapeManager:
# Also checksumming process seems to take more time that rsync itself.
tape
=
self
.
identify_tape
()
tape
.
state
=
models
.
TapeState
.
finalized
pathlib
.
touc
h
(
self
.
mountpoint
+
"/finalized.txt"
)
pathlib
.
Pat
h
(
self
.
mountpoint
+
"/finalized.txt"
)
.
touch
()
log
.
info
(
"Finalized"
)
self
.
eject_current_tape_to_empty_magazine_slot
()
log
.
info
(
"Ejected to magazine"
)
...
...
@@ -146,8 +156,8 @@ class TapeManager:
# tape rotation mechanism
def
eject_current_tape_to_empty_magazine_slot
(
self
):
if
self
.
mountcheck
():
mountpoint
=
"/srv_mount_dont_go_here/tapes/"
+
self
.
drives
[
0
][
self
.
PRIMARY_VOLUME_TAG
]
umount_completed
=
subprocess
.
run
([
self
.
umount_command
,
mountpoint
],
capture_output
=
True
,
shell
=
False
)
log
.
info
(
"Tape is mounted; need to unmount first"
)
umount_completed
=
subprocess
.
run
([
self
.
umount_command
,
self
.
mountpoint
],
capture_output
=
True
,
shell
=
False
)
if
umount_completed
.
returncode
:
raise
Exception
(
"Failed to unmount => can not move tape. Try again when tape is not used."
)
else
:
...
...
@@ -159,6 +169,7 @@ class TapeManager:
raise
Exception
(
"No available slots in magazine; it's critical to have exactly 35 tapes in magazines!"
)
else
:
self
.
eject_to
(
empty_slot
)
self
.
scan
()
# Scan for data tape slots
def
scan_drives
(
self
,
device
,
element_address_assignment
):
...
...
@@ -285,6 +296,8 @@ class TapeManager:
log
.
info
(
"Tape is already in drive"
)
return
device
=
SCSI
(
init_device
(
self
.
changer_device
))
if
self
.
drives
[
0
][
'full'
]:
self
.
eject_current_tape_to_empty_magazine_slot
()
device
.
movemedium
(
self
.
robot
[
0
][
'element_address'
],
slot
,
self
.
drives
[
0
][
'element_address'
])
log
.
info
(
"Moving tape from slot %d to drive"
,
slot
)
return
...
...
@@ -296,6 +309,7 @@ class TapeManager:
raise
Exception
(
"Drive is empty; nothing to eject."
)
# umount is **obligatory**, otherwise it hangs to death
movemedium
=
device
.
movemedium
(
self
.
robot
[
0
][
'element_address'
],
self
.
drives
[
0
][
'element_address'
],
slot
)
log
.
info
(
"Moved tape from %d to slot %d"
,
self
.
drives
[
0
][
'element_address'
],
slot
)
return
movemedium
def
get_drive_state
(
self
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment