diff options
author | Sven Hartge <Sven Hartge sven@svenhartge.de> | 2018-08-09 09:26:31 +0200 |
---|---|---|
committer | Sven Hartge <Sven Hartge sven@svenhartge.de> | 2018-08-09 09:26:31 +0200 |
commit | 80bafa66a1f92981132922c65a103b14e2b016ad (patch) | |
tree | 73beef9812889e4b664211325439c3972544221c /scripts | |
parent | 038694b727cf1cc2222d3054e85828d7af27e320 (diff) |
New upstream version 9.2.0
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/Makefile.in | 4 | ||||
-rw-r--r-- | scripts/bacula-ctl-sd.in | 3 | ||||
-rwxr-xr-x | scripts/bacula.in | 2 | ||||
-rw-r--r-- | scripts/dvd-handler.in | 515 | ||||
-rw-r--r-- | scripts/dvd-simulator.in | 476 |
5 files changed, 5 insertions, 995 deletions
diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 4eb2478a..40ad3e67 100755 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -50,9 +50,9 @@ install: installdirs $(INSTALL_SCRIPT) mtx-changer $(DESTDIR)$(scriptdir)/mtx-changer @if test -f ${DESTDIR}${scriptdir}/mtx-changer.conf; then \ echo " ==> Installing mtx-changer.conf to mtx-changer.conf.new"; \ - $(INSTALL_SCRIPT) mtx-changer.conf $(DESTDIR)$(scriptdir)/mtx-changer.conf.new; \ + $(INSTALL_DATA) mtx-changer.conf $(DESTDIR)$(scriptdir)/mtx-changer.conf.new; \ else \ - $(INSTALL_SCRIPT) mtx-changer.conf $(DESTDIR)$(scriptdir)/mtx-changer.conf; \ + $(INSTALL_DATA) mtx-changer.conf $(DESTDIR)$(scriptdir)/mtx-changer.conf; \ fi @if test -f ${DESTDIR}${scriptdir}/disk-changer; then \ echo " ==> Saving existing disk-changer to disk-changer.old"; \ diff --git a/scripts/bacula-ctl-sd.in b/scripts/bacula-ctl-sd.in index f545cd63..2c247967 100644 --- a/scripts/bacula-ctl-sd.in +++ b/scripts/bacula-ctl-sd.in @@ -2,7 +2,7 @@ # # Bacula(R) - The Network Backup Solution # -# Copyright (C) 2000-2016 Kern Sibbald +# Copyright (C) 2000-2018 Kern Sibbald # # The original author of Bacula is Kern Sibbald, with contributions # from many others, a complete list can be found in the file AUTHORS. @@ -225,6 +225,7 @@ case "$1" in OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi + ulimit -l unlimited > /dev/null 2> /dev/null || true if [ "x${VALGRIND_SD}" = "x1" ]; then valgrind --leak-check=full ${BACSDBIN}/bacula-sd $2 $3 ${OPTIONS} -v -c ${BACSDCFG}/bacula-sd.conf else diff --git a/scripts/bacula.in b/scripts/bacula.in index cadfa655..acefe0dc 100755 --- a/scripts/bacula.in +++ b/scripts/bacula.in @@ -2,7 +2,7 @@ # # Bacula(R) - The Network Backup Solution # -# Copyright (C) 2000-2016 Kern Sibbald +# Copyright (C) 2000-2018 Kern Sibbald # # The original author of Bacula is Kern Sibbald, with contributions # from many others, a complete list can be found in the file AUTHORS. diff --git a/scripts/dvd-handler.in b/scripts/dvd-handler.in deleted file mode 100644 index 2d2bcf15..00000000 --- a/scripts/dvd-handler.in +++ /dev/null @@ -1,515 +0,0 @@ -#!@PYTHON@ -# -# Bacula(R) - The Network Backup Solution -# -# Copyright (C) 2000-2016 Kern Sibbald -# -# The original author of Bacula is Kern Sibbald, with contributions -# from many others, a complete list can be found in the file AUTHORS. -# -# You may use this file and others of this release according to the -# license defined in the LICENSE file, which includes the Affero General -# Public License, v3.0 ("AGPLv3") and some additional permissions and -# terms pursuant to its AGPLv3 Section 7. -# -# This notice must be preserved when any source code is -# conveyed and/or propagated. -# -# Bacula(R) is a registered trademark of Kern Sibbald. -# -# Check the free space available on a writable DVD -# Should always exit with 0 status, otherwise it indicates a serious error. -# (wrong number of arguments, Python exception...) -# -# called: dvd-handler <dvd-device-name> operation args -# -# operations used by Bacula: -# -# free (no arguments) -# Scan the device and report the available space. It returns: -# Prints on the first output line the free space available in bytes. -# If an error occurs, prints a negative number (-errno), followed, -# on the second line, by an error message. -# -# write op filename -# Write a part file to disk. -# This operation needs two additional arguments. -# The first (op) indicates to -# 0 -- append -# 1 -- first write to a blank disk -# 2 -- blank or truncate a disk -# -# The second is the filename to write -# -# operations available but not used by Bacula: -# -# test Scan the device and report the information found. -# This operation needs no further arguments. -# prepare Prepare a DVD+/-RW for being used by Bacula. -# Note: This is only useful if you already have some -# non-Bacula data on a medium, and you want to use -# it with Bacula. Don't run this on blank media, it -# is useless. -# -# -# $Id$ -# - -import popen2 -import os -import os.path -import errno -import sys -import re -import signal -import time -import array - -class disk: -# Configurable values: - - dvdrwmediainfo = "@DVDRWMEDIAINFO@" - growcmd = "@GROWISOFS@" - dvdrwformat = "@DVDRWFORMAT@" - dd = "@DD@" - margin = 10485760 # 10 mb security margin - - # Comment the following line if you want the tray to be reloaded - # when writing ends. - growcmd += " -use-the-force-luke=notray" - -# end of configurable values - -############################################################################### -# -# This class represents DVD disk informations. -# When instantiated, it needs a device name. -# Status information about the device and the disk loaded is collected only when -# asked for (for example dvd-freespace doesn't need to know the media type, and -# dvd-writepart doesn't not always need to know the free space). -# -# The following methods are implemented: -# __init__ we need that... -# __repr__ this seems to be a good idea to have. -# Quite minimalistic implementation, though. -# __str__ For casts to string. Return the current disk information -# is_empty Returns TRUE if the disk is empty, blank... this needs more -# work, especially concerning non-RW media and blank vs. no -# filesystem considerations. Here, we should also look for -# other filesystems - probably we don't want to silently -# overwrite UDF or ext2 or anything not mentioned in fstab... -# (NB: I don't think it is a problem) -# free Returns the available free space. -# write Writes one part file to disk, either starting a new file -# system on disk, or appending to it. -# This method should also prepare a blank disk so that a -# certain part of the disk is used to allow detection of a -# used disk by all / more disk drives. -# prepare Blank the device -# -############################################################################### - def __init__(self, devicename): - self.device = devicename - self.disktype = "none" - self.diskmode = "none" - self.diskstatus = "none" - self.hardwaredevice = "none" - self.pid = 0 - self.next_session = -1 - self.capacity = -1 - - self.freespace_collected = 0 - self.mediumtype_collected = 0 - - self.growcmd += " -quiet" - - if self.is4gbsupported(): - self.growcmd += " -use-the-force-luke=4gms" - - self.growparams = " -A 'Bacula Data' -input-charset=default -iso-level 3 -pad " + \ - "-p 'dvd-handler / growisofs' -sysid 'BACULADATA' -R" - - return - - def __repr__(self): - return "disk(" + self.device + ") # This is an instance of class disk" - - def __str__(self): - if not self.freespace_collected: - self.collect_freespace(); - if not self.mediumtype_collected: - self.collect_mediumtype(); - - self.me = "Class disk, initialized with device '" + self.device + "'\n" - self.me += "type = '" + self.disktype + "' mode='" + self.diskmode + "' status = '" + self.diskstatus + "'\n" - self.me += " next_session = " + str(self.next_session) + " capacity = " + str(self.capacity) + "\n" - self.me += "Hardware device is '" + self.hardwaredevice + "'\n" - self.me += "growcmd = '" + self.growcmd + "'\ngrowparams = '" + self.growparams + "'\n" - return self.me - - ## Check if we want to allow growisofs to cross the 4gb boundary - def is4gbsupported(self): - processi = popen2.Popen4("uname -s -r") - status = processi.wait() - if not os.WIFEXITED(status): - return 1 - if os.WEXITSTATUS(status) != 0: - return 1 - strres = processi.fromchild.readline()[0:-1] - version = re.search(r"Linux (\d+)\.(\d+)\.(\d+)", strres) - if not version: # Non-Linux: allow - return 1 - - if (int(version.group(1)) > 2) or (int(version.group(2)) > 6) or ((int(version.group(1)) == 2) and (int(version.group(2)) == 6) and (int(version.group(3)) >= 8)): - return 1 - else: - return 0 - - def collect_freespace(self): # Collects current free space - self.cmd = self.growcmd + " -F " + self.device - processi = popen2.Popen4(self.cmd) - status = processi.wait() - if not os.WIFEXITED(status): - raise DVDError(0, "growisofs process did not exit correctly.") - result = processi.fromchild.read() - if os.WEXITSTATUS(status) != 0: - if (os.WEXITSTATUS(status) & 0x7F) == errno.ENOSPC: - # Kludge to force dvd-handler to return a free space of 0 - self.next_session = 1 - self.capacity = 1 - self.freespace_collected = 1 - return - else: - raise DVDError(os.WEXITSTATUS(status), "growisofs returned with an error " + result + ". Please check your are using a patched version of dvd+rw-tools.") - next_sess = re.search(r"\snext_session=(\d+)\s", result, re.MULTILINE) - capa = re.search(r"\scapacity=(\d+)\s", result, re.MULTILINE) - - if next_sess and capa: - self.next_session = long(next_sess.group(1)) - self.capacity = long(capa.group(1)) - - # testing cheat (emulate 4GB boundary at 100MB) - #if self.next_session > 100000000: - # self.capacity = self.next_session - else: - raise DVDError(0, "Cannot get next_session and capacity from growisofs.\nReturned: " + result) - - self.freespace_collected = 1 - return - - def collect_mediumtype(self): # Collects current medium type - self.lasterror = "" - cmd = self.dvdrwmediainfo + " " + self.device - processi = popen2.Popen4(cmd) - status = processi.wait() - if not os.WIFEXITED(status): - raise DVDError(0, self.dvdrwmediainfo + " process did not exit correctly.") - if os.WEXITSTATUS(status) != 0: - raise DVDError(0, "Cannot get media info from " + self.dvdrwmediainfo) - return - result = processi.fromchild.read() - - hardware = re.search(r"INQUIRY:\s+(.*)\n", result, re.MULTILINE) - mediatype = re.search(r"\sMounted Media:\s+([0-9A-F]{2})h, (\S*)\s", result, re.MULTILINE) - mediamode = re.search(r"\sMounted Media:\s+[0-9A-F]{2}h, \S* (.*)\n", result, re.MULTILINE) - status = re.search(r"\sDisc status:\s+(.*)\n", result, re.MULTILINE) - - if hardware: - self.hardwaredevice = hardware.group(1) - - if mediatype: - self.disktype = mediatype.group(2) - else: - raise DVDError(0, "Media type not found in " + self.dvdrwmediainfo + " output") - - if self.disktype == "DVD-RW": - if mediamode: - self.diskmode = mediamode.group(1) - else: - raise DVDError(0, "Media mode not found for DVD-RW in " + self.dvdrwmediainfo + " output") - - if status: - self.diskstatus = status.group(1) - else: - raise DVDError(0, "Disc status not found in " + self.dvdrwmediainfo + " output") - - - self.mediumtype_collected = 1 - return - - def is_empty(self): - if not self.freespace_collected: - self.collect_freespace(); - - return 0 == self.next_session - - def is_RW(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return "DVD-RW" == self.disktype or "DVD+RW" == self.disktype or "DVD-RAM" == self.disktype - - def is_plus_RW(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return "DVD+RW" == self.disktype - - def is_minus_RW(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return "DVD-RW" == self.disktype - - def is_restricted_overwrite(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return self.diskmode == "Restricted Overwrite" - - def is_blank(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - - return self.diskstatus == "blank" - - def free(self): - if not self.freespace_collected: - self.collect_freespace(); - - fr = self.capacity-self.next_session-self.margin - if fr < 0: - return 0 - else: - return fr - - def term_handler(self, signum, frame): - print 'dvd-handler: Signal term_handler called with signal', signum - if self.pid != 0: - print "dvd-handler: Sending SIGTERM to pid", self.pid - os.kill(self.pid, signal.SIGTERM) - time.sleep(10) - print "dvd-handler: Sending SIGKILL to pid", self.pid - os.kill(self.pid, signal.SIGKILL) - sys.exit(1) - - def write(self, newvol, partfile): - # Blank DVD+RW when there is no data on it - if newvol and self.is_plus_RW() and self.is_blank(): - print "DVD+RW looks brand-new, blank it to fix some DVD-writers bugs." - self.blank() - print "Done, now writing the part file." - - if newvol and self.is_minus_RW() and (not self.is_restricted_overwrite()): - print "DVD-RW is in " + self.diskmode + " mode, reformating it to Restricted Overwrite" - self.reformat_minus_RW() - print "Done, now writing the part file." - - cmd = self.growcmd + self.growparams - if newvol: - # Ignore any existing iso9660 filesystem - used for truncate - if newvol == 2: - cmd += " -use-the-force-luke=tty" - cmd += " -Z " - else: - cmd += " -M " - cmd += self.device + " " + str(partfile) - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if not os.WIFEXITED(status): - raise DVDError(0, cmd + " process did not exit correctly, signal/status " + str(status)) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - - def prepare(self): - if not self.is_RW(): - raise DVDError(0, "I won't prepare a non-rewritable medium") - - # Blank DVD+RW when there is no data on it - if self.is_plus_RW() and self.is_blank(): - print "DVD+RW looks brand-new, blank it to fix some DVD-writers bugs." - self.blank() - return # It has been completely blanked: Medium is ready to be used by Bacula - - if self.is_minus_RW() and (not self.is_restricted_overwrite()): - print "DVD-RW is in " + self.diskmode + " mode, reformating it to Restricted Overwrite" - self.reformat_minus_RW() - return # Reformated: Medium is ready to be used by Bacula - - # TODO: Check if /dev/fd/0 and /dev/zero exists, otherwise, run self.blank() - if not os.path.exists("/dev/fd/0") or not os.path.exists("/dev/zero"): - print "/dev/fd/0 or /dev/zero doesn't exist, blank the medium completely." - self.blank() - return - - cmd = self.dd + " if=/dev/zero bs=1024 count=512 | " + self.growcmd + " -Z " + self.device + "=/dev/fd/0" - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - - def blank(self): - cmd = self.growcmd + " -Z " + self.device + "=/dev/zero" - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - - def reformat_minus_RW(self): - cmd = self.dvdrwformat + " -force " + self.device - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - -# class disk ends here. - -class DVDError(Exception): - def __init__(self, errno, value): - self.errno = errno - self.value = value - if self.value[-1] == '\n': - self.value = self.value[0:-1] - def __str__(self): - return str(self.value) + " || errno = " + str(self.errno) + " (" + os.strerror(self.errno & 0x7F) + ")" - -def usage(): - print "Wrong number of arguments." - print """ -Usage: - -dvd-handler DEVICE test -dvd-handler DEVICE free -dvd-handler DEVICE write APPEND FILE -dvd-handler DEVICE prepare - -where DEVICE is a device name like /dev/sr0 or /dev/dvd. - -Operations: -test Scan the device and report the information found. - This operation needs no further arguments. -free Scan the device and report the available space. -write Write a part file to disk. - This operation needs two additional arguments. - The first indicates to append (0), restart the - disk (1) or restart existing disk (2). The second - is the file to write. -prepare Prepare a DVD+/-RW for being used by Bacula. - Note: This is only useful if you already have some - non-Bacula data on a medium, and you want to use - it with Bacula. Don't run this on blank media, it - is useless. -""" - sys.exit(1) - -if len(sys.argv) < 3: - usage() - -dvd = disk(sys.argv[1]) - -if "free" == sys.argv[2]: - if len(sys.argv) == 3: - try: - free = dvd.free() - except DVDError, e: - if e.errno != 0: - print -e.errno - else: - print errno.EPIPE - print str(e) - else: - print free - print "No Error reported." - else: - print "Wrong number of arguments for free operation. Wanted 3 got", len(sys.argv) - usage() -elif "prepare" == sys.argv[2]: - if len(sys.argv) == 3: - try: - dvd.prepare() - except DVDError, e: - print "Error while preparing medium: ", str(e) - if e.errno != 0: - sys.exit(e.errno & 0x7F) - else: - sys.exit(errno.EPIPE) - else: - print "Medium prepared successfully." - else: - print "Wrong number of arguments for prepare operation. Wanted 3 got", len(sys.argv) - usage() -elif "test" == sys.argv[2]: - try: - print str(dvd) - print "Blank disk: " + str(dvd.is_blank()) + " ReWritable disk: " + str(dvd.is_RW()) - print "Free space: " + str(dvd.free()) - except DVDError, e: - print "Error while getting informations: ", str(e) -elif "write" == sys.argv[2]: - if len(sys.argv) == 5: - try: - dvd.write(long(sys.argv[3]), sys.argv[4]) - except DVDError, e: - print "Error while writing part file: ", str(e) - if e.errno != 0: - sys.exit(e.errno & 0x7F) - else: - sys.exit(errno.EPIPE) - else: - print "Part file " + sys.argv[4] + " successfully written to disk." - else: - print "Wrong number of arguments for write operation. Wanted 5 got", len(sys.argv) - usage() - sys.exit(1) -else: - print "No operation - use test, free, prepare or write." - print "THIS MIGHT BE A CASE OF DEBUGGING BACULA OR AN ERROR!" -sys.exit(0) diff --git a/scripts/dvd-simulator.in b/scripts/dvd-simulator.in deleted file mode 100644 index 75bc5d2d..00000000 --- a/scripts/dvd-simulator.in +++ /dev/null @@ -1,476 +0,0 @@ -#!@PYTHON@ -# -# Bacula(R) - The Network Backup Solution -# -# Copyright (C) 2000-2016 Kern Sibbald -# -# The original author of Bacula is Kern Sibbald, with contributions -# from many others, a complete list can be found in the file AUTHORS. -# -# You may use this file and others of this release according to the -# license defined in the LICENSE file, which includes the Affero General -# Public License, v3.0 ("AGPLv3") and some additional permissions and -# terms pursuant to its AGPLv3 Section 7. -# -# This notice must be preserved when any source code is -# conveyed and/or propagated. -# -# Bacula(R) is a registered trademark of Kern Sibbald. -# -# Modified version of dvd-handler used to simulate reading/writing -# to a DVD but using disk storage. This is a pretty crude implementation -# and a lot of the old code is still here and just sort of blunders -# along. -# -# called: dvd-simulator <dvd-device-name> operation args -# -# operations used by Bacula: -# -# free (no arguments) -# Scan the device and report the available space. -# -# write op filename -# Write a part file to disk. -# This operation needs two additional arguments. -# The first (op) indicates to -# 0 -- append -# 1 -- first write to a blank disk -# 2 -- blank or truncate a disk -# -# The second is the filename to write -# -# operations available but not used by Bacula: -# -# test Scan the device and report the information found. -# This operation needs no further arguments. -# prepare Prepare a DVD+/-RW for being used by Bacula. -# Note: This is only useful if you already have some -# non-Bacula data on a medium, and you want to use -# it with Bacula. Don't run this on blank media, it -# is useless. -# -# -# in case of operation ``free'' returns: -# Prints on the first output line the free space available in bytes. -# If an error occurs, prints a negative number (-errno), followed, -# on the second line, by an error message. -# - -import popen2 -import os -import os.path -import shutil -import errno -import sys -import re -import signal -import time -import array - -class disk: -# Configurable values: - - dvdrwmediainfo = "@DVDRWMEDIAINFO@" - growcmd = "@GROWISOFS@" - dvdrwformat = "@DVDRWFORMAT@" - dd = "@DD@" - margin = 10485760 # 10 mb security margin - - # Comment the following line if you want the tray to be reloaded - # when writing ends. - growcmd += " -use-the-force-luke=notray" - -# end of configurable values - -############################################################################### -# -# This class represents DVD disk informations. -# When instantiated, it needs a device name. -# Status information about the device and the disk loaded is collected only when -# asked for (for example dvd-freespace doesn't need to know the media type, and -# dvd-writepart doesn't not always need to know the free space). -# -# The following methods are implemented: -# __init__ we need that... -# __repr__ this seems to be a good idea to have. -# Quite minimalistic implementation, though. -# __str__ For casts to string. Return the current disk information -# is_empty Returns TRUE if the disk is empty, blank... this needs more -# work, especially concerning non-RW media and blank vs. no -# filesystem considerations. Here, we should also look for -# other filesystems - probably we don't want to silently -# overwrite UDF or ext2 or anything not mentioned in fstab... -# (NB: I don't think it is a problem) -# free Returns the available free space. -# write Writes one part file to disk, either starting a new file -# system on disk, or appending to it. -# This method should also prepare a blank disk so that a -# certain part of the disk is used to allow detection of a -# used disk by all / more disk drives. -# blank Blank the device -# -############################################################################### - def __init__(self, devicename): - self.device = devicename - self.disktype = "none" - self.diskmode = "none" - self.diskstatus = "none" - self.hardwaredevice = "none" - self.pid = 0 - self.next_session = -1 - self.capacity = -1 - self.maxcapacity = 4000000000 - - self.freespace_collected = 0 - self.mediumtype_collected = 0 - - self.growcmd += " -quiet" - - if self.is4gbsupported(): - self.growcmd += " -use-the-force-luke=4gms" - - self.growparams = " -A 'Bacula Data' -input-charset=default -iso-level 3 -pad " + \ - "-p 'dvd-handler / growisofs' -sysid 'BACULADATA' -R" - - return - - def __repr__(self): - return "disk(" + self.device + ") # This is an instance of class disk" - - def __str__(self): - if not self.freespace_collected: - self.collect_freespace(); - if not self.mediumtype_collected: - self.collect_mediumtype(); - - self.me = "Class disk, initialized with device '" + self.device + "'\n" - self.me += "type = '" + self.disktype + "' mode='" + self.diskmode + "' status = '" + self.diskstatus + "'\n" - self.me += " next_session = " + str(self.next_session) + " capacity = " + str(self.capacity) + "\n" - self.me += "Hardware device is '" + self.hardwaredevice + "'\n" - self.me += "growcmd = '" + self.growcmd + "'\ngrowparams = '" + self.growparams + "'\n" - return self.me - - ## Check if we want to allow growisofs to cross the 4gb boundary - def is4gbsupported(self): - processi = popen2.Popen4("uname -s -r") - status = processi.wait() - if not os.WIFEXITED(status): - return 1 - if os.WEXITSTATUS(status) != 0: - return 1 - strres = processi.fromchild.readline()[0:-1] - version = re.search(r"Linux (\d+)\.(\d+)\.(\d+)", strres) - if not version: # Non-Linux: allow - return 1 - - if (int(version.group(1)) > 2) or (int(version.group(2)) > 6) or ((int(version.group(1)) == 2) and (int(version.group(2)) == 6) and (int(version.group(3)) >= 8)): - return 1 - else: - return 0 - - def collect_freespace(self): # Collects current free space - self.next_session = 0 - self.capacity = 4000000000 - self.freespace_collected = 1 - - cmd = "du -sb " + self.device - processi = popen2.Popen4(cmd) - status = processi.wait() - if not os.WIFEXITED(status): - return 1; - if os.WEXITSTATUS(status) != 0: - return 1; - result = processi.fromchild.read() - - used = re.search(r"(\d+)\s", result, re.MULTILINE) - - self.capacity = self.maxcapacity - long(used.group(1)) - if self.capacity < 0: - self.capacity = 0 - - return 0 - - def collect_mediumtype(self): # Collects current medium type - self.lasterror = "" - cmd = self.dvdrwmediainfo + " " + self.device - processi = popen2.Popen4(cmd) - status = processi.wait() - if not os.WIFEXITED(status): - raise DVDError(0, self.dvdrwmediainfo + " process did not exit correctly.") - if os.WEXITSTATUS(status) != 0: - raise DVDError(0, "Cannot get media info from " + self.dvdrwmediainfo) - return - result = processi.fromchild.read() - - hardware = re.search(r"INQUIRY:\s+(.*)\n", result, re.MULTILINE) - mediatype = re.search(r"\sMounted Media:\s+([0-9A-F]{2})h, (\S*)\s", result, re.MULTILINE) - mediamode = re.search(r"\sMounted Media:\s+[0-9A-F]{2}h, \S* (.*)\n", result, re.MULTILINE) - status = re.search(r"\sDisc status:\s+(.*)\n", result, re.MULTILINE) - - if hardware: - self.hardwaredevice = hardware.group(1) - - if mediatype: - self.disktype = mediatype.group(2) - else: - raise DVDError(0, "Media type not found in " + self.dvdrwmediainfo + " output") - - if self.disktype == "DVD-RW": - if mediamode: - self.diskmode = mediamode.group(1) - else: - raise DVDError(0, "Media mode not found for DVD-RW in " + self.dvdrwmediainfo + " output") - - if status: - self.diskstatus = status.group(1) - else: - raise DVDError(0, "Disc status not found in " + self.dvdrwmediainfo + " output") - - - self.mediumtype_collected = 1 - return - - def is_empty(self): - if not self.freespace_collected: - self.collect_freespace(); - - return 0 == self.next_session - - def is_RW(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return "DVD-RW" == self.disktype or "DVD+RW" == self.disktype or "DVD-RAM" == self.disktype - - def is_plus_RW(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return "DVD+RW" == self.disktype - - def is_minus_RW(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return "DVD-RW" == self.disktype - - def is_restricted_overwrite(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - return self.diskmode == "Restricted Overwrite" - - def is_blank(self): - if not self.mediumtype_collected: - self.collect_mediumtype(); - - return self.diskstatus == "blank" - - def free(self): - if not self.freespace_collected: - self.collect_freespace(); - - fr = self.capacity-self.next_session-self.margin - if fr < 0: - return 0 - else: - return fr - - def term_handler(self, signum, frame): - print 'dvd-handler: Signal term_handler called with signal', signum - if self.pid != 0: - print "dvd-handler: Sending SIGTERM to pid", self.pid - os.kill(self.pid, signal.SIGTERM) - time.sleep(10) - print "dvd-handler: Sending SIGKILL to pid", self.pid - os.kill(self.pid, signal.SIGKILL) - sys.exit(1) - - def write(self, newvol, partfile): - if newvol: - print "Newvol", newvol - print "Zap everything ..." - os.system("rm -f "+self.device+"/*") - print "cp", partfile, self.device - shutil.copy(partfile,self.device) - - def prepare(self): - if not self.is_RW(): - raise DVDError(0, "I won't prepare a non-rewritable medium") - - # Blank DVD+RW when there is no data on it - if self.is_plus_RW() and self.is_blank(): - print "DVD+RW looks brand-new, blank it to fix some DVD-writers bugs." - self.blank() - return # It has been completely blanked: Medium is ready to be used by Bacula - - if self.is_minus_RW() and (not self.is_restricted_overwrite()): - print "DVD-RW is in " + self.diskmode + " mode, reformating it to Restricted Overwrite" - self.reformat_minus_RW() - return # Reformated: Medium is ready to be used by Bacula - - # TODO: Check if /dev/fd/0 and /dev/zero exists, otherwise, run self.blank() - if not os.path.exists("/dev/fd/0") or not os.path.exists("/dev/zero"): - print "/dev/fd/0 or /dev/zero doesn't exist, blank the medium completely." - self.blank() - return - - cmd = self.dd + " if=/dev/zero bs=1024 count=512 | " + self.growcmd + " -Z " + self.device + "=/dev/fd/0" - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - - def blank(self): - cmd = self.growcmd + " -Z " + self.device + "=/dev/zero" - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - - def reformat_minus_RW(self): - cmd = self.dvdrwformat + " -force " + self.device - print "Running " + cmd - oldsig = signal.signal(signal.SIGTERM, self.term_handler) - proc = popen2.Popen4(cmd) - self.pid = proc.pid - status = proc.poll() - while status == -1: - line = proc.fromchild.readline() - while len(line) > 0: - print line, - line = proc.fromchild.readline() - time.sleep(1) - status = proc.poll() - self.pid = 0 - print - signal.signal(signal.SIGTERM, oldsig) - if os.WEXITSTATUS(status) != 0: - raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) - -# class disk ends here. - -class DVDError(Exception): - def __init__(self, errno, value): - self.errno = errno - self.value = value - if self.value[-1] == '\n': - self.value = self.value[0:-1] - def __str__(self): - return str(self.value) + " || errno = " + str(self.errno) + " (" + os.strerror(self.errno & 0x7F) + ")" - -def usage(): - print "Wrong number of arguments." - print """ -Usage: - -dvd-handler DEVICE test -dvd-handler DEVICE free -dvd-handler DEVICE write APPEND FILE -dvd-handler DEVICE blank - -where DEVICE is a device name like /dev/sr0 or /dev/dvd. - -Operations: -test Scan the device and report the information found. - This operation needs no further arguments. -free Scan the device and report the available space. -write Write a part file to disk. - This operation needs two additional arguments. - The first indicates to append (0), restart the - disk (1) or restart existing disk (2). The second - is the file to write. -prepare Prepare a DVD+/-RW for being used by Bacula. - Note: This is only useful if you already have some - non-Bacula data on a medium, and you want to use - it with Bacula. Don't run this on blank media, it - is useless. -""" - sys.exit(1) - -if len(sys.argv) < 3: - usage() - -dvd = disk(sys.argv[1]) - -if "free" == sys.argv[2]: - if len(sys.argv) == 3: - try: - free = dvd.free() - except DVDError, e: - if e.errno != 0: - print -e.errno - else: - print errno.EPIPE - print str(e) - else: - print free - print "No Error reported." - else: - print "Wrong number of arguments for free operation. Wanted 3 got", len(sys.argv) - print sys.argv[1], sys.argv[2], sys.argv[3] - usage() -elif "prepare" == sys.argv[2]: - if len(sys.argv) == 3: - try: - dvd.prepare() - except DVDError, e: - print "Error while preparing medium: ", str(e) - if e.errno != 0: - sys.exit(e.errno & 0x7F) - else: - sys.exit(errno.EPIPE) - else: - print "Medium prepared successfully." - else: - print "Wrong number of arguments for prepare operation." - usage() -elif "test" == sys.argv[2]: - try: - print str(dvd) - print "Blank disk: " + str(dvd.is_blank()) + " ReWritable disk: " + str(dvd.is_RW()) - print "Free space: " + str(dvd.free()) - except DVDError, e: - print "Error while getting informations: ", str(e) -elif "write" == sys.argv[2]: - if len(sys.argv) == 5: - try: - dvd.write(long(sys.argv[3]), sys.argv[4]) - except DVDError, e: - print "Error while writing part file: ", str(e) - if e.errno != 0: - sys.exit(e.errno & 0x7F) - else: - sys.exit(errno.EPIPE) - else: - print "Part file " + sys.argv[4] + " successfully written to disk." - else: - print "Wrong number of arguments for write operation." - usage() - sys.exit(1) -else: - print "No operation - use test, free, prepare or write." - print "THIS MIGHT BE A CASE OF DEBUGGING BACULA OR AN ERROR!" -sys.exit(0) |