Initial commit

This commit is contained in:
Joe S 2020-05-29 04:59:02 -04:00
commit f4dbd012b7
56 changed files with 6049 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

BIN
Cleaning Tape Label.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,51 @@
#
# Bacula barcode simulation file
# used by ${PREFIX}/sbin/chio-bacula (FreeBSD)
#
# The volumenames are returned by the "changer list" command
# labeling in the console is done by "label barcodes"
# (then all volumes belog to the default pool).
# All Lines with an "#" at the bedinning are ignored
#
# !!!! If you export an tape and reinsert another one,
# !!!! don't forget to change the volume name in this file!
#
1:Volume1-100
2:Volume1-101
3:Volume1-102
4:Volume1-103
5:Volume1-104
6:Volume1-105
7:Volume1-106
8:Volume1-107
9:Volume1-108
10:Volume1-109
11:Volume1-110
12:Volume1-111
#
# Further volumes exported from the changer
#
# 36GB AIT2 tapes
#Volume1-100
#Volume1-101
#Volume1-102
#Volume1-103
#Volume1-104
#Volume1-105
#Volume1-106
#Volume1-107
#Volume1-108
#Volume1-109
#Volume1-110
#Volume1-111
#Volume1-112
#Volume1-113
#Volume1-114
#Volume1-115
#
# 50GB AIT2 tapes
#Volume2-200
#Volume2-201
#Volume2-202
#Volume2-203
#Volume2-204

View File

@ -0,0 +1,99 @@
@/etc/bacula/clients/director-client.conf
@/etc/bacula/clients/zinc-client.conf
@/etc/bacula/filesets.conf
@/etc/bacula/schedules.conf
@/etc/bacula/pools.conf
Director { # define myself
Name = bacula-dir
DIRport = 9101 # where we listen for UA connections
QueryFile = "/etc/bacula/scripts/query.sql"
WorkingDirectory = "/var/lib/bacula"
PidDirectory = "/run/bacula"
Maximum Concurrent Jobs = 20
Password = "iamnotacrook" # Console password
Messages = JoesMail
DirAddress = 10.85.3.30
}
Catalog {
Name = MyCatalog
dbname = bacula
dbaddress = localhost
dbuser = bacula
dbpassword = "iamnotacrook"
}
Autochanger { # New resource
Name = Iron-Autochanger
Address = 10.85.3.39
SDPort = 9103
Password = "iamnotacrook"
Device = Drive-0-LTO-3
Media Type = LTO-3
Maximum Concurrent Jobs = 20
}
Storage {
Name = Drive-0-LTO-3
Address = 10.85.3.39
SDPort = 9103
Password = "iamnotacrook"
Device = LTO-3
Media Type = LTO-3
Maximum Concurrent Jobs = 10
Autochanger = Iron-Autochanger # New directive
}
# Maintiance
Job { # Restore job
Name = "RestoreFiles"
Type = Restore
Client = Zinc-Client
FileSet = "Catalog"
Storage = Iron-Autochanger
Where = /mnt/Restore
Messages = JoesMail
Pool = FullFile
}
Job { # This job should release the tape once finished
Name = "Release Tape"
Type = Admin
Run Script {
Runs When = Before
Runs on Client = No
Command = "/etc/bacula/scripts/release_tape.sh"
}
Schedule = AdminTwoDays
Priority = 25
Messages = JoesMail
Pool = FullFile
Client = Zinc-Client
FileSet = "Catalog"
}
messages { # Send mail just to me
name = JoesMail
mail = kenwood364@gmail.com = all, !skipped
console = all, !skipped, !saved
}
messages { # Send mail to me and dad
name = MarksMail
mail = mws03@comcast.net,kenwood364@gmail.com = all, !skipped
console = all, !skipped, !saved
}
messages { # Send mail to me and michael
name = MikesMail
mail = mikesedutto@gmail.com,kenwood364@gmail.com = all, !skipped
console = all, !skipped, !saved
}
messages { # Send mail to me and matthew
name = MattsMail
mail = younglad204@gmail.com,kenwood364@gmail.com = all, !skipped
console = all, !skipped, !saved
}

View File

@ -0,0 +1,324 @@
#
# Default Bacula Director Configuration file
#
# The only thing that MUST be changed is to add one or more
# file or directory names in the Include directive of the
# FileSet resource.
#
# For Bacula release 9.4.2 (04 February 2019) -- ubuntu 20.04
#
# You might also want to change the default email address
# from root to your address. See the "mail" and "operator"
# directives in the Messages resource.
#
# Copyright (C) 2000-2017 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Director { # define myself
Name = bacula-dir
DIRport = 9101 # where we listen for UA connections
QueryFile = "/etc/bacula/scripts/query.sql"
WorkingDirectory = "/var/lib/bacula"
PidDirectory = "/run/bacula"
Maximum Concurrent Jobs = 20
Password = "p2ee6NtCH6Y-mw3bVk5yGgo1wjXnyne4a" # Console password
Messages = Daemon
DirAddress = 127.0.0.1
}
JobDefs {
Name = "DefaultJob"
Type = Backup
Level = Incremental
Client = bacula-fd
FileSet = "Full Set"
Schedule = "WeeklyCycle"
Storage = File1
Messages = Standard
Pool = File
SpoolAttributes = yes
Priority = 10
Write Bootstrap = "/var/lib/bacula/%c.bsr"
}
#
# Define the main nightly save backup job
# By default, this job will back up to disk in /nonexistant/path/to/file/archive/dir
Job {
Name = "BackupClient1"
JobDefs = "DefaultJob"
}
#Job {
# Name = "BackupClient2"
# Client = bacula2-fd
# JobDefs = "DefaultJob"
#}
#Job {
# Name = "BackupClient1-to-Tape"
# JobDefs = "DefaultJob"
# Storage = LTO-4
# Spool Data = yes # Avoid shoe-shine
# Pool = Default
#}
#}
# Backup the catalog database (after the nightly save)
Job {
Name = "BackupCatalog"
JobDefs = "DefaultJob"
Level = Full
FileSet="Catalog"
Schedule = "WeeklyCycleAfterBackup"
# This creates an ASCII copy of the catalog
# Arguments to make_catalog_backup.pl are:
# make_catalog_backup.pl <catalog-name>
RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup.pl MyCatalog"
# This deletes the copy of the catalog
RunAfterJob = "/etc/bacula/scripts/delete_catalog_backup"
Write Bootstrap = "/var/lib/bacula/%n.bsr"
Priority = 11 # run after main backup
}
#
# Standard Restore template, to be changed by Console program
# Only one such job is needed for all Jobs/Clients/Storage ...
#
Job {
Name = "RestoreFiles"
Type = Restore
Client=bacula-fd
Storage = File1
# The FileSet and Pool directives are not used by Restore Jobs
# but must not be removed
FileSet="Full Set"
Pool = File
Messages = Standard
Where = /nonexistant/path/to/file/archive/dir/bacula-restores
}
# List of files to be backed up
FileSet {
Name = "Full Set"
Include {
Options {
signature = MD5
}
#
# Put your list of files here, preceded by 'File =', one per line
# or include an external list with:
#
# File = <file-name
#
# Note: / backs up everything on the root partition.
# if you have other partitions such as /usr or /home
# you will probably want to add them too.
#
# By default this is defined to point to the Bacula binary
# directory to give a reasonable FileSet to backup to
# disk storage during initial testing.
#
File = /usr/sbin
}
#
# If you backup the root directory, the following two excluded
# files can be useful
#
Exclude {
File = /var/lib/bacula
File = /nonexistant/path/to/file/archive/dir
File = /proc
File = /tmp
File = /sys
File = /.journal
File = /.fsck
}
}
#
# When to do the backups, full backup on first sunday of the month,
# differential (i.e. incremental since full) every other sunday,
# and incremental backups other days
Schedule {
Name = "WeeklyCycle"
Run = Full 1st sun at 23:05
Run = Differential 2nd-5th sun at 23:05
Run = Incremental mon-sat at 23:05
}
# This schedule does the catalog. It starts after the WeeklyCycle
Schedule {
Name = "WeeklyCycleAfterBackup"
Run = Full sun-sat at 23:10
}
# This is the backup of the catalog
FileSet {
Name = "Catalog"
Include {
Options {
signature = MD5
}
File = "/var/lib/bacula/bacula.sql"
}
}
# Client (File Services) to backup
Client {
Name = bacula-fd
Address = localhost
FDPort = 9102
Catalog = MyCatalog
Password = "plfcG_XSfD6EBSD0YQhZThlZNHFFFjqtg" # password for FileDaemon
File Retention = 60 days # 60 days
Job Retention = 6 months # six months
AutoPrune = yes # Prune expired Jobs/Files
}
#
# Second Client (File Services) to backup
# You should change Name, Address, and Password before using
#
#Client {
# Name = bacula2-fd
# Address = localhost2
# FDPort = 9102
# Catalog = MyCatalog
# Password = "plfcG_XSfD6EBSD0YQhZThlZNHFFFjqtg2" # password for FileDaemon 2
# File Retention = 60 days # 60 days
# Job Retention = 6 months # six months
# AutoPrune = yes # Prune expired Jobs/Files
#}
# Definition of file Virtual Autochanger device
Autochanger {
Name = File1
# Do not use "localhost" here
Address = localhost # N.B. Use a fully qualified name here
SDPort = 9103
Password = "wyHyTtf3Q5Mul8VvNNtm9D2lsIg2mKBVh"
Device = FileChgr1
Media Type = File1
Maximum Concurrent Jobs = 10 # run up to 10 jobs a the same time
Autochanger = File1 # point to ourself
}
# Definition of a second file Virtual Autochanger device
# Possibly pointing to a different disk drive
Autochanger {
Name = File2
# Do not use "localhost" here
Address = localhost # N.B. Use a fully qualified name here
SDPort = 9103
Password = "wyHyTtf3Q5Mul8VvNNtm9D2lsIg2mKBVh"
Device = FileChgr2
Media Type = File2
Autochanger = File2 # point to ourself
Maximum Concurrent Jobs = 10 # run up to 10 jobs a the same time
}
# Definition of LTO-4 tape Autochanger device
#Autochanger {
# Name = LTO-4
# Do not use "localhost" here
# Address = localhost # N.B. Use a fully qualified name here
# SDPort = 9103
# Password = "wyHyTtf3Q5Mul8VvNNtm9D2lsIg2mKBVh" # password for Storage daemon
# Device = LTO-4 # must be same as Device in Storage daemon
# Media Type = LTO-4 # must be same as MediaType in Storage daemon
# Autochanger = LTO-4 # enable for autochanger device
# Maximum Concurrent Jobs = 10
#}
# Generic catalog service
Catalog {
Name = MyCatalog
dbname = "bacula"; DB Address = "localhost"; dbuser = "bacula"; dbpassword = "iamnotacrook"
}
# Reasonable message delivery -- send most everything to email address
# and to the console
Messages {
Name = Standard
#
# NOTE! If you send to two email or more email addresses, you will need
# to replace the %r in the from field (-f part) with a single valid
# email address in both the mailcommand and the operatorcommand.
# What this does is, it sets the email address that emails would display
# in the FROM field, which is by default the same email as they're being
# sent to. However, if you send email to more than one address, then
# you'll have to set the FROM address manually, to a single address.
# for example, a 'no-reply@mydomain.com', is better since that tends to
# tell (most) people that its coming from an automated source.
#
mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r"
operatorcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
mail = root = all, !skipped
operator = root = mount
console = all, !skipped, !saved
#
# WARNING! the following will create a file that you must cycle from
# time to time as it will grow indefinitely. However, it will
# also keep all your messages if they scroll off the console.
#
append = "/var/log/bacula/bacula.log" = all, !skipped
catalog = all
}
#
# Message delivery for daemon messages (no job).
Messages {
Name = Daemon
mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r"
mail = root = all, !skipped
console = all, !skipped, !saved
append = "/var/log/bacula/bacula.log" = all, !skipped
}
# Default pool definition
Pool {
Name = Default
Pool Type = Backup
Recycle = yes # Bacula can automatically recycle Volumes
AutoPrune = yes # Prune expired volumes
Volume Retention = 365 days # one year
Maximum Volume Bytes = 50G # Limit Volume size to something reasonable
Maximum Volumes = 100 # Limit number of Volumes in Pool
}
# File Pool definition
Pool {
Name = File
Pool Type = Backup
Recycle = yes # Bacula can automatically recycle Volumes
AutoPrune = yes # Prune expired volumes
Volume Retention = 365 days # one year
Maximum Volume Bytes = 50G # Limit Volume size to something reasonable
Maximum Volumes = 100 # Limit number of Volumes in Pool
Label Format = "Vol-" # Auto label
}
# Scratch pool definition
Pool {
Name = Scratch
Pool Type = Backup
}
#
# Restricted console used by tray-monitor to get the status of the director
#
Console {
Name = bacula-mon
Password = "qh2ITlwo3xfTzP8uxwJjq1vJshc1Dsimc"
CommandACL = status, .status
}

23
Dir Config/bacula-fd.conf Normal file
View File

@ -0,0 +1,23 @@
Director {
Name = bacula-dir
Password = "iamnotacrook"
}
#
# "Global" File daemon configuration specifications
#
FileDaemon { # this is me
Name = bacula-fd
FDport = 9102 # where we listen for the director
WorkingDirectory = /var/lib/bacula
Pid Directory = /run/bacula
Maximum Concurrent Jobs = 20
Plugin Directory = /usr/lib/bacula
FDAddress = 127.0.0.1
}
# Send all messages except skipped files back to Director
Messages {
Name = Standard
director = bacula-dir = all, !skipped, !restored
}

View File

@ -0,0 +1,49 @@
#
# Default Bacula File Daemon Configuration file
#
# For Bacula release 9.4.2 (04 February 2019) -- ubuntu 20.04
#
# There is not much to change here except perhaps the
# File daemon Name to
#
#
# Copyright (C) 2000-2015 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
#
# List Directors who are permitted to contact this File daemon
#
Director {
Name = bacula-dir
Password = "plfcG_XSfD6EBSD0YQhZThlZNHFFFjqtg"
}
#
# Restricted Director, used by tray-monitor to get the
# status of the file daemon
#
Director {
Name = bacula-mon
Password = "ULdl26830u9xQw1i8YI_VBqaIMG1OfE_V"
Monitor = yes
}
#
# "Global" File daemon configuration specifications
#
FileDaemon { # this is me
Name = bacula-fd
FDport = 9102 # where we listen for the director
WorkingDirectory = /var/lib/bacula
Pid Directory = /run/bacula
Maximum Concurrent Jobs = 20
Plugin Directory = /usr/lib/bacula
FDAddress = 127.0.0.1
}
# Send all messages except skipped files back to Director
Messages {
Name = Standard
director = bacula-dir = all, !skipped, !restored
}

38
Dir Config/bacula-sd.conf Normal file
View File

@ -0,0 +1,38 @@
Storage { # definition of myself
Name = test-bacula-sd # Name of this device
SDPort = 9103 # Director's port
WorkingDirectory = "/var/lib/bacula" # Working Directory
Pid Directory = "/run/bacula" # PID Directory
Plugin Directory = "/usr/lib/bacula" # Directory for plugins
Maximum Concurrent Jobs = 20 # Max jobs it can do at any one time
SDAddress = 127.0.0.1 # Address of the SD
}
Director { # Director who is allowed to contact us
Name = bacula-dir # Name of the director
Password = "iamnotacrook" # Password for the director to usr to login
}
#Autochanger { # Virtual Auto Changer
# Name = FileChgr1 # Has a name
# Device = FileChgr1-Dev1 # Seperate tape drives with commas
# Changer Command = "" # Not sure what this is for
# Changer Device = /dev/null # Device is not real
#}
#Device { # Device for Autochanger
# Name = FileChgr1-Dev1 # Has a name
# Media Type = File1 # has a type of media
# Archive Device = /backup/tape # Archive location(?) not sure on this one
# LabelMedia = yes; # lets Bacula label unlabeled media
# Random Access = Yes; # Not sure what this is for
# AutomaticMount = yes; # when device opened, read it
# RemovableMedia = no; # Not sure what this is for
# AlwaysOpen = no; # Not sure what this is for
# Maximum Concurrent Jobs = 5 # Can do 5 jobs at once? (not sure how but ok)
#}
Messages { # Place to send messages
Name = Standard # Send standard messag es
director = bacula-dir = all # Forward those to the director
}

View File

@ -0,0 +1,335 @@
#
# Default Bacula Storage Daemon Configuration file
#
# For Bacula release 9.4.2 (04 February 2019) -- ubuntu 20.04
#
# You may need to change the name of your tape drive
# on the "Archive Device" directive in the Device
# resource. If you change the Name and/or the
# "Media Type" in the Device resource, please ensure
# that dird.conf has corresponding changes.
#
#
# Copyright (C) 2000-2017 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Storage { # definition of myself
Name = bacula-sd
SDPort = 9103 # Director's port
WorkingDirectory = "/var/lib/bacula"
Pid Directory = "/run/bacula"
Plugin Directory = "/usr/lib/bacula"
Maximum Concurrent Jobs = 20
SDAddress = 127.0.0.1
}
#
# List Directors who are permitted to contact Storage daemon
#
Director {
Name = bacula-dir
Password = "wyHyTtf3Q5Mul8VvNNtm9D2lsIg2mKBVh"
}
#
# Restricted Director, used by tray-monitor to get the
# status of the storage daemon
#
Director {
Name = bacula-mon
Password = "F988Q4o09gBCTwOO3hvk-DKGMtd-xKLo7"
Monitor = yes
}
#
# Note, for a list of additional Device templates please
# see the directory <bacula-source>/examples/devices
# Or follow the following link:
# http://www.bacula.org/git/cgit.cgi/bacula/tree/bacula/examples/devices?h=Branch-7.4
#
#
# Devices supported by this Storage daemon
# To connect, the Director's bacula-dir.conf must have the
# same Name and MediaType.
#
#
# Define a Virtual autochanger
#
Autochanger {
Name = FileChgr1
Device = FileChgr1-Dev1, FileChgr1-Dev2
Changer Command = ""
Changer Device = /dev/null
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
#
# Define a second Virtual autochanger
#
Autochanger {
Name = FileChgr2
Device = FileChgr2-Dev1, FileChgr2-Dev2
Changer Command = ""
Changer Device = /dev/null
}
Device {
Name = FileChgr2-Dev1
Media Type = File2
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
Device {
Name = FileChgr2-Dev2
Media Type = File2
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
#
# An autochanger device with two drives
#
#Autochanger {
# Name = Autochanger
# Device = Drive-1
# Device = Drive-2
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
#}
#Device {
# Name = Drive-1 #
# Drive Index = 0
# Media Type = DLT-8000
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# #
# # Enable the Alert command only if you have the mtx package loaded
# # Note, apparently on some systems, tapeinfo resets the SCSI controller
# # thus if you turn this on, make sure it does not reset your SCSI
# # controller. I have never had any problems, and smartctl does
# # not seem to cause such problems.
# #
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#Device {
# Name = Drive-2 #
# Drive Index = 1
# Media Type = DLT-8000
# Archive Device = /dev/nst1
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = yes
# # Enable the Alert command only if you have the mtx package loaded
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-2 tape drive
#
#Device {
# Name = LTO-2
# Media Type = LTO-2
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 3GB
## Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
## Changer Device = /dev/sg0
## AutoChanger = yes
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-3 tape drive
#
#Device {
# Name = LTO-3
# Media Type = LTO-3
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 4GB
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-4 tape drive
#
#Device {
# Name = LTO-4
# Media Type = LTO-4
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 5GB
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# An HP-UX tape drive
#
#Device {
# Name = Drive-1 #
# Drive Index = 0
# Media Type = DLT-8000
# Archive Device = /dev/rmt/1mnb
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = no
# Two EOF = yes
# Hardware End of Medium = no
# Fast Forward Space File = no
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/rmt/1mnb
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# #
# # Enable the Alert command only if you have the mtx package loaded
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A FreeBSD tape drive
#
#Device {
# Name = DDS-4
# Description = "DDS-4 for FreeBSD"
# Media Type = DDS-4
# Archive Device = /dev/nsa1
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes
# Offline On Unmount = no
# Hardware End of Medium = no
# BSF at EOM = yes
# Backward Space Record = no
# Fast Forward Space File = no
# TWO EOF = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nsa1
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# Send all messages to the Director,
# mount messages also are sent to the email address
#
Messages {
Name = Standard
director = bacula-dir = all
}

13
Dir Config/bconsole.conf Normal file
View File

@ -0,0 +1,13 @@
#
# Bacula User Agent (or Console) Configuration File
#
# Copyright (C) 2000-2020 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Director {
Name = 113amd64-quarterly-job-10-dir
DIRport = 9101
address = 10.85.3.30
Password = "iamnotacrook"
}

View File

@ -0,0 +1,41 @@
Client {
Name = BaculaDirectorClient
Password = "iamnotacrook"
Address = localhost
Catalog = MyCatalog
File Retention = 60 days # 60 days
Job Retention = 6 months # six months
AutoPrune = yes # Prune expired Jobs/Files
}
#Job {
# Name = "MyFirstJob"
# Client = BaculaDirectorClient
# Type = "Backup"
# FileSet = "MyFirstFileSet"
# Storage = Iron-Autochanger
# Schedule = MyFirstSchedule
# Messages = JoesMail
#
# Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
#
# Full Backup Pool = FullFile
# #Differential Backup Pool = DiffFile
# Incremental Backup Pool = IncrFile
#}
Job {
Name = "BackupDatabase"
Client = BaculaDirectorClient
Type = "Backup"
FileSet = "Catalog"
Storage = Iron-Autochanger
Schedule = EveryTwoDays
Messages = JoesMail
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = Diff-Pool
Incremental Backup Pool = IncrFile
}

View File

@ -0,0 +1,15 @@
# These are jobs run for vms, storage, archive, etc
Job { # Archive Obelisk
Name = "Archive-Obelisk"
Client = Zinc-Client
Type = "Backup"
FileSet = "Obelisk Archive"
Storage = Iron-Autochanger
Messages = JoesMail
Pool = Archive-Pool # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = Archive-Pool
Incremental Backup Pool = Archive-Pool
}

View File

@ -0,0 +1,80 @@
# These are jobs run for users
Job { # Caleb's Job
Name = "Backup-Caleb"
Client = Zinc-Client
Type = "Backup"
FileSet = "Caleb Backup"
Storage = Iron-Autochanger
#Schedule = EveryTwoDays
Messages = JoesMail
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = Diff-Pool
Incremental Backup Pool = IncrFile
}
Job { # Mark's Job
Name = "Backup-Mark"
Client = Zinc-Client
Type = "Backup"
FileSet = "Mark Backup"
Storage = Iron-Autochanger
Schedule = EveryTwoDays
Messages = MarksMail
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = Diff-Pool
Incremental Backup Pool = IncrFile
}
Job { # My Job
Name = "Backup-Joe"
Client = Zinc-Client
Type = "Backup"
FileSet = "Joe Backup"
Storage = Iron-Autochanger
Schedule = EveryTwoDays
Messages = JoesMail
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = Diff-Pool
Incremental Backup Pool = IncrFile
}
Job { # Backup Michael
Name = "Backup-Michael"
Client = Zinc-Client
Type = "Backup"
FileSet = "Michael Backup"
Storage = Iron-Autochanger
Schedule = EveryTwoDays
Messages = MikesMail
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = Diff-Pool
Incremental Backup Pool = IncrFile
}
Job { # Backup Matthew
Name = "Backup-Matthew"
Client = Zinc-Client
Type = "Backup"
FileSet = "Matthew Backup"
Storage = Iron-Autochanger
Schedule = EveryTwoDays
Messages = MattsMail
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = Diff-Pool
Incremental Backup Pool = IncrFile
}

View File

@ -0,0 +1,14 @@
@/etc/bacula/clients/zinc-client-users.conf
@/etc/bacula/clients/zinc-client-other.conf
Client {
Name = Zinc-Client
Password = "iamnotacrook"
Address = 10.85.3.31
Catalog = MyCatalog
File Retention = 60 days # 60 days
Job Retention = 6 months # six months
AutoPrune = yes # Prune expired Jobs/Files
}

View File

@ -0,0 +1,12 @@
#
# This file has been autogenerated during package installation and
# holds defaults for new Bacula packages installed on this system. It
# is used only when you install a new Bacula package, and can be
# safely removed at any time.
DIRPASSWD=p2ee6NtCH6Y-mw3bVk5yGgo1wjXnyne4a
DIRMPASSWD=qh2ITlwo3xfTzP8uxwJjq1vJshc1Dsimc
SDPASSWD=wyHyTtf3Q5Mul8VvNNtm9D2lsIg2mKBVh
SDMPASSWD=F988Q4o09gBCTwOO3hvk-DKGMtd-xKLo7
FDPASSWD=plfcG_XSfD6EBSD0YQhZThlZNHFFFjqtg
FDMPASSWD=ULdl26830u9xQw1i8YI_VBqaIMG1OfE_V

100
Dir Config/filesets.conf Normal file
View File

@ -0,0 +1,100 @@
# Bacula config Backup
FileSet {
Name = "MyFirstFileSet"
Include {
Options {
signature=MD5
}
File = /etc/bacula/
}
Exclude {
File = *~
}
}
# This is the backup of the catalog
FileSet {
Name = "Catalog"
Include {
Options {
signature = MD5
}
File = "/var/lib/postgresql/12/main"
}
}
# Caleb's backup on zinc
FileSet {
Name = "Caleb Backup"
Include {
Options {
signature = MD5
compression=GZIP
}
File = "/mnt/Caleb/"
}
}
# Mark's backup on zinc
FileSet {
Name = "Mark Backup"
Include {
Options {
signature = MD5
compression=GZIP
}
File = "/mnt/Mark/"
#File = "/mnt/NextCloud/data/mark/"
}
}
# Joe's backup on zinc
FileSet {
Name = "Joe Backup"
Include {
Options {
signature = MD5
compression=GZIP
}
File = "/mnt/Joe/"
File = "/mnt/NextCloud/data/joe/"
}
}
# Matthew's backup on zinc
FileSet {
Name = "Matthew Backup"
Include {
Options {
signature = MD5
compression=GZIP
}
File = "/mnt/Matthew/"
#File = "/mnt/NextCloud/data/matthew/"
}
}
# Michael's backup on zinc
FileSet {
Name = "Michael Backup"
Include {
Options {
signature = MD5
compression=GZIP
}
File = "/mnt/Michael/"
#File = "/mnt/NextCloud/data/michael/"
}
}
# Archive for Obelisk
FileSet {
Name = "Obelisk Archive"
Include {
Options {
signature = MD5
compression=GZIP
}
File = "/mnt/Obelisk/"
}
}

54
Dir Config/pools.conf Normal file
View File

@ -0,0 +1,54 @@
Pool {
Name = FullFile
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 6 months
Storage = Iron-Autochanger
Maximum Volume Bytes = 800G
#Maximum Volumes = 10
Cleaning Prefix = "CLN"
}
Pool {
Name = Diff-Pool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 2 months
Storage = Iron-Autochanger
Maximum Volume Bytes = 800G
#Maximum Volumes = 10
Cleaning Prefix = "CLN"
}
Pool {
Name = IncrFile
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 1 month
Storage = Iron-Autochanger
Maximum Volume Bytes = 800G
#Maximum Volumes = 10
Cleaning Prefix = "CLN"
}
Pool {
Name = Archive-Pool
Pool Type = Backup
Recycle = no
AutoPrune = no
Volume Retention = 30 years
Storage = Iron-Autochanger
Maximum Volume Bytes = 800G
Cleaning Prefix = "CLN"
}

37
Dir Config/schedules.conf Normal file
View File

@ -0,0 +1,37 @@
Schedule {
Name = EveryTwoDays
Run = Level=Full jan 1st sun at 4:15
Run = Level=Differential feb 1st sun at 4:15
Run = Level=Differential mar 1st sun at 4:15
Run = Level=Full apr 1st sun at 4:15
Run = Level=Differential may 1st sun at 4:15
Run = Level=Differential jun 1st sun at 4:15
Run = Level=Full jul 1st sun at 4:15
Run = Level=Differential aug 1st sun at 4:15
Run = Level=Differential sep 1st sun at 4:15
Run = Level=Full oct 1st sun at 4:15
Run = Level=Differential nov 1st sun at 4:15
Run = Level=Differential dec 1st sun at 4:15
Run = Level=Incremental tue at 2:15
Run = Level=Incremental sat at 2:15
}
Schedule {
Name = AdminTwoDays
Run = Level=Full jan 1st sun at 4:30
Run = Level=Differential feb 1st sun at 4:30
Run = Level=Differential mar 1st sun at 4:30
Run = Level=Full apr 1st sun at 4:30
Run = Level=Differential may 1st sun at 4:30
Run = Level=Differential jun 1st sun at 4:30
Run = Level=Full jul 1st sun at 4:30
Run = Level=Differential aug 1st sun at 4:30
Run = Level=Differential sep 1st sun at 4:30
Run = Level=Full oct 1st sun at 4:30
Run = Level=Differential nov 1st sun at 4:30
Run = Level=Differential dec 1st sun at 4:30
Run = Level=Incremental tue at 2:30
Run = Level=Incremental sat at 2:30
}

View File

@ -0,0 +1,858 @@
#!/bin/sh
#
# baculabackupreport.sh
#
# ------------------------------------------------------------------------------
#
# waa - 20130428 - Initial release.
# Generate basic Bacula backup report.
#
# waa - 20170501 - Change Log moved to bottom of script.
#
# ------------------------------------------------------------------------------
#
# Copyright (c) 2013-2017, William A. Arlofski waa-at-revpol-dot-com
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ------------------------------------------------------------------------------
# System variables
# ----------------
server="localhost"
admin="root"
bcbin="/opt/bacula/bin/bconsole"
sendmail="/usr/sbin/sendmail"
bcconfig="/opt/bacula/etc/bconsole.conf"
# Database variables
# ------------------
dbtype="pgsql" # Supported options are pgsql, mysql, mariadb
db="bacula"
dbuser="bacula"
dbbin="/usr/bin/psql"
# dbpass="-pPassword" # Uncomment and set db password if one is used
# Formatting variables
# --------------------
html="yes" # Generate HTML emails instead of plain text emails?
boldstatus="yes" # Set <b> tag on Status field (only if html="yes")
colorstatusbg="yes" # Colorize the Status cell's background? (only if html="yes")
jobtableheadercolor="#b0b0b0" # Background color for the HTML table's header
jobtablejobcolor="#f4f4f4" # Background color for the job rows in the HTML table
runningjobcolor="#4d79ff" # Background color of the Status cell for "Running" jobs
goodjobcolor="#00f000" # Background color of the Status cell for "OK" jobs
warnjobcolor="#ffff00" # Background color of the Status cell for "OK" jobs (with warnings - well, actually with 'joberrors')
badjobcolor="#cc3300" # Background color of the Status cell for "bad" jobs
goodjobwitherrcolor="#cccc00" # Background color of the Status cell for "OK" jobs (with errors) - Not implemented due to request
fontfamily="Verdana, Arial, Helvetica, sans-serif" # Set the font family to use for HTML emails
fontsize="16px" # Set the font size to use for email title and print summaries
fontsizejobinfo="12px" # Set the font size to use for job information inside of table
fontsizesumlog="10px" # Set the font size of bad logs and job summaries
printsummary="yes" # Print a short summary after the job list table? (Total Jobs, Files & Bytes)
emailsummaries="no" # Email all job summaries. Be careful with this, it can generate very large emails
emailbadlogs="yes" # Email logs of bad jobs or jobs with JobErrors -ne 0. Be careful, this can generate very large emails.
addsubjecticon="yes" # Prepend the email Subject with UTF-8 icons (a 'checkmark', 'circle with slash', or a bold 'x')
nojobsicon="=?utf-8?Q?=E2=8A=98?=" # utf-8 subject icon when no jobs have been run
goodjobsicon="=?utf-8?Q?=E2=9C=94?=" # utf-8 subject icon when all jobs were "OK"
badjobsicon="=?utf-8?Q?=E2=9C=96?=" # utf-8 subject icon when there are jobs with errors etc
starbadjobids="yes" # Prepend an asterisk "*" to jobids of "bad" jobs
sortfield="EndTime" # Which catalog db field to sort on? Multiple,fields,work,here
sortorder="DESC" # Which direction to sort?
emailtitle="Jobs Run On ${server} in the Past ${1} Hours" # This is prepended at the top of the email, before the jobs table
# --------------------------------------------------
# Nothing should need to be modified below this line
# --------------------------------------------------
hist=${1}
if [ -z ${hist} ]; then
echo -e "\nUSE:\n$0 <history in hours>\n"
exit 1
fi
if [ ! -e ${bcconfig} ]; then
echo -e "\nThe bconsole configuration file does not seem to be '${bcconfig}'."
echo -e "Please check the setting for the variable 'bcconfig'.\n"
exit 1
fi
if [ ! -x ${bcbin} ]; then
echo -e "\nThe bconsole binary does not seem to be '${bcbin}', or it is not executable."
echo -e "Please check the setting for the variable 'bcbin'.\n"
exit 1
fi
if [ ! -x ${dbbin} ]; then
echo -e "\nThe database client binary does not seem to be '${dbbin}', or it is not executable."
echo -e "Please check the setting for the variable 'dbbin'.\n"
exit 1
fi
if [ ! -x ${sendmail} ]; then
echo -e "\nThe sendmail binary does not seem to be '${sendmail}', or it is not executable."
echo -e "Please check the setting for the variable 'sendmail'.\n"
exit 1
fi
# Build query based on dbtype. Good thing we have "standards" Sigh...
# -------------------------------------------------------------------
case ${dbtype} in
mysql )
queryresult=$(echo "SELECT JobId, Name, StartTime, EndTime, Type, Level, JobStatus, JobFiles, JobBytes, \
TIMEDIFF (EndTime,StartTime) as RunTime, JobErrors \
FROM Job \
WHERE (RealEndTime >= DATE_ADD(NOW(), INTERVAL -${hist} HOUR) OR JobStatus='R') \
ORDER BY ${sortfield} ${sortorder};" \
| ${dbbin} -u ${dbuser} ${dbpass} ${db} \
| sed '/^JobId/d' )
;;
pgsql )
queryresult=$(echo "SELECT JobId, Name, StartTime, EndTime, Type, Level, JobStatus, JobFiles, JobBytes, \
AGE(EndTime, StartTime) as RunTime, JobErrors \
FROM Job \
WHERE (RealEndTime >= CURRENT_TIMESTAMP(2) - cast('${hist} HOUR' as INTERVAL) OR JobStatus='R') \
ORDER BY ${sortfield} ${sortorder};" \
| ${dbbin} -U ${dbuser} ${dbpass} ${db} -0t \
| sed -e 's/|//g' -e '/^$/d' )
;;
mariadb )
queryresult=$(echo "SELECT JobId, Name, StartTime, EndTime, Type, Level, JobStatus, JobFiles, JobBytes, \
TIMEDIFF (EndTime,StartTime) as RunTime, JobErrors \
FROM Job \
WHERE (RealEndTime >= DATE_ADD(NOW(), INTERVAL -${hist} HOUR) OR JobStatus='R') \
ORDER BY ${sortfield} ${sortorder};" \
| ${dbbin} -u ${dbuser} -p${dbpass} ${db} -s -N )
;;
* )
echo "dbtype of '${dbtype}' is invalid. Please set dbtype variable to 'mysql', 'pgsql', or 'mariadb'"
exit 1
;;
esac
# If we have no jobs to report on, then
# we need to skip the entire awk script
# and some bash stuff and jump all the
# way to about line 673
# -------------------------------------
if [ -z "${queryresult}" ]; then
results="0"
else
results="1"
# Now for some fun with awk
# -------------------------
IFS=" "
msg=$(echo ${queryresult} | \
LC_ALL=en_US.UTF-8 \
awk \
-v html="${html}" \
-v boldstatus="${boldstatus}" \
-v colorstatusbg="${colorstatusbg}" \
-v jobtableheadercolor="${jobtableheadercolor}" \
-v jobtablejobcolor="${jobtablejobcolor}" \
-v runningjobcolor="${runningjobcolor}" \
-v goodjobcolor="${goodjobcolor}" \
-v goodjobwitherrcolor="${goodjobwitherrcolor}" \
-v warnjobcolor="${warnjobcolor}" \
-v badjobcolor="${badjobcolor}" \
-v printsummary="${printsummary}" \
-v starbadjobids="${starbadjobids}" \
'BEGIN { awkerr = 0 }
{star = " " }
# List of possible jobstatus codes
# --------------------------------
# Enter SQL query: SELECT * FROM status;
# +-----------+---------------------------------+----------+
# | jobstatus | jobstatuslong | severity |
# +-----------+---------------------------------+----------+
# | C | Created, not yet running | 15 |
# | R | Running | 15 |
# | B | Blocked | 15 |
# | T | Completed successfully | 10 |
# | E | Terminated with errors | 25 |
# | e | Non-fatal error | 20 |
# | f | Fatal error | 100 |
# | D | Verify found differences | 15 |
# | A | Canceled by user | 90 |
# | F | Waiting for Client | 15 |
# | S | Waiting for Storage daemon | 15 |
# | m | Waiting for new media | |
# | M | Waiting for media mount | 15 |
# | s | Waiting for storage resource | 15 |
# | j | Waiting for job resource | 15 |
# | c | Waiting for client resource | 15 |
# | d | Waiting on maximum jobs | 15 |
# | t | Waiting on start time | 15 |
# | p | Waiting on higher priority jobs | 15 |
# | a | SD despooling attributes | 15 |
# | i | Doing batch insert file records | 15 |
# | I | Incomplete Job | 25 |
# +-----------+---------------------------------+----------+
# Is this job still running?
# If a job is still running, then there will be no "Stop Time"
# fields, so $9 (jobstatus) will be shifted left two columns
# to $7, and we will need to test and then reassign these variables
# Note, this seems to be required for PostgreSQL, but MariaDB and
# MySQL return all zeros for the date and time for running jobs
# -----------------------------------------------------------------
{ if ($7 == "R" && $8 ~ /^[0-9]+/)
{
$13 = $10
$11 = $9
$10 = $8
$9 = $7
$8 = $6
$7 = $5
$5 = "--=Still Running=--"
$6 = ""
}
}
# Assign words to job status code characters
# ------------------------------------------
# First, check to see if we need to generate an HTML email
{ if (html == "yes")
{
# Set default opening and closing tags for status cell
# ----------------------------------------------------
tdo = "<td align=\"center\">"
tdc = "</td>"
# Check to see if the job is "OK" then assign
# the "goodjobcolor" to the cell background
# -------------------------------------------
if ($9 ~ /[T]/ && $13 == 0)
{
if (colorstatusbg == "yes")
# Assign jobs that are OK or Running the goodjobcolor
# ---------------------------------------------------
{
tdo = "<td align=\"center\" bgcolor=\"" goodjobcolor "\">"
}
# Should the status be bolded?
# ----------------------------
if (boldstatus == "yes")
{
tdo=tdo"<b>"
tdc="</b>"tdc
}
status["T"]=tdo"-OK-"tdc
# If it is a good job, but with errors or warnings
# then we will assign the warnjobcolor
# ------------------------------------------------
} else if ($9 == "T" && $13 != 0)
{
if (colorstatusbg == "yes")
# Assign OK jobs with errors the warnjobcolor
# -------------------------------------------
{
tdo = "<td align=\"center\" bgcolor=\"" warnjobcolor "\">"
}
# Should the status be bolded?
# ----------------------------
if (boldstatus == "yes")
{
tdo=tdo"<b>"
tdc="</b>"tdc
}
# Since the "W" jobstatus never appears in the DB, we manually
# assign it here so it can be recognized later on in the script
# -------------------------------------------------------------
$9 = "W"
status["W"]=tdo"OK/Warnings"tdc
# If the job is still running we will
# assign it the runningjobcolor
# -----------------------------------
} else if ($9 == "R")
{
if (colorstatusbg == "yes")
# Assign running jobs the runningjobcolor
# ---------------------------------------
{
tdo = "<td align=\"center\" bgcolor=\"" runningjobcolor "\">"
}
# Should the status be bolded?
# ----------------------------
if (boldstatus == "yes")
{
tdo=tdo"<b>"
tdc="</b>"tdc
}
status["R"]=tdo"Running"tdc
# If it is a bad job, then
# we assign the badjobcolor
# -------------------------
} else if ($9 ~ /[ABDef]/)
{
if (colorstatusbg == "yes")
# Assign bad jobs the badjobcolor
# -------------------------------
{
tdo = "<td align=\"center\" bgcolor=\"" badjobcolor "\">"
}
# Should the status be bolded?
# ----------------------------
if (boldstatus == "yes")
{
tdo=tdo"<b>"
tdc="</b>"tdc
}
status["A"]=tdo"Aborted"tdc
status["D"]=tdo"Verify Diffs"tdc
status["f"]=tdo"Failed"tdc
# If it is a job with warnings or errors, assign the job the warnjobcolor
# I have never seen a "W" status in the db. Jobs that are "OK -- with warnings"
# still have a "T" jobstatus, but the joberrors field is incremented in the db
# -----------------------------------------------------------------------------
} else if ($9 ~ /[EI]/)
{
if (colorstatusbg == "yes")
# Assign job the warnjobcolor
# ---------------------------
{
tdo = "<td align=\"center\" bgcolor=\"" warnjobcolor "\">"
}
# Should the status be bolded?
# ----------------------------
if (boldstatus == "yes")
{
tdo=tdo"<b>"
tdc="</b>"tdc
}
status["E"]=tdo"OK, w/Errors"tdc
status["I"]=tdo"Incomplete"tdc
}
} else
# $html is not "yes" so statuses will be normal text
# --------------------------------------------------
{
status["A"]=" Aborted "
status["D"]=" Verify Diffs "
status["E"]=" OK, w/Errors "
status["f"]=" Failed "
status["I"]=" Incomplete "
status["R"]=" Running "
status["T"]=" -OK- "
# Since the "W" jobstatus never appears in the DB, we manually
# assign it here so it can be recognized later on in the script
# -------------------------------------------------------------
if ($9 == "T" && $13 != 0)
{ $9 = "W"
status["W"]=" OK/Warnings "
}
}
}
# These status characters seem to only
# be Director "in memory" statuses. They
# do not get entered into the DB ever so we
# cannot catch them with the db query we use
# I might have to query the DIR as well as
# the DB to be able to capture these
# ------------------------------------------
{
status["C"]=" Created "
status["B"]=" Blocked "
status["F"]=" Wait FD "
status["S"]=" Wait SD "
status["m"]=" Wait New Media"
status["M"]=" Wait Mount "
status["s"]=" Wait Storage"
status["j"]=" Wait Job "
status["c"]=" Wait Client "
status["d"]=" Wait Max Jobs"
status["t"]="Wait Start Time"
status["p"]=" Wait Priority"
status["a"]=" Despool Attrs"
status["i"]=" Batch Insert "
status["L"]="Spool Last Data"
}
# Assign words to job type code characters
# ----------------------------------------
{
jobtype["D"]="Admin"
jobtype["B"]="Backup"
jobtype["C"]="Copy"
jobtype["c"]="Control"
jobtype["R"]="Restore"
jobtype["V"]="Verify"
}
# Assign words to job level code characters
# -----------------------------------------
{
level["F"]="Full"
level["I"]="Incr"
level["D"]="Diff"
level["f"]="VFul"
level["-"]="----"
}
# Assign words to Verify job level code characters
# ------------------------------------------------
{
level["A"]="VVol"
level["C"]="VCat"
level["V"]="Init"
level["O"]="VV2C"
level["d"]="VD2C"
}
# Check to see if the job did not "T"erminate OK then increment $awkerr,
# and prepend the JobId with an asterisk for quick visual identification
# of problem jobs.
# Need to choose between a positive or negative test of the job status code
# -------------------------------------------------------------------------
# Negative check - testing for non existence of all "good" status codes
# $9 !~ /[TRCFSMmsjcdtpai]/ { awkerr++; $1 = "* "$1 }
# Positive check - testing the existence of all "bad" status codes
# good { if ($9 ~ /[ABDEIWef]/ || $13 != 0) { awkerr++; if (starbadjobids == "yes") { star = "*" } } }
{ if ($9 ~ /[ABDEIef]/) { awkerr++; if (starbadjobids == "yes") { star = "*" } } }
# If the job is an Admin, Copy, Control,
# Restore, or Migration job it will have
# no real "Level", so we set it to "----"
# ---------------------------------------
{ if ($7 ~ /[CcDRm]/) { $8 = "-" } }
# Print out each job, formatted with the following fields:
# JobId Name Status Errors Type Level Files Bytes StartTime EndTime RunTime
# -------------------------------------------------------------------------
{ if (html == "yes")
{ printf("<tr bgcolor=\"%s\"> \
<td align=\"center\">%s%s%s</td> \
<td>%s</td> \
%s \
<td align=\"right\">%'"'"'d</td> \
<td align=\"center\">%s</td> \
<td align=\"center\">%s</td> \
<td align=\"right\">%'"'"'d</td> \
<td align=\"right\">%'"'"'9.2f GB</td> \
<td align=\"center\">%s %s</td> \
<td align=\"center\">%s %s</td> \
<td align=\"center\">%s</td> \
</tr>\n", \
jobtablejobcolor, star, $1, star, $2, status[$9], $13, jobtype[$7], level[$8], $10, $11/(1024*1024*1024), $3, $4, $5, $6, $12);
} else
{ printf("%s %-7s %-14s %16s %'"'"'12d %8s %6s %'"'"'9d %'"'"'9.2f GB %11s %-9s %-10s %-9s %-9s\n", \
star, $1, $2, status[$9], $13, jobtype[$7], level[$8], $10, $11/(1024*1024*1024), $3, $4, $5, $6, $12);
}
}
# Count the number of jobs
# ------------------------
{ totaljobs++ }
# Count the number of files and bytes from all jobs
# -------------------------------------------------
{ files += $10 }
{ bytes += $11 }
# Finally, print out the summaries
# --------------------------------
END {
if (printsummary == "yes")
{ if (html == "yes")
{
printf("</table>")
printf("<br>\
<hr align=\"left\" width=\"25%\">\
<table width=\"25%\">\
<tr><td><b>Total Jobs</b></td><td align=\"center\"><b>:</b></td> <td align=\"right\"><b>%'"'"'15d</b></td></tr>\
<tr><td><b>Total Files</b></td><td align=\"center\"><b>:</b></td> <td align=\"right\"><b>%'"'"'15d</b></td></tr>\
<tr><td><b>Total Bytes</b></td><td align=\"center\"><b>:</b></td> <td align=\"right\"><b>%'"'"'15.2f GB</b></td></tr>\
</table>\
<hr align=\"left\" width=\"25%\">",\
totaljobs, files, bytes/(1024*1024*1024));
} else
printf("\
=================================\n\
Total Jobs : %'"'"'15d\n\
Total Files : %'"'"'15d\n\
Total Bytes : %'"'"'15.2f GB\n\
=================================\n",\
totaljobs, files, bytes/(1024*1024*1024));
} exit awkerr }
')
# Any failed jobs, or jobs with errors?
# -------------------------------------
numbadjobs=$?
# Do we email the job summaries?
# ------------------------------
if [ ${emailsummaries} == "yes" ]; then
# Get all of the jobids from the query results, but
# skip any running jobs because they will not have
# a summary in the DB until the job has terminated
# -------------------------------------------------
alljobids=$(echo "${queryresult}" \
| awk '{ if ($7 != "R") printf("%s ", $1) }')
# If no jobids were returned, skip creating
# the header and looping through zero records
# -------------------------------------------
if [ ! -z "${alljobids}" ]; then
# Generate the header
# -------------------
msg="${msg}"$(
if [ ${html} == "yes" ]; then
echo "<pre>====================================="
else
echo -e "\n\n\n====================================="
fi
echo "Job Summaries of All Terminated Jobs:"
echo "====================================="
)
# Get the job logs from all jobs and just grep for the summary
# ------------------------------------------------------------
for jobid in ${alljobids}; do
msg="${msg}"$(
echo -e "\n--------------"
echo "JobId: ${jobid}"
echo "--------------"
echo "llist joblog jobid=${jobid}" | ${bcbin} -c ${bcconfig} | grep -A31 "^ Build OS:"
echo "======================================================================"
)
done
if [ ${html} == "yes" ]; then
msg=${msg}$(echo "</pre>")
fi
fi
fi
# Do we email the bad job logs with the report?
# ---------------------------------------------
if [ ${emailbadlogs} == "yes" ]; then
# Get the badjobs, or the good jobs with
# JobErrors != 0 from the query results
# --------------------------------------
badjobids=$(echo "${queryresult}" \
| awk '{ if ($9 ~ /[ABDEIef]/ || ($9 == "T" && $13 != 0)) printf("%s ", $1) }')
# If no jobids were returned, skip creating
# the header and looping through zero records
# -------------------------------------------
if [ ! -z "${badjobids}" ]; then
# Generate the header
# -------------------
msg="${msg}"$(
if [ ${html} == "yes" ]; then
echo "<pre>=========================================================="
else
echo -e "\n\n\n=========================================================="
fi
echo "Job logs of failed jobs, or good jobs with JobErrors != 0:"
echo "=========================================================="
)
# Get the bad job's log from the Director via bconsole
# ----------------------------------------------------
for jobid in ${badjobids}; do
msg="${msg}"$(
echo -e "\n--------------"
echo "JobId: ${jobid}"
echo "--------------"
echo "llist joblog jobid=${jobid}" | ${bcbin} -c ${bcconfig}
echo "======================================================================"
)
done
if [ ${html} == "yes" ]; then
msg=${msg}$(echo "</pre>")
fi
fi
fi
# Prepend the header to the $msg output
# -------------------------------------
if [ ${html} == "yes" ]; then
msg="<html>
<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
<style>
body {font-family:$fontfamily; font-size:$fontsize;} td {font-size:$fontsizejobinfo;} pre {font-size:$fontsizesumlog;}
</style>
</head>
<body>
<p><u><b>${emailtitle}</b></u></p>
<table width=\"98%\" align=\"center\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
<tr bgcolor=\"${jobtableheadercolor}\">
<td align=\"center\"><b>Job ID</b></td>
<td align=\"center\"><b>Job Name</b></td>
<td align=\"center\"><b>Status</b></td>
<td align=\"center\"><b>Errors</b></td>
<td align=\"center\"><b>Type</b></td>
<td align=\"center\"><b>Level</b></td>
<td align=\"center\"><b>Files</b></td>
<td align=\"center\"><b>Bytes</b></td>
<td align=\"center\"><b>Start Time</b></td>
<td align=\"center\"><b>End Time</b></td>
<td align=\"center\"><b>Run Time</b></td>
</tr>
${msg}
</body></html>"
else
msg="
${emailtitle}
------------------------------------------
JobId Job Name Status Errors Type Level Files Bytes Start Time End Time Run Time
----- -------------- --------------- ---------- ------- ----- -------- ----------- ------------------- ------------------- --------
${msg}"
fi
fi # If there were zero results returned from the
# SQL the query, we skip the entire awk script,
# and a lot of other bash stuff that generates
# the email body and we end up here
# -------------------------------------------------
if [ ${results} -eq 0 ]; then
status="No Jobs Have Been Run"
subjecticon="${nojobsicon}"
msg="Nothing to see here..."
else
# Totally unnecessary, but, well... OCD... :)
# --------------------------------------------
if [ ${numbadjobs} -ne 0 ]; then
if [ ${numbadjobs} -eq 1 ]; then
job="Job"
else
job="Jobs"
fi
status="(${numbadjobs}) ${job} with Errors"
subjecticon="${badjobsicon}"
else
status="All Jobs OK"
subjecticon="${goodjobsicon}"
fi
fi
# More silliness
# --------------
if [ ${hist} -eq 1 ]; then
hour="Hour"
else
hour="Hours"
fi
# Email the report
# ----------------
(
echo "To: ${admin}"
echo "From: ${admin}"
if [ ${addsubjecticon} == "yes" ]; then
echo "Subject: ${subjecticon} ${server} - ${status} in the Past ${hist} ${hour}"
else
echo "Subject: ${server} - ${status} in the Past ${hist} ${hour}"
fi
if [ ${html} == "yes" ] && [ ${results} -ne 0 ]; then
echo "Content-Type: text/html"
echo "MIME-Version: 1.0"
fi
echo ""
echo "${msg}"
) | /usr/sbin/sendmail -t
# -------------
# End of script
# -------------
# ----------
# Change Log
# ----------
# ----------------------------
# William A. Arlofski
# Reverse Polarity, LLC
# helpdesk@revpol.com
# http://www.revpol.com/bacula
# ----------------------------
#
#
# 20130428 - Initial release
# Generate and email a basic Bacula backup report
# 1st command line parameter is expected to be a
# number of hours. No real error checking is done
#
# 20131224 - Removed "AND JobStatus='T'" to get all backup jobs
# whether running, or completed with errors etc.
# - Added Several fields "StartTime", "EndTime",
# "JobFiles"
# - Removed "JobType" because we are only selecting
# jobs of type "Backup" (AND Type='B')
# - Modified header lines and printf lines for better
# formatting
#
# 20140107 - Modified script to include more information and cleaned
# up the output formatting
#
# 20150704 - Added ability to work with MySQL or Postgresql
#
# 20150723 - Modified query, removed "Type='B'" clause to catch all jobs,
# including Copy jobs, Admin jobs etc. Modified header, and
# output string to match new query and include job's "Type"
# column.
#
# 20170225 - Rewrote awk script so that a status/summary could be set in
# the email report's subject. eg:
# Subject: "serverName - All Jobs OK in the past x hours"
# Subject: "serverName - x Jobs FAILED in the past y hours"
#
# 20170303 - Fixed output in cases where there are jobs running and there
# is no "Stop Time" for a job.
#
# 20170406 - Some major modifications:
# - Added feature to spell out words instead of using the
# single character codes for Job type, Job Status, and
# Job Level - Including the different levels for Verify
# jobs
# - If a job terminates with an error or warning, then the
# job's line in the output is prepended with an asterisk
# "*" for quick visual identification
# - Modified the outputs of the files and bytes fields to
# include commas when the number is > 999
# - Added totals to the end of the report for Jobs, Files,
# and Bytes
# - Added $sortfield and $sortorder variables to allow output
# to be sorted as desired
# - Set the level of a job to "----" when the level is not
# applicable as in Restore jobs, Admin jobs etc.
#
# 20170408 - Some minor cleanup, and moving things around
# - Added $emailsummaries variable to append the job summaries
# to the end of the report.
# - Added $emailbadlogs variable to append full joblogs of jobs
# which have failed or jobs with errors to the end of the report
# for quick access to investigate failed jobs.
#
# 20170417 - Added some tests for binaries and the bconsole config file
#
# 20170429 - Thanks to Chris Couture for contacting me and submitting a
# working query for MariaDB. I have added 'mariadb' as a new
# dbtype option.
# - Thanks to Chris Couture for the ideas and some code examples
# to create an HTML email.
# - Added $html variable to enable HTML emails.
# - Added $boldstatus variable to make the Status <b>bold</b>
# in HTML emails.
# - Added $colorstatusbg variable to color the background of
# the Status cell in HTML emails.
# - Thanks to Chris Couture for the idea of adding RunTime
# to the email output.
# - Thanks to Chris Couture for the idea of using some unicode
# characters (a 'checkmark'or a bold 'x') in the Subject:
# to quickly see if everything ran OK.
# - Added $addsubjecticon variable to enable/disable the
# prepending of this icon to the Subject.
# - Added $printsumary variable to give the option to print the
# total Jobs, Files, and Bytes after the job listing table.
# - Added $starbadjobids variable to enable/disable prepending
# the bad jobids with an asterisk "*".
# - Modified the way the email is built at the end. Thanks to
# Chris Courture again for this nice idea.
# - Added $jobtableheadercolor, $jobtablejobcolor, $goodjobcolor,
# $goodjobwitherrcolor, $runningjobcolor, $warnjobcolor, and
# $badjobcolor variables to colorize HTML emails
# - Added $emailtitle variable for the title at the top
# - Added $fontfamily, $fontsize, $fontsizejobinfo, and $fontsizesumlog
# variables to allow styling of the HTML output (Thanks again Chris)
# - Added $nojobsicon, $goodjobsicon, and $badjobsicon variables to
# allow setting the prepended utf-8 subject icon character
# - Reformatted things so that if there are no jobs returned by the
# SQL query, the email message sent is nice and short
# - Modified the license to allow for inclusion into Bacula Community,
# and possibly the Enterprise Edition releases
#
# 20170430 - Modified the order of the fields to make more sense
# - Re-aligned the text email so that when an asterisk is pre-pended it
# does not shift the whole line
#
# 20170508 - Re-worked some of the logic so that good jobs (JobStatus="T") which
# have errors will have their status listed as "OK/Warnings", and it
# will not trigger as a "bad job" on the JobErrors, so it will not
# have an asterisk prepended to the JobId in the job listing. I think
# this fix is more of a temporary change in the hopes that a "W"
# status to represent "good jobs with warnings" is implemented in the
# db in the future.
# - Added an "Errors" column to the table to show "JobErrors" from the
# db.
# - Some minor variable name changes and other minor changes
#
# 20170511 - Minor adjustments to the alignment formatting of the text email
# - Minor 'case' changes to a couple levels (Init & VCat)
#
# ------------------------------------------------------------------------------
# I like small tabs. Use :set list in vim to see tabbing etc
# vim: set tabstop=2:softtabstop=2:shiftwidth=2 #

View File

@ -0,0 +1,33 @@
print fail_time
print my_name
print exename
print exepath
print assert_msg
print db_engine_name
print version
print host_os
print distname
print distver
print host_name
print dist_name
show env TestName
bt
thread apply all bt
f 0
info locals
f 1
info locals
f 2
info locals
f 3
info locals
f 4
info locals
f 5
info locals
f 6
info locals
f 7
info locals
detach
quit

View File

@ -0,0 +1,25 @@
#!/bin/sh
#
# Copyright (C) 2000-2017 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# This script deletes a catalog dump
#
db_name=bacula
rm -f /var/lib/bacula/${db_name}.sql
#
# We recommend that you email a copy of the bsr file that was
# made for the Job that runs this script to yourself.
# You just need to put the bsr file in /opt/bacula/bsr/catalog.bsr
# or adjust the script below. Please replace all %xxx% with what
# is appropriate at your site.
#
#${exec_prefix}/bin/bsmtp -h %smtp-server% -s "catalog.bsr" \
# %your-name@company.org% </opt/bacula/bsr/catalog.bsr
#
# The following script will email a summary of the backup jobs that
# were completed in the last 24 hours
#/etc/bacula/scripts/baculabackupreport 24
#

View File

@ -0,0 +1,397 @@
#!/bin/sh
#
# Bacula interface to virtual autoloader using disk storage
#
# Written by Kern Sibbald
#
# 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.
# If you set in your Device resource
#
# Changer Command = "path-to-this-script/disk-changer %c %o %S %a %d"
# you will have the following input to this script:
#
# So Bacula will always call with all the following arguments, even though
# in come cases, not all are used. Note, the Volume name is not always
# included.
#
# disk-changer "changer-device" "command" "slot" "archive-device" "drive-index" "volume"
# $1 $2 $3 $4 $5 $6
#
# By default the autochanger has 10 Volumes and 1 Drive.
#
# Note: For this script to work, you *must" specify
# Device Type = File
# in each of the Devices associated with your AutoChanger resource.
#
# changer-device is the name of a file that overrides the default
# volumes and drives. It may have:
# maxslot=n where n is one based (default 10)
# maxdrive=m where m is zero based (default 1 -- i.e. 2 drives)
#
# This code can also simulate barcodes. You simply put
# a list of the slots and barcodes in the "base" directory/barcodes.
# See below for the base directory definition. Example of a
# barcodes file:
# /var/bacula/barcodes
# 1:Vol001
# 2:Vol002
# ...
#
# archive-device is the name of the base directory where you want the
# Volumes stored appended with /drive0 for the first drive; /drive1
# for the second drive, ... For example, you might use
# /var/bacula/drive0 Note: you must not have a trailing slash, and
# the string (e.g. /drive0) must be unique, and it must not match
# any other part of the directory name. These restrictions could be
# easily removed by any clever script jockey.
#
# Full example: disk-changer /var/bacula/conf load 1 /var/bacula/drive0 0 TestVol001
#
# The Volumes will be created with names slot1, slot2, slot3, ... maxslot in the
# base directory. In the above example the base directory is /var/bacula.
# However, as with tapes, their Bacula Volume names will be stored inside the
# Volume label. In addition to the Volumes (e.g. /var/bacula/slot1,
# /var/bacula/slot3, ...) this script will create a /var/bacula/loadedn
# file to keep track of what Slot is loaded. You should not change this file.
#
# Modified 8 June 2010 to accept Volume names from the calling program as arg 6.
# In this case, rather than storing the data in slotn, it is stored in the
# Volume name. Note: for this to work, Volume names may not include spaces.
#
wd=/var/lib/bacula
#
# log whats done
#
# to turn on logging, uncomment the following line
#touch $wd/disk-changer.log
#
dbgfile="$wd/disk-changer.log"
debug() {
if test -f $dbgfile; then
echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
fi
}
#
# Create a temporary file
#
make_temp_file() {
TMPFILE=`mktemp -t mtx.XXXXXXXXXX`
if test x${TMPFILE} = x; then
TMPFILE="$wd/disk-changer.$$"
if test -f ${TMPFILE}; then
echo "Temp file security problem on: ${TMPFILE}"
exit 1
fi
fi
}
# check parameter count on commandline
#
check_parm_count() {
pCount=$1
pCountNeed=$2
if test $pCount -lt $pCountNeed; then
echo "usage: disk-changer ctl-device command [slot archive-device drive-index]"
echo " Insufficient number of arguments arguments given."
if test $pCount -lt 2; then
echo " Mimimum usage is first two arguments ..."
else
echo " Command expected $pCountNeed arguments"
fi
exit 1
fi
}
#
# Strip off the final name in order to get the Directory ($dir)
# that we are dealing with.
#
get_dir() {
bn=`basename $device`
dir=`echo "$device" | sed -e s%/$bn%%g`
if [ ! -d $dir ]; then
echo "ERROR: Autochanger directory \"$dir\" does not exist."
echo " You must create it."
exit 1
fi
}
#
# Get the Volume name from the call line, or directly from
# the volslotn information.
#
get_vol() {
havevol=0
debug "vol=$volume"
if test "x$volume" != x && test "x$volume" != "x*NONE*" ; then
debug "touching $dir/$volume"
touch $dir/$volume
echo "$volume" >$dir/volslot${slot}
havevol=1
elif [ -f $dir/volslot${slot} ]; then
volume=`cat $dir/volslot${slot}`
havevol=1
fi
}
# Setup arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
drive=$5
volume=$6
# set defaults
maxdrive=1
maxslot=10
# Pull in conf file
if [ -f $ctl ]; then
. $ctl
fi
# Check for special cases where only 2 arguments are needed,
# all others are a minimum of 5
#
case $2 in
list|listall)
check_parm_count $# 2
;;
slots)
check_parm_count $# 2
;;
transfer)
check_parm_count $# 4
if [ $slot -gt $maxslot ]; then
echo "Slot ($slot) out of range (1-$maxslot)"
debug "Error: Slot ($slot) out of range (1-$maxslot)"
exit 1
fi
;;
*)
check_parm_count $# 5
if [ $drive -gt $maxdrive ]; then
echo "Drive ($drive) out of range (0-$maxdrive)"
debug "Error: Drive ($drive) out of range (0-$maxdrive)"
exit 1
fi
if [ $slot -gt $maxslot ]; then
echo "Slot ($slot) out of range (1-$maxslot)"
debug "Error: Slot ($slot) out of range (1-$maxslot)"
exit 1
fi
;;
esac
debug "Parms: $ctl $cmd $slot $device $drive $volume $havevol"
case $cmd in
unload)
debug "Doing disk -f $ctl unload $slot $device $drive $volume"
get_dir
if [ -f $dir/loaded${drive} ]; then
ld=`cat $dir/loaded${drive}`
else
echo "Storage Element $slot is Already Full"
debug "Unload error: $dir/loaded${drive} is already unloaded"
exit 1
fi
if [ $slot -eq $ld ]; then
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
unlink ${device}.add 2>/dev/null >/dev/null
rm -f ${device} ${device}.add
else
echo "Storage Element $slot is Already Full"
debug "Unload error: $dir/loaded${drive} slot=$ld is already unloaded"
exit 1
fi
;;
load)
debug "Doing disk $ctl load $slot $device $drive $volume"
get_dir
i=0
# Check if slot already in a drive
while [ $i -le $maxdrive ]; do
if [ -f $dir/loaded${i} ]; then
ld=`cat $dir/loaded${i}`
else
ld=0
fi
if [ $ld -eq $slot ]; then
echo "Drive ${i} Full (Storage element ${ld} loaded)"
debug "Load error: Cannot load Slot=${ld} in drive=$drive. Already in drive=${i}"
exit 1
fi
i=`expr $i + 1`
done
# Check if we have a Volume name
get_vol
if [ $havevol -eq 0 ]; then
# check if slot exists
if [ ! -f $dir/slot${slot} ] ; then
echo "source Element Address $slot is Empty"
debug "Load error: source Element Address $slot is Empty"
exit 1
fi
fi
if [ -f $dir/loaded${drive} ]; then
ld=`cat $dir/loaded${drive}`
else
ld=0
fi
if [ $ld -ne 0 ]; then
echo "Drive ${drive} Full (Storage element ${ld} loaded)"
echo "Load error: Drive ${drive} Full (Storage element ${ld} loaded)"
exit 1
fi
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
unlink ${device}.add 2>/dev/null >/dev/null
rm -f ${device} ${device}.add
if [ $havevol -ne 0 ]; then
ln -s $dir/$volume $device
ln -s $dir/${volume}.add ${device}.add
rtn=$?
else
ln -s $dir/slot${slot} $device
ln -s $dir/slot${slot}.add ${device}.add
rtn=$?
fi
if [ $rtn -eq 0 ]; then
echo $slot >$dir/loaded${drive}
fi
exit $rtn
;;
list)
debug "Doing disk -f $ctl -- to list volumes"
get_dir
if [ -f $dir/barcodes ]; then
cat $dir/barcodes
else
i=1
while [ $i -le $maxslot ]; do
slot=$i
volume=
get_vol
if [ $havevol -eq 0 ]; then
echo "$i:"
else
echo "$i:$volume"
fi
i=`expr $i + 1`
done
fi
exit 0
;;
listall)
# ***FIXME*** must add new Volume stuff
make_temp_file
debug "Doing disk -f $ctl -- to list volumes"
get_dir
if [ ! -f $dir/barcodes ]; then
exit 0
fi
# we print drive content seen by autochanger
# and we also remove loaded media from the barcode list
i=0
while [ $i -le $maxdrive ]; do
if [ -f $dir/loaded${i} ]; then
ld=`cat $dir/loaded${i}`
v=`awk -F: "/^$ld:/"' { print $2 }' $dir/barcodes`
echo "D:$i:F:$ld:$v"
echo "^$ld:" >> $TMPFILE
fi
i=`expr $i + 1`
done
# Empty slots are not in barcodes file
# When we detect a gap, we print missing rows as empty
# At the end, we fill the gap between the last entry and maxslot
grep -v -f $TMPFILE $dir/barcodes | sort -n | \
perl -ne 'BEGIN { $cur=1 }
if (/(\d+):(.+)?/) {
if ($cur == $1) {
print "S:$1:F:$2\n"
} else {
while ($cur < $1) {
print "S:$cur:E\n";
$cur++;
}
}
$cur++;
}
END { while ($cur < '"$maxslot"') { print "S:$cur:E\n"; $cur++; } } '
rm -f $TMPFILE
exit 0
;;
transfer)
# ***FIXME*** must add new Volume stuff
get_dir
make_temp_file
slotdest=$device
if [ -f $dir/slot{$slotdest} ]; then
echo "destination Element Address $slot is Full"
exit 1
fi
if [ ! -f $dir/slot${slot} ] ; then
echo "source Element Address $slot is Empty"
exit 1
fi
echo "Transfering $slot to $slotdest"
mv $dir/slot${slot} $dir/slot{$slotdest}
mv $dir/slot${slot}.add $dir/slot{$slotdest}.add
if [ -f $dir/barcodes ]; then
sed "s/^$slot:/$slotdest:/" > $TMPFILE
sort -n $TMPFILE > $dir/barcodes
fi
exit 0
;;
loaded)
debug "Doing disk -f $ctl $drive -- to find what is loaded"
get_dir
if [ -f $dir/loaded${drive} ]; then
a=`cat $dir/loaded${drive}`
else
a="0"
fi
debug "Loaded: drive=$drive is $a"
echo $a
exit
;;
slots)
debug "Doing disk -f $ctl -- to get count of slots"
echo $maxslot
;;
esac

84
Dir Config/scripts/isworm Normal file
View File

@ -0,0 +1,84 @@
#!/bin/sh
#
# Copyright (C) 2000-2018 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Bacula interface to get worm status of tape
#
# isworm %l (control device name)
#
# Typical output:
# sdparm --page=0x1D -f /dev/sg0
# /dev/st0: HP Ultrium 5-SCSI I5AW [tape]
# Medium configuration (SSC) mode page:
# WORMM 1 [cha: n, def: 1, sav: 1]
# WMLR 1 [cha: n, def: 1, sav: 1]
# WMFR 2 [cha: n, def: 2, sav: 2]
#
# Where WORMM is worm mode
# WMLR is worm mode label restrictions
# 0 - No blocks can be overwritten
# 1 - Some types of format labels may not be overwritten
# 2 - All format labels can be overwritten
# WMFR is worm mode filemark restrictions
# 0-1 - Reserved
# 2 - Any number of filemarks immediately preceding EOD can be
# overwritten except file mark closest to BOP (beginning of
# partition).
# 3 - Any number of filemarks immediately preceding the EOD
# can be overwritten
# 4-FF - Reserved
#
if [ x$1 = x ] ; then
echo "First argument missing. Must be device control name."
exit 1
fi
sdparm=`which sdparm`
if [ x${sdparm} = x ] ; then
echo "sdparm program not found, but is required."
exit 0
fi
#
# This should be the correct way to determine if the tape is WORM
# but it does not work for mhvtl. Comment out the next 5 lines
# and the code that follows will detect correctly on mhtvl.
#
worm=`$sdparm --page=0x1D -f $1 |grep " *WORMM"|cut -b12-16|sed "s:^ *::"`
if [ $? = 0 ] ; then
echo $worm
exit 0
fi
tapeinfo=`which tapeinfo`
if [ x${tapeinfo} = x ] ; then
echo "tapeinfo program not found, but is required."
exit 1
fi
#
# Unfortunately IBM and HP handle the Medium Type differently,
# so we detect the vendor and get the appropriate Worm flag.
#
vendor=`$tapeinfo -f $1|grep "^Vendor ID:"|cut -b13-15`
if [ x$vendor = xHP ] ; then
worm=`$tapeinfo -f $1|grep "^Medium Type: 0x"|cut -b16-16`
echo $worm
exit 0
fi
if [ x$vendor = xIBM ] ; then
worm=`$tapeinfo -f $1|grep "^Medium Type: 0x"|cut -b17-17`
if [ x$worm = xc ]; then
echo "1"
exit 0
fi
if [ x$worm = xC ]; then
echo "1"
exit 0
fi
fi
echo "0"
exit 0

View File

@ -0,0 +1,111 @@
#!/bin/sh
#
# Copyright (C) 2000-2017 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# This script dumps your Bacula catalog in ASCII format
# It works for MySQL, SQLite, and PostgreSQL
#
# $1 is the name of the database to be backed up and the name
# of the output file (default = bacula).
# $2 is the user name with which to access the database
# (default = bacula).
# $3 is the password with which to access the database or "" if no password
# (default ""). WARNING!!! Passing the password via the command line is
# insecure and should not be used since any user can display the command
# line arguments and the environment using ps. Please consult your
# MySQL or PostgreSQL manual for secure methods of specifying the
# password.
# $4 is the host on which the database is located
# (default "")
# $5 is the type of database
#
#
default_db_type=postgresql
user=${2:-bacula}
#
# See if the fifth argument is a valid backend name.
# If so the user overrides the default database backend.
#
if [ $# -ge 5 ]; then
case $5 in
sqlite3)
db_type=$5
;;
mysql)
db_type=$5
;;
postgresql)
db_type=$5
;;
ingres)
db_type=$5
;;
*)
;;
esac
fi
#
# If no new db_type is gives use the default db_type.
#
if [ -z "${db_type}" ]; then
db_type="${default_db_type}"
fi
cd /var/lib/bacula
rm -f $1.sql
case ${db_type} in
sqlite3)
BINDIR=/usr/bin
echo ".dump" | ${BINDIR}/sqlite3 $1.db >$1.sql
;;
mysql)
BINDIR=/usr/bin
if test $# -gt 2; then
MYSQLPASSWORD=" --password=$3"
else
MYSQLPASSWORD=""
fi
if test $# -gt 3; then
MYSQLHOST=" --host=$4"
else
MYSQLHOST=""
fi
${BINDIR}/mysqldump -u ${user}${MYSQLPASSWORD}${MYSQLHOST} -f --opt $1 >$1.sql
;;
postgresql)
BINDIR=/usr/bin
if test $# -gt 2; then
PGPASSWORD=$3
export PGPASSWORD
fi
if test $# -gt 3; then
PGHOST=" --host=$4"
else
PGHOST=""
fi
# you could also add --compress for compression. See man pg_dump
exec ${BINDIR}/pg_dump -c $PGHOST -U $user $1 >$1.sql
;;
esac
#
# To read back a MySQL database use:
# cd /var/lib/bacula
# rm -f ${BINDIR}/../var/bacula/*
# mysql <bacula.sql
#
# To read back a SQLite database use:
# cd /var/lib/bacula
# rm -f bacula.db
# sqlite bacula.db <bacula.sql
#
# To read back a PostgreSQL database use:
# cd /var/lib/bacula
# dropdb bacula
# createdb bacula -T template0 -E SQL_ASCII
# psql bacula <bacula.sql
#

View File

@ -0,0 +1,195 @@
#!/usr/bin/perl
#
# Author: Eric Bollengier, Copyright, 2006-2017
# License: BSD 2-Clause; see file LICENSE-FOSS
use strict;
=head1 SCRIPT
This script dumps your Bacula catalog in ASCII format
It works for MySQL, SQLite, and PostgreSQL
=head1 USAGE
make_catalog_backup.pl [-m] MyCatalog
=head1 LICENSE
Author: Eric Bollengier, 2010
License: BSD 2-Clause; see file LICENSE-FOSS
=cut
my $cat = shift or die "Usage: $0 [-m] catalogname";
my $mode = "dump";
if ($cat eq '-m') {
$mode = "analyse";
$cat = shift or die "Usage: $0 [-m] catalogname";
}
my $dir_conf='/usr/sbin/dbcheck -B -c /etc/bacula/bacula-dir.conf';
my $wd = "/var/lib/bacula";
sub dump_sqlite3
{
my %args = @_;
exec("echo .dump | sqlite3 '$wd/$args{db_name}.db' > '$wd/$args{db_name}.sql'");
print "Error while executing sqlite dump $!\n";
return 1;
}
# TODO: use just ENV and drop the pg_service.conf file
sub setup_env_pgsql
{
my %args = @_;
my $username = getpwuid $ENV{'UID'};
umask(0077);
if ($args{db_address}) {
$ENV{PGHOST}=$args{db_address};
}
if ($args{db_socket}) {
$ENV{PGHOST}=$args{db_socket};
}
if ($args{db_port}) {
$ENV{PGPORT}=$args{db_port};
}
if ($args{db_user}) {
$ENV{PGUSER}=$args{db_user};
}
if ($args{db_password}) {
$ENV{PGPASSWORD}=$args{db_password};
}
$ENV{PGDATABASE}=$args{db_name};
system("echo '\\q' | HOME='$wd' psql") == 0 or die "$username doesn't have access to the catalog database\n";
}
sub dump_pgsql
{
my %args = @_;
setup_env_pgsql(%args);
exec("HOME='$wd' pg_dump -c > '$wd/$args{db_name}.sql'");
print "Error while executing postgres dump $!\n";
return 1; # in case of error
}
sub analyse_pgsql
{
my %args = @_;
setup_env_pgsql(%args);
my @output =`LANG=C HOME='$wd' vacuumdb -z 2>&1`;
my $exitcode = $? >> 8;
print grep { !/^WARNING:\s+skipping\s\"(pg_|sql_)/ } @output;
if ($exitcode != 0) {
print "Error while executing postgres analyse. Exitcode=$exitcode\n";
}
return $exitcode;
}
sub setup_env_mysql
{
my %args = @_;
umask(0077);
unlink("$wd/.my.cnf");
open(MY, ">$wd/.my.cnf")
or die "Can't open $wd/.my.cnf for writing $@";
$args{db_address} = $args{db_address} || "localhost";
my $addr = "host=$args{db_address}";
if ($args{db_socket}) { # unix socket is fastest than net socket
$addr = "socket=\"$args{db_socket}\"";
}
my $mode = $args{mode} || 'client';
print MY "[$mode]
$addr
user=\"$args{db_user}\"
password=\"$args{db_password}\"
";
if ($args{db_port}) {
print MY "port=$args{db_port}\n";
}
close(MY);
}
sub dump_mysql
{
my %args = @_;
setup_env_mysql(%args);
exec("HOME='$wd' mysqldump -f --opt $args{db_name} > '$wd/$args{db_name}.sql'");
print "Error while executing mysql dump $!\n";
return 1;
}
sub analyse_mysql
{
my %args = @_;
$args{mode} = 'mysqlcheck';
setup_env_mysql(%args);
exec("HOME='$wd' mysqlcheck -a $args{db_name}");
print "Error while executing mysql analyse $!\n";
return 1;
}
sub handle_catalog
{
my ($mode, %args) = @_;
if ($args{db_type} eq 'SQLite3') {
$ENV{PATH}="/usr/bin:$ENV{PATH}";
if ($mode eq 'dump') {
dump_sqlite3(%args);
}
} elsif ($args{db_type} eq 'PostgreSQL') {
$ENV{PATH}="/usr/bin:$ENV{PATH}";
if ($mode eq 'dump') {
dump_pgsql(%args);
} else {
analyse_pgsql(%args);
}
} elsif ($args{db_type} eq 'MySQL') {
$ENV{PATH}="/usr/bin:$ENV{PATH}";
if ($mode eq 'dump') {
dump_mysql(%args);
} else {
analyse_mysql(%args);
}
} else {
die "This database type isn't supported";
}
}
open(FP, "$dir_conf -C '$cat'|") or die "Can't get catalog information $@";
# catalog=MyCatalog
# db_type=SQLite
# db_name=regress
# db_driver=
# db_user=regress
# db_password=
# db_address=
# db_port=0
# db_socket=
my %cfg;
while(my $l = <FP>)
{
if ($l =~ /catalog=(.+)/) {
if (exists $cfg{catalog} and $cfg{catalog} eq $cat) {
exit handle_catalog($mode, %cfg);
}
%cfg = (); # reset
}
if ($l =~ /(\w+)=(.+)/) {
$cfg{$1}=$2;
}
}
if (exists $cfg{catalog} and $cfg{catalog} eq $cat) {
exit handle_catalog($mode, %cfg);
}
print "Can't find your catalog ($cat) in director configuration\n";
exit 1;

View File

@ -0,0 +1,51 @@
#!/usr/bin/gawk -f
# extract.awk script expects Catalog definition in a form of:
# Catalog {
# Name = NameOfCatalog
# dbname = ""; DB Address = ""; user = ""; password = ""; DB Socket = ""; DB Port = ""
# }
#
BEGIN { RS= "}" ; FS="[;\n]+"}
function trim(v) {
## Remove leading and trailing spaces
sub(/^ */,"",v)
sub(/ *$/,"",v)
return v
}
$0 ~ /Catalog[[:space:]]*{/ {
for ( i = 1; i <= NF ; i++)
{
split($i,a,"=")
if (a[1] ~ /dbname/)
dbname = trim(gensub("\"","","g",a[2])) # remove " char
if (a[1] ~ /user/)
user = trim(gensub("\"","","g",a[2]))
if (a[1] ~ /Name/)
catname = trim(gensub("\"","","g",a[2]))
if (a[1] ~ /password/)
password = trim(gensub("\"","","g",a[2]))
if (a[1] ~ /DB Address/)
dbaddress = trim(gensub("\"","","g",a[2]))
if (a[1] ~ /DB Socket/)
dbsocket = trim(gensub("\"","","g",a[2]))
if (a[1] ~ /DB Port/)
dbport = trim(gensub("\"","","g",a[2]))
}
if (catname == cat1 || catname == cat2 || catname == cat3 || catname == cat4) {
if (dbaddress == "") #Not optional in the case of MySQL
dbaddress = "localhost"
system("rm -rf /var/lib/bacula/pg_service.conf")
system("touch /var/lib/bacula/pg_service.conf")
system("chmod 600 /var/lib/bacula/pg_service.conf")
printf "[bacula]\n dbname=%s\n user=%s\n password=%s\n",dbname,user,password >> "/var/lib/bacula/pg_service.conf"
if (dbport != "")
printf " port=%s\n",dbport >> "/var/lib/bacula/pg_service.conf"
system("HOME=/var/lib/bacula PGSERVICE=bacula PGSYSCONFDIR=/var/lib/bacula pg_dump > /var/lib/bacula/bacula.sql")
}
}

View File

@ -0,0 +1,353 @@
#!/bin/sh
#
# 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.
#
# If you set in your Device resource
#
# Changer Command = "path-to-this-script/mtx-changer %c %o %S %a %d"
# you will have the following input to this script:
#
# So Bacula will always call with all the following arguments, even though
# in come cases, not all are used.
#
# mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index"
# $1 $2 $3 $4 $5
#
# for example:
#
# mtx-changer /dev/sg0 load 1 /dev/nst0 0 (on a Linux system)
#
# will request to load the first cartidge into drive 0, where
# the SCSI control channel is /dev/sg0, and the read/write device
# is /dev/nst0.
#
# The commands are:
# Command Function
# unload unload a given slot
# load load a given slot
# loaded which slot is loaded?
# list list Volume names (requires barcode reader)
# slots how many slots total?
# listall list all info
# transfer
#
# Slots are numbered from 1 ...
# Drives are numbered from 0 ...
#
#
# If you need to an offline, refer to the drive as $4
# e.g. mt -f $4 offline
#
# Many changers need an offline after the unload. Also many
# changers need a sleep 60 after the mtx load.
#
# N.B. If you change the script, take care to return either
# the mtx exit code or a 0. If the script exits with a non-zero
# exit code, Bacula will assume the request failed.
#
# myversion must be the same as version in mtx-changer.conf
myversion=2
# source our conf file
if test ! -f /etc/bacula/scripts/mtx-changer.conf ; then
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "ERROR: /etc/bacula/scripts/mtx-changer.conf file not found!!!!"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
exit 1
fi
. /etc/bacula/scripts/mtx-changer.conf
if test "${version}" != "${myversion}" ; then
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "ERROR: /etc/bacula/scripts/mtx-changer.conf has wrong version. Wanted ${myversion}, got ${version} !!!"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
exit 1
fi
MTX=/usr/sbin/mtx
if test ${debug_log} -ne 0 ; then
touch /var/lib/bacula/mtx.log
fi
dbgfile="/var/lib/bacula/mtx.log"
debug() {
if test -f $dbgfile -a ${debug_level} -ge $1; then
echo "`date +%m%d-%H:%M:%S.%N|cut -c1-16` ${chgr_id} $2" >> $dbgfile
fi
}
#
# Create a temporary file
#
make_temp_file() {
TMPFILE=`mktemp /var/lib/bacula/mtx.XXXXXXXXXX`
if test x${TMPFILE} = x; then
TMPFILE="/var/lib/bacula/mtx.$$"
if test -f ${TMPFILE}; then
echo "ERROR: Temp file security problem on: ${TMPFILE}"
exit 1
fi
fi
}
#
# Create a temporary file for stderr
#
# Note, this file is used because sometime mtx emits
# unexpected error messages followed by the output
# expected during success.
# So we separate STDOUT and STDERR in
# certain of the mtx commands. The contents of STDERR
# is then printed after the STDOUT produced by mtx
# thus we sometimes get better changer results.
#
make_err_file() {
ERRFILE=`mktemp /var/lib/bacula/mtx.err.XXXXXXXXXX`
if test x${ERRFILE} = x; then
ERRFILE="/var/lib/bacula/mtx.err.$$"
if test -f ${ERRFILE}; then
echo "ERROR: Temp file security problem on: ${ERRFILE}"
exit 1
fi
fi
}
#
# The purpose of this function to wait a maximum
# time for the drive. It will
# return as soon as the drive is ready, or after
# waiting a maximum of 300 seconds.
# Note, this is very system dependent, so if you are
# not running on Linux, you will probably need to
# re-write it, or at least change the grep target.
# We've attempted to get the appropriate OS grep targets
# in the code at the top of this script.
#
wait_for_drive() {
i=0
while [ $i -le 300 ]; do # Wait max 300 seconds
if mt -f $1 status 2>&1 | grep "${ready}" >/dev/null 2>&1; then
break
fi
debug $dbglvl "Device $1 - not ready, retrying..."
sleep 1
i=`expr $i + 1`
done
}
# check parameter count on commandline
#
check_parm_count() {
pCount=$1
pCountNeed=$2
if test $pCount -lt $pCountNeed; then
echo "ERROR: usage: mtx-changer ctl-device command [slot archive-device drive-index]"
echo " Insufficient number of arguments given."
if test $pCount -lt 2; then
echo " Mimimum usage is first two arguments ..."
else
echo " Command expected $pCountNeed arguments"
fi
exit 1
fi
}
# Check for special cases where only 2 arguments are needed,
# all others are a minimum of 5
#
case $2 in
list|listall)
check_parm_count $# 2
;;
slots)
check_parm_count $# 2
;;
transfer)
check_parm_count $# 4
;;
*)
check_parm_count $# 5
;;
esac
# Setup arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
drive=$5
debug $dbglvl "Parms: $ctl $cmd $slot $device $drive"
case $cmd in
unload)
if test ${offline} -eq 1 ; then
mt -f $device offline
fi
if test ${offline_sleep} -ne 0 ; then
sleep ${offline_sleep}
fi
make_err_file
for i in 1 2 3 4 5 ; do
debug $idbglvl "Doing mtx -f $ctl unload slot=$slot drv=$drive"
${MTX} -f $ctl unload $slot $drive 2>${ERRFILE}
rtn=$?
if test $rtn -eq 0 ; then
break
fi
grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null
if test $? -ne 0 ; then
break
fi
sleep $i
done
cat ${ERRFILE}
rm -f ${ERRFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl unload slot=$slot drv=$drive"
fi
exit $rtn
;;
load)
make_err_file
for i in 1 2 3 4 5 ; do
debug $idbglvl "Doing mtx -f $ctl load slot=$slot drv=$drive"
${MTX} -f $ctl load $slot $drive 2>${ERRFILE}
rtn=$?
if test $rtn -eq 0 ; then
break
fi
grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null
if test $? -ne 0 ; then
break
fi
sleep $i
done
if test ${load_sleep} -ne 0 ; then
sleep ${load_sleep}
fi
wait_for_drive $device
cat ${ERRFILE}
rm -f ${ERRFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl load slot=$slot drv=$drive"
fi
exit $rtn
;;
list)
make_temp_file
if test ${inventory} -ne 0 ; then
${MTX} -f $ctl inventory
fi
debug $dbglvl "Doing mtx -f $ctl list"
${MTX} -f $ctl status >${TMPFILE}
rtn=$?
if test ${vxa_packetloader} -ne 0 ; then
cat ${TMPFILE} | grep " *Storage Element [0-9]*:.*Full" | sed "s/ Storage Element //" | sed "s/Full :VolumeTag=//"
else
cat ${TMPFILE} | grep " Storage Element [0-9]*:.*Full" | awk "{print \$3 \$4}" | sed "s/Full *\(:VolumeTag=\)*//"
fi
cat ${TMPFILE} | grep "^Data Transfer Element [0-9]*:Full (Storage Element [0-9]" | awk '{printf "%s:%s\n",$7,$10}'
rm -f ${TMPFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl list"
fi
exit $rtn
;;
listall)
# Drive content: D:Drive num:F:Slot loaded:Volume Name
# D:0:F:2:vol2 or D:Drive num:E
# D:1:F:42:vol42
# D:3:E
#
# Slot content:
# S:1:F:vol1 S:Slot num:F:Volume Name
# S:2:E or S:Slot num:E
# S:3:F:vol4
#
# Import/Export tray slots:
# I:10:F:vol10 I:Slot num:F:Volume Name
# I:11:E or I:Slot num:E
# I:12:F:vol40
make_temp_file
if test ${inventory} -ne 0 ; then
${MTX} -f $ctl inventory
fi
debug $dbglvl "Doing mtx -f $ctl -- to list all"
${MTX} -f $ctl status >${TMPFILE}
rtn=$?
# can be converted to awk+sed+cut, see below
perl -ne '
/Data Transfer Element (\d+):Empty/ && print "D:$1:E\n";
/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "D:$1:F:$2:$4\n";
/Storage Element (\d+):Empty/ && print "S:$1:E\n";
/Storage Element (\d+):Full( :VolumeTag=(.+))?/ && print "S:$1:F:$3\n";
/Storage Element (\d+) IMPORT.EXPORT:Empty/ && print "I:$1:E\n";
/Storage Element (\d+) IMPORT.EXPORT:Full( :VolumeTag=(.+))?/ && print "I:$1:F:$3\n";' ${TMPFILE}
# If perl isn't installed, you can use by those commands
#cat ${TMPFILE} | grep "Data Transfer Element" | awk "{print \"D:\"\$4 \$7 \$9 \$10}" | sed "s/=/:/" | sed "s/Full/F:/" | sed "s/Empty/E/"
#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep -v "IMPORT/EXPORT" | awk "{print \"S:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep "IMPORT/EXPORT" | awk "{print \"I:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
rm -f ${TMPFILE} >/dev/null 2>&1
exit $rtn
;;
transfer)
slotdest=$device
debug $dbglvl "Doing transfer from $slot to $slotdest"
${MTX} -f $ctl transfer $slot $slotdest
rtn=$?
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl transfer from=$slot to=$slotdest"
fi
exit $rtn
;;
loaded)
make_temp_file
debug $idbglvl "Doing mtx -f $ctl $drive -- to find what is loaded"
${MTX} -f $ctl status >${TMPFILE}
rtn=$?
cat ${TMPFILE} | grep "^Data Transfer Element $drive:Full" | awk "{print \$7}"
cat ${TMPFILE} | grep "^Data Transfer Element $drive:Empty" | awk "{print 0}"
rm -f ${TMPFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl loaded drv=$drive"
fi
exit $rtn
;;
slots)
debug $dbglvl "Doing mtx -f $ctl -- to get count of slots"
${MTX} -f $ctl status | grep " *Storage Changer" | awk "{print \$5}"
rtn=$?
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl slots"
fi
;;
esac

View File

@ -0,0 +1,89 @@
#
# Copyright (C) 2000-2015 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
#
# This file is sourced by the mtx-changer script every time it runs.
# You can put your site customization here, and when you do an
# upgrade, the process should not modify this file. Thus you
# preserve your mtx-changer configuration.
#
# We update the version when an incompatible change
# to mtx-changer or this conf file is made, such as
# adding a new required variable.
version=2
# Set to 1 if you want to do offline before unload
offline=0
# Set to amount of time in seconds to wait after an offline
offline_sleep=0
# Set to amount of time in seconds to wait after a load
load_sleep=0
# Set to 1 to do an inventory before a status. Not normally needed.
inventory=0
# If you have a VXA PacketLoader, it might display a different
# Storage Element line, so try setting the following to 1
vxa_packetloader=0
#
# Debug logging
#
# If you have multiple SD's, set this differently for each one
# so you know which message comes from which one. This can
# be any string, and will appear in each debug message just
# after the time stamp.
chgr_id=0
# Set to 1 if you want debug info written to a log
debug_log=0
# Set to debug level you want to see
# 0 is off
# 10 is important events (load, unload, loaded)
# 100 is everything
# Note debug_log must be set to 1 for anything to be generated
#
debug_level=10
# Debug levels by importance
# Normally you do not need to change this
dbglvl=100
# More important messages
idbglvl=10
#
# mt status output
# SunOS No Additional Sense
# FreeBSD Current Driver State: at rest.
# Linux ONLINE
# Note Debian has a different mt than the standard Linux version.
# When no tape is in the drive it waits 2 minutes.
# When a tape is in the drive, it prints user unfriendly output.
# Note, with Ubuntu Gusty (8.04), there are two versions of mt,
# so we attempt to figure out which one.
#
OS=`uname`
case ${OS} in
SunOS)
ready="No Additional Sense"
;;
FreeBSD)
ready="Current Driver State: at rest."
;;
Linux)
ready="ONLINE"
if test -f /etc/debian_version ; then
mt --version|grep "mt-st" >/dev/null 2>&1
if test $? -eq 1 ; then
ready="drive status"
fi
fi
;;
esac

View File

@ -0,0 +1,7 @@
#
# See the file <bacula-source>/examples/sample-query.sql
# for some sample queries.
#
# 1
:The default file is empty, see sample-query.sql (in /opt/bacula/scripts or <bacula-source>/examples) for samples
SELECT 'See sample-query.sql (in /opt/bacula/scripts or <bacula-source>/examples) for samples' AS Info;

View File

@ -0,0 +1,5 @@
#!/bin/sh
# This script written by joe
# This will inject "release" into bconsole
echo release storage=Iron-Autochanger slot=0 | bconsole

View File

@ -0,0 +1,68 @@
#!/bin/sh
#
# Copyright (C) 2000-2016 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Bacula interface to tapeinfo to get tape alerts
#
# tapealert %l (control device name)
#
# Note: you must have in your SD Device resource:
# Alert Command = /full-path/tapealert %l
# Control Device = /dev/sg0n (where this is the scsi control
# device for the device you are using).
#
# Note: to test
# 1. uncomment out the DEBUG=1 line below
# 2. Possibly remove or add TapeAlert[nn]: that you want to test.
# Note, the message following the : is not used.
# 3. Run Bacula
#
#DEBUG=1
tapeinfo=`which tapeinfo`
if [ x${tapeinfo} = x ] ; then
echo "tapeinfo program not found, but is required."
exit 1
fi
if [ x$1 = x ] ; then
echo "First argument missing. Must be device control name."
exit 1
fi
if [ x$DEBUG = x ] ; then
$tapeinfo -f $1 |grep "^TapeAlert" - |cut -b1-13
exit $?
else
# For testing only
cat <<EOF |grep "^TapeAlert" - |cut -b1-13
Product Type: Tape Drive
Vendor ID: 'IBM '
Product ID: 'ULTRIUM-TD6 '
Revision: 'G350'
Attached Changer API: No
SerialNumber: 'F3A2930090'
TapeAlert[3]: Hard Error: Uncorrectable read/write error.
TapeAlert[5]: Read Failure: Tape faulty or tape drive broken.
TapeAlert[39]: Undefined.
MinBlock: 1
MaxBlock: 8388608
SCSI ID: 9
SCSI LUN: 0
Ready: yes
BufferedMode: yes
Medium Type: 0x58
Density Code: 0x58
BlockSize: 0
DataCompEnabled: yes
DataCompCapable: yes
DataDeCompEnabled: yes
CompType: 0xff
DeCompType: 0xff
EOF
fi

31
Notes.md Normal file
View File

@ -0,0 +1,31 @@
when you buy new tapes, install them in your library and run the
*label pool=Scratch storage=Iron-Autochanger slots=19,20,21,22,23,24,25,26,27,28,29 barcodes
command to write the initial label onto the tape (so bacula knows it's allowed to use the tape) and then bacula and scratch pool will do everything else
libraries have slots, that command says "load the tape from slot 1 into the drive, and write a label to it matching its barcode. then repeat for slot 2. then repeat for slot 3"
# mt -f /dev/nst0 erase 1 to quick erase disk
*status dir days=15
<kenwoodfox> Can i change that behavior?
<kenwoodfox> https://cdn.discordapp.com/attachments/306060488163328001/715312740876550164/unknown.png
<kenwoodfox> What if have a job that takes up 4.5 tapes, and later on, i purge the first four tapes that are 100% full will the last tape that only has half of its volume used by the now purged job go back to being Append or will i have to pudge that tape too?
* Topic for #bacula is "If you can't send to the channel, please register with FreeNode. || Please don't ask if you can ask... just ask || Please use pastebin.ca to paste || auth problems? http://tinyurl.com/47u2lck || SQLite no longer supported http://bit.ly/dUw2zN (login as anonymous/anonymous)"
* Topic set by dvl!~dvl@freebsd/developer/dvl on 2016-06-08 23:22:21 UTC
[@ChanServ] This is the support channel for Bacula, an open-source cross-platform enterprise backup solution from one of the principal authors of apcupsd. If you have questions, please just speak up - ve don't bite, and ve von't suck your blut. Honest!
* Homepage for #bacula is http://www.bacula.org
*** Mode #bacula +nt by orwell.freenode.net
* Channel #bacula created on 2005-08-08 07:51:28 UTC
- {Day changed to Thursday, May 28, 2020}
<kenwoodfox_> Do my incremental, difs and fulls have to line up? is that the way to do it?
<kenwoodfox_> Like doing one incremental twice a week, retaining them for four weeks, doing a diff every four weeks, retaining them for three months, and doing four full backups a year
<kenwoodfox_> I only have so many tapes,
<kenwoodfox_> Right now i do an incremental twice a week, a full backup four times a year and a diff backup every other month, just starting out so i dont know how much that will be eventually
<optiz0r> <kenwoodfox> Can i change that behavior? << No. you can only force bacula to reuse a purged volume by making sure it cannot label new volumes. i.e. by disabling autolabelling or by setting a PoolMaximumPoolVolumes to an upper limit on the size of the pool
<optiz0r> prune/purge only affects volumes in the full or used states. If a volume is half-full and still in append state, deleting the job will not cause that volume to be purged. Instead it will remain in the append state, the next job will continue writing in the second half of the tape, and only when it is filled does the expiration counter start
<optiz0r> if you know you have half-full volumes and you're about to delete the contents of that volume, you would want to manually set the VolStatus to Full and then prune it
<optiz0r> <kenwoodfox_> Do my incremental, difs and fulls have to line up? is that the way to do it? << I keep each successive level for longer than the interval of the parent level. e.g. if I take monthly fulls, weekly diffs, and daily incrementals, I would retain the incrementals for at least 5 weeks, and incrementals for at least 10 days
<optiz0r> also for each level, make sure you are retaining volumes for longer than the interval. If you had monthly fulls in a 30-day pool, you would only be keeping one backup at a time. and if the most recent backup failed (e.g. network interruptionm, server crash) then you no longer have any viable backups

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# Bacula
Dis is bacula

51
SD Config/bacula-barcodes Normal file
View File

@ -0,0 +1,51 @@
#
# Bacula barcode simulation file
# used by ${PREFIX}/sbin/chio-bacula (FreeBSD)
#
# The volumenames are returned by the "changer list" command
# labeling in the console is done by "label barcodes"
# (then all volumes belog to the default pool).
# All Lines with an "#" at the bedinning are ignored
#
# !!!! If you export an tape and reinsert another one,
# !!!! don't forget to change the volume name in this file!
#
1:Volume1-100
2:Volume1-101
3:Volume1-102
4:Volume1-103
5:Volume1-104
6:Volume1-105
7:Volume1-106
8:Volume1-107
9:Volume1-108
10:Volume1-109
11:Volume1-110
12:Volume1-111
#
# Further volumes exported from the changer
#
# 36GB AIT2 tapes
#Volume1-100
#Volume1-101
#Volume1-102
#Volume1-103
#Volume1-104
#Volume1-105
#Volume1-106
#Volume1-107
#Volume1-108
#Volume1-109
#Volume1-110
#Volume1-111
#Volume1-112
#Volume1-113
#Volume1-114
#Volume1-115
#
# 50GB AIT2 tapes
#Volume2-200
#Volume2-201
#Volume2-202
#Volume2-203
#Volume2-204

View File

@ -0,0 +1,51 @@
#
# Bacula barcode simulation file
# used by ${PREFIX}/sbin/chio-bacula (FreeBSD)
#
# The volumenames are returned by the "changer list" command
# labeling in the console is done by "label barcodes"
# (then all volumes belog to the default pool).
# All Lines with an "#" at the bedinning are ignored
#
# !!!! If you export an tape and reinsert another one,
# !!!! don't forget to change the volume name in this file!
#
1:Volume1-100
2:Volume1-101
3:Volume1-102
4:Volume1-103
5:Volume1-104
6:Volume1-105
7:Volume1-106
8:Volume1-107
9:Volume1-108
10:Volume1-109
11:Volume1-110
12:Volume1-111
#
# Further volumes exported from the changer
#
# 36GB AIT2 tapes
#Volume1-100
#Volume1-101
#Volume1-102
#Volume1-103
#Volume1-104
#Volume1-105
#Volume1-106
#Volume1-107
#Volume1-108
#Volume1-109
#Volume1-110
#Volume1-111
#Volume1-112
#Volume1-113
#Volume1-114
#Volume1-115
#
# 50GB AIT2 tapes
#Volume2-200
#Volume2-201
#Volume2-202
#Volume2-203
#Volume2-204

View File

@ -0,0 +1,44 @@
@/usr/local/etc/bacula/client-myclient.conf
@/usr/local/etc/bacula/filesets.conf
@/usr/local/etc/bacula/schedules.conf
@/usr/local/etc/bacula/pools.conf
Director {
Name = ZincBaculaDirector
Password = "iamnotacrook"
QueryFile = "/usr/local/share/bacula/query.sql"
PidDirectory = "/var/run"
WorkingDirectory = "/usr/local/bacula/working"
Messages = MyMessages
}
Catalog {
Name = MyCatalog
dbname = bacula
dbaddress = localhost
user = bacula
password = ""
}
Storage {
Name = MyFirstStorage
Address = localhost
Password = "iamnotacrook"
Device = MyFirstStorageDevice
Media Type = MyMediaType
}
Messages {
Name = MyMessages
mailcommand = "/usr/local/sbin/bsmtp -h localhost -f \"\(Bacula\) %r\" -s \"Bacula: %t %e of %c %l\" %r"
operatorcommand = "/usr/local/sbin/bsmtp -h localhost -f \"\(Bacula\) %r\" -s \"Bacula: Intervention needed for %j\" %r"
operator = root@localhost = mount
mail = root@localhost = all
console = all
append = "/var/log/bacula.log" = all, !skipped, !restored
catalog = all, !skipped, !saved
}

View File

@ -0,0 +1,323 @@
#
# Default Bacula Director Configuration file
#
# The only thing that MUST be changed is to add one or more
# file or directory names in the Include directive of the
# FileSet resource.
#
# For Bacula release 9.6.3 (09 March 2020) -- freebsd 11.3-RELEASE-p8
#
# You might also want to change the default email address
# from root to your address. See the "mail" and "operator"
# directives in the Messages resource.
#
# Copyright (C) 2000-2020 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Director { # define myself
Name = 113amd64-quarterly-job-07-dir
DIRport = 9101 # where we listen for UA connections
QueryFile = "/usr/local/share/bacula/query.sql"
WorkingDirectory = "/var/db/bacula"
PidDirectory = "/var/run"
Maximum Concurrent Jobs = 20
Password = "fX+8It4fQAIBIyYpBGbbyOcMcFkCLfnBHwkgmrEgRa5V" # Console password
Messages = Daemon
}
JobDefs {
Name = "DefaultJob"
Type = Backup
Level = Incremental
Client = 113amd64-quarterly-job-07-fd
FileSet = "Full Set"
Schedule = "WeeklyCycle"
Storage = File1
Messages = Standard
Pool = File
SpoolAttributes = yes
Priority = 10
Write Bootstrap = "/var/db/bacula/%c.bsr"
}
#
# Define the main nightly save backup job
# By default, this job will back up to disk in /tmp
Job {
Name = "BackupClient1"
JobDefs = "DefaultJob"
}
#Job {
# Name = "BackupClient2"
# Client = 113amd64-quarterly-job-072-fd
# JobDefs = "DefaultJob"
#}
#Job {
# Name = "BackupClient1-to-Tape"
# JobDefs = "DefaultJob"
# Storage = LTO-4
# Spool Data = yes # Avoid shoe-shine
# Pool = Default
#}
#}
# Backup the catalog database (after the nightly save)
Job {
Name = "BackupCatalog"
JobDefs = "DefaultJob"
Level = Full
FileSet="Catalog"
Schedule = "WeeklyCycleAfterBackup"
# This creates an ASCII copy of the catalog
# Arguments to make_catalog_backup.pl are:
# make_catalog_backup.pl <catalog-name>
RunBeforeJob = "/usr/local/share/bacula/make_catalog_backup.pl MyCatalog"
# This deletes the copy of the catalog
RunAfterJob = "/usr/local/share/bacula/delete_catalog_backup"
Write Bootstrap = "/var/db/bacula/%n.bsr"
Priority = 11 # run after main backup
}
#
# Standard Restore template, to be changed by Console program
# Only one such job is needed for all Jobs/Clients/Storage ...
#
Job {
Name = "RestoreFiles"
Type = Restore
Client=113amd64-quarterly-job-07-fd
Storage = File1
# The FileSet and Pool directives are not used by Restore Jobs
# but must not be removed
FileSet="Full Set"
Pool = File
Messages = Standard
Where = /tmp/bacula-restores
}
# List of files to be backed up
FileSet {
Name = "Full Set"
Include {
Options {
signature = MD5
}
#
# Put your list of files here, preceded by 'File =', one per line
# or include an external list with:
#
# File = <file-name
#
# Note: / backs up everything on the root partition.
# if you have other partitions such as /usr or /home
# you will probably want to add them too.
#
# By default this is defined to point to the Bacula binary
# directory to give a reasonable FileSet to backup to
# disk storage during initial testing.
#
File = /usr/local/sbin
}
#
# If you backup the root directory, the following two excluded
# files can be useful
#
Exclude {
File = /var/db/bacula
File = /tmp
File = /proc
File = /tmp
File = /sys
File = /.journal
File = /.fsck
}
}
#
# When to do the backups, full backup on first sunday of the month,
# differential (i.e. incremental since full) every other sunday,
# and incremental backups other days
Schedule {
Name = "WeeklyCycle"
Run = Full 1st sun at 23:05
Run = Differential 2nd-5th sun at 23:05
Run = Incremental mon-sat at 23:05
}
# This schedule does the catalog. It starts after the WeeklyCycle
Schedule {
Name = "WeeklyCycleAfterBackup"
Run = Full sun-sat at 23:10
}
# This is the backup of the catalog
FileSet {
Name = "Catalog"
Include {
Options {
signature = MD5
}
File = "/var/db/bacula/bacula.sql"
}
}
# Client (File Services) to backup
Client {
Name = 113amd64-quarterly-job-07-fd
Address = localhost
FDPort = 9102
Catalog = MyCatalog
Password = "ttyesBkRnbjPesjkbNIfOc2zLScaks3A8q/JW7GOfG0x" # password for FileDaemon
File Retention = 60 days # 60 days
Job Retention = 6 months # six months
AutoPrune = yes # Prune expired Jobs/Files
}
#
# Second Client (File Services) to backup
# You should change Name, Address, and Password before using
#
#Client {
# Name = 113amd64-quarterly-job-072-fd
# Address = localhost2
# FDPort = 9102
# Catalog = MyCatalog
# Password = "ttyesBkRnbjPesjkbNIfOc2zLScaks3A8q/JW7GOfG0x2" # password for FileDaemon 2
# File Retention = 60 days # 60 days
# Job Retention = 6 months # six months
# AutoPrune = yes # Prune expired Jobs/Files
#}
# Definition of file Virtual Autochanger device
Autochanger {
Name = File1
# Do not use "localhost" here
Address = localhost # N.B. Use a fully qualified name here
SDPort = 9103
Password = "dTo6A76E6WP4wFOgPuUv2OxTzNRqKfPfnh0Bn+C4Yg7t"
Device = FileChgr1
Media Type = File1
Maximum Concurrent Jobs = 10 # run up to 10 jobs a the same time
Autochanger = File1 # point to ourself
}
# Definition of a second file Virtual Autochanger device
# Possibly pointing to a different disk drive
Autochanger {
Name = File2
# Do not use "localhost" here
Address = localhost # N.B. Use a fully qualified name here
SDPort = 9103
Password = "dTo6A76E6WP4wFOgPuUv2OxTzNRqKfPfnh0Bn+C4Yg7t"
Device = FileChgr2
Media Type = File2
Autochanger = File2 # point to ourself
Maximum Concurrent Jobs = 10 # run up to 10 jobs a the same time
}
# Definition of LTO-4 tape Autochanger device
#Autochanger {
# Name = LTO-4
# Do not use "localhost" here
# Address = localhost # N.B. Use a fully qualified name here
# SDPort = 9103
# Password = "dTo6A76E6WP4wFOgPuUv2OxTzNRqKfPfnh0Bn+C4Yg7t" # password for Storage daemon
# Device = LTO-4 # must be same as Device in Storage daemon
# Media Type = LTO-4 # must be same as MediaType in Storage daemon
# Autochanger = LTO-4 # enable for autochanger device
# Maximum Concurrent Jobs = 10
#}
# Generic catalog service
Catalog {
Name = MyCatalog
dbname = "bacula"; dbuser = "bacula"; dbpassword = ""
}
# Reasonable message delivery -- send most everything to email address
# and to the console
Messages {
Name = Standard
#
# NOTE! If you send to two email or more email addresses, you will need
# to replace the %r in the from field (-f part) with a single valid
# email address in both the mailcommand and the operatorcommand.
# What this does is, it sets the email address that emails would display
# in the FROM field, which is by default the same email as they're being
# sent to. However, if you send email to more than one address, then
# you'll have to set the FROM address manually, to a single address.
# for example, a 'no-reply@mydomain.com', is better since that tends to
# tell (most) people that its coming from an automated source.
#
mailcommand = "/usr/local/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r"
operatorcommand = "/usr/local/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
mail = root@localhost = all, !skipped
operator = root@localhost = mount
console = all, !skipped, !saved
#
# WARNING! the following will create a file that you must cycle from
# time to time as it will grow indefinitely. However, it will
# also keep all your messages if they scroll off the console.
#
append = "/var/log/bacula.log" = all, !skipped
catalog = all
}
#
# Message delivery for daemon messages (no job).
Messages {
Name = Daemon
mailcommand = "/usr/local/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r"
mail = root@localhost = all, !skipped
console = all, !skipped, !saved
append = "/var/log/bacula.log" = all, !skipped
}
# Default pool definition
Pool {
Name = Default
Pool Type = Backup
Recycle = yes # Bacula can automatically recycle Volumes
AutoPrune = yes # Prune expired volumes
Volume Retention = 365 days # one year
Maximum Volume Bytes = 50G # Limit Volume size to something reasonable
Maximum Volumes = 100 # Limit number of Volumes in Pool
}
# File Pool definition
Pool {
Name = File
Pool Type = Backup
Recycle = yes # Bacula can automatically recycle Volumes
AutoPrune = yes # Prune expired volumes
Volume Retention = 365 days # one year
Maximum Volume Bytes = 50G # Limit Volume size to something reasonable
Maximum Volumes = 100 # Limit number of Volumes in Pool
Label Format = "Vol-" # Auto label
}
# Scratch pool definition
Pool {
Name = Scratch
Pool Type = Backup
}
#
# Restricted console used by tray-monitor to get the status of the director
#
Console {
Name = 113amd64-quarterly-job-07-mon
Password = "QJyLdIOlBT8HjOZZoUG07j8dXzZDiBLFv90Dh4ZWUgNj"
CommandACL = status, .status
}

18
SD Config/bacula-fd.conf Normal file
View File

@ -0,0 +1,18 @@
Director { # Director who is allowed to contact us
Name = bacula-dir
Password = "iamnotacrook"
}
FileDaemon {
Name = ZincFD
FDport = 9102 # where we listen for the director
WorkingDirectory = /var/db/bacula
Pid Directory = /var/run
FDAddress = 10.85.3.31 # Address of the SD
}
Messages {
Name = Standard
director = bacula-dir = all, !skipped, !restored
}

View File

@ -0,0 +1,48 @@
#
# Default Bacula File Daemon Configuration file
#
# For Bacula release 9.6.3 (09 March 2020) -- freebsd 11.3-RELEASE-p8
#
# There is not much to change here except perhaps the
# File daemon Name to
#
#
# Copyright (C) 2000-2020 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
#
# List Directors who are permitted to contact this File daemon
#
Director {
Name = 113amd64-quarterly-job-10-dir
Password = "Ts6jjOAKGG0ntHv+YQmR+cDsiezuIEaErotLXv6IzTOQ"
}
#
# Restricted Director, used by tray-monitor to get the
# status of the file daemon
#
Director {
Name = 113amd64-quarterly-job-10-mon
Password = "MSBv8L3qRgEkBixUVm3GhZktGRDLEupWnKhlA+sD9oC/"
Monitor = yes
}
#
# "Global" File daemon configuration specifications
#
FileDaemon { # this is me
Name = 113amd64-quarterly-job-10-fd
FDport = 9102 # where we listen for the director
WorkingDirectory = /var/db/bacula
Pid Directory = /var/run
Maximum Concurrent Jobs = 20
Plugin Directory = /usr/local/lib
}
# Send all messages except skipped files back to Director
Messages {
Name = Standard
director = 113amd64-quarterly-job-10-dir = all, !skipped, !restored
}

View File

@ -0,0 +1,29 @@
Storage {
Name = ZincStorage
SDPort = 9103 # Director's port
WorkingDirectory = "/usr/local/bacula/working"
Pid Directory = "/var/run"
Maximum Concurrent Jobs = 10 # Max jobs it can do at any one time
SDAddress = 10.85.3.31 # Address of the SD
}
Director { # Director who is allowed to contact us
Name = bacula-dir
Password = "iamnotacrook"
}
Device {
Name = MyFirstStorageDevice
Media Type = MyMediaType
Archive Device = /usr/local/bacula/volumes
LabelMedia = yes
Random Access = yes
AutomaticMount = yes
RemovableMedia = no
AlwaysOpen = no
}
Messages {
Name = Standard
director = bacula-dir = all
}

View File

@ -0,0 +1,334 @@
#
# Default Bacula Storage Daemon Configuration file
#
# For Bacula release 9.6.3 (09 March 2020) -- freebsd 11.3-RELEASE-p8
#
# You may need to change the name of your tape drive
# on the "Archive Device" directive in the Device
# resource. If you change the Name and/or the
# "Media Type" in the Device resource, please ensure
# that dird.conf has corresponding changes.
#
#
# Copyright (C) 2000-2020 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Storage { # definition of myself
Name = 113amd64-quarterly-job-07-sd
SDPort = 9103 # Director's port
WorkingDirectory = "/var/db/bacula"
Pid Directory = "/var/run"
Plugin Directory = "/usr/local/lib"
Maximum Concurrent Jobs = 20
}
#
# List Directors who are permitted to contact Storage daemon
#
Director {
Name = 113amd64-quarterly-job-07-dir
Password = "dTo6A76E6WP4wFOgPuUv2OxTzNRqKfPfnh0Bn+C4Yg7t"
}
#
# Restricted Director, used by tray-monitor to get the
# status of the storage daemon
#
Director {
Name = 113amd64-quarterly-job-07-mon
Password = "4+4eEkTKpkP9D5iYJUrXF2eqMct80+cu+Gup42U8ZuDs"
Monitor = yes
}
#
# Note, for a list of additional Device templates please
# see the directory <bacula-source>/examples/devices
# Or follow the following link:
# http://www.bacula.org/git/cgit.cgi/bacula/tree/bacula/examples/devices?h=Branch-7.4
#
#
# Devices supported by this Storage daemon
# To connect, the Director's bacula-dir.conf must have the
# same Name and MediaType.
#
#
# Define a Virtual autochanger
#
Autochanger {
Name = FileChgr1
Device = FileChgr1-Dev1, FileChgr1-Dev2
Changer Command = ""
Changer Device = /dev/null
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /tmp
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
#
# Define a second Virtual autochanger
#
Autochanger {
Name = FileChgr2
Device = FileChgr2-Dev1, FileChgr2-Dev2
Changer Command = ""
Changer Device = /dev/null
}
Device {
Name = FileChgr2-Dev1
Media Type = File2
Archive Device = /tmp
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
Device {
Name = FileChgr2-Dev2
Media Type = File2
Archive Device = /tmp
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
#
# An autochanger device with two drives
#
#Autochanger {
# Name = Autochanger
# Device = Drive-1
# Device = Drive-2
# Changer Command = "/usr/local/share/bacula/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
#}
#Device {
# Name = Drive-1 #
# Drive Index = 0
# Media Type = DLT-8000
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/usr/local/share/bacula/tapealert %l"
#
# #
# # Enable the Alert command only if you have the mtx package loaded
# # Note, apparently on some systems, tapeinfo resets the SCSI controller
# # thus if you turn this on, make sure it does not reset your SCSI
# # controller. I have never had any problems, and smartctl does
# # not seem to cause such problems.
# #
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#Device {
# Name = Drive-2 #
# Drive Index = 1
# Media Type = DLT-8000
# Archive Device = /dev/nst1
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = yes
# # Enable the Alert command only if you have the mtx package loaded
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-2 tape drive
#
#Device {
# Name = LTO-2
# Media Type = LTO-2
# Archive Device = /dev/nrsa0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 3GB
## Changer Command = "/usr/local/share/bacula/mtx-changer %c %o %S %a %d"
## Changer Device = /dev/sg0
## AutoChanger = yes
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-3 tape drive
#
#Device {
# Name = LTO-3
# Media Type = LTO-3
# Archive Device = /dev/nrsa0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 4GB
# Changer Command = "/usr/local/share/bacula/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nrsa0
# Alert Command = "/usr/local/share/bacula/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-4 tape drive
#
#Device {
# Name = LTO-4
# Media Type = LTO-4
# Archive Device = /dev/nrsa0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 5GB
# Changer Command = "/usr/local/share/bacula/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nrsa0
# Alert Command = "/usr/local/share/bacula/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# An HP-UX tape drive
#
#Device {
# Name = Drive-1 #
# Drive Index = 0
# Media Type = DLT-8000
# Archive Device = /dev/rmt/1mnb
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = no
# Two EOF = yes
# Hardware End of Medium = no
# Fast Forward Space File = no
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/rmt/1mnb
# Alert Command = "/usr/local/share/bacula/tapealert %l"
#
# #
# # Enable the Alert command only if you have the mtx package loaded
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A FreeBSD tape drive
#
#Device {
# Name = DDS-4
# Description = "DDS-4 for FreeBSD"
# Media Type = DDS-4
# Archive Device = /dev/nsa1
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes
# Offline On Unmount = no
# Hardware End of Medium = no
# BSF at EOM = yes
# Backward Space Record = no
# Fast Forward Space File = no
# TWO EOF = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nsa1
# Alert Command = "/usr/local/share/bacula/tapealert %l"
#
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# Send all messages to the Director,
# mount messages also are sent to the email address
#
Messages {
Name = Standard
director = 113amd64-quarterly-job-07-dir = all
}

13
SD Config/bconsole.conf Normal file
View File

@ -0,0 +1,13 @@
#
# Bacula User Agent (or Console) Configuration File
#
# Copyright (C) 2000-2020 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Director {
Name = 113amd64-quarterly-job-10-dir
DIRport = 9101
address = localhost
Password = "iamnotacrook"
}

View File

@ -0,0 +1,13 @@
#
# Bacula User Agent (or Console) Configuration File
#
# Copyright (C) 2000-2020 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Director {
Name = 113amd64-quarterly-job-10-dir
DIRport = 9101
address = localhost
Password = "uP67UNGktVWHhGv8XAiGDRkfSx3HKuB4VxgryvXCSmfi"
}

View File

@ -0,0 +1,22 @@
Client {
Name = MyFirstBaculaClient
Password = "iamnotacrook"
Address = localhost
Catalog = MyCatalog
}
Job {
Name = "MyFirstJob"
Client = MyFirstBaculaClient
Type = "Backup"
FileSet = "MyFirstFileSet"
Storage = MyFirstStorage
Schedule = MyFirstSchedule
Messages = MyMessages
Pool = FullFile # required parameter for all Jobs, despite what appears in the next few lines
Full Backup Pool = FullFile
Differential Backup Pool = DiffFile
Incremental Backup Pool = IncrFile
}

View File

@ -0,0 +1,13 @@
FileSet {
Name = "Caleb Backup"
Include {
Options {
signature = MD5
}
File = /usr/local/etc/bacula/
}
Exclude {
File = *~
}
}

41
SD Config/pools.conf.old Normal file
View File

@ -0,0 +1,41 @@
Pool {
Name = FullFile
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 3 years
Storage = MyFirstStorage
Maximum Volume Bytes = 5G
Maximum Volumes = 5
LabelFormat = "FullAuto-"
}
Pool {
Name = DiffFile
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 6 weeks
Storage = MyFirstStorage
Maximum Volume Bytes = 5G
Maximum Volumes = 5
LabelFormat = "DiffAuto-"
}
Pool {
Name = IncrFile
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 3 weeks
Storage = MyFirstStorage
Maximum Volume Bytes = 5G
Maximum Volumes = 5
LabelFormat = "IncrAuto-"
}

View File

@ -0,0 +1,6 @@
Schedule {
Name = MyFirstSchedule
Run = Level=Full 1st sun at 8:15
Run = Level=Differential 2nd-5th sun at 8:15
Run = Level=Incremental mon-sat at 8:15
}

View File

@ -0,0 +1,76 @@
Storage { # definition of myself
Name = temp-iron-sd
SDPort = 9103 # Director's port
WorkingDirectory = "/var/lib/bacula"
Pid Directory = "/run/bacula"
Plugin Directory = "/usr/lib/bacula"
Maximum Concurrent Jobs = 20
SDAddress = 10.85.3.39
}
Director { # Director who is allowed to contact us
Name = bacula-dir
Password = "iamnotacrook"
}
Autochanger {
Name = "Iron-Autochanger"
Device = LTO-3
Changer Device = /dev/sg3
Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
}
Device {
Name = LTO-3
Media Type = LTO-3
Archive Device = /dev/nst0
AutomaticMount = yes; # when device opened, read it
AlwaysOpen = yes;
RemovableMedia = yes;
RandomAccess = no;
Maximum File Size = 4GB
#Changer Command = "/opt/bacula/scripts/mtx-changer %c %o %S %a %d"
Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
Changer Device = /dev/sg3
AutoChanger = yes
# Enable the Alert command only if you have the mtx package loaded
Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
}
#
# A Linux or Solaris LTO-3 tape drive
#
#Device {
# Name = LTO-3
# Media Type = LTO-3
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 4GB
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
Messages {
Name = Standard
director = bacula-dir = all
}

View File

@ -0,0 +1,335 @@
#
# Default Bacula Storage Daemon Configuration file
#
# For Bacula release 9.4.2 (04 February 2019) -- ubuntu 20.04
#
# You may need to change the name of your tape drive
# on the "Archive Device" directive in the Device
# resource. If you change the Name and/or the
# "Media Type" in the Device resource, please ensure
# that dird.conf has corresponding changes.
#
#
# Copyright (C) 2000-2017 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
Storage { # definition of myself
Name = temp-iron-sd
SDPort = 9103 # Director's port
WorkingDirectory = "/var/lib/bacula"
Pid Directory = "/run/bacula"
Plugin Directory = "/usr/lib/bacula"
Maximum Concurrent Jobs = 20
SDAddress = 127.0.0.1
}
#
# List Directors who are permitted to contact Storage daemon
#
Director {
Name = temp-iron-dir
Password = "dA5Tbqzqo4hPGJAEFvy7zD7wGdQZe6HVn"
}
#
# Restricted Director, used by tray-monitor to get the
# status of the storage daemon
#
Director {
Name = temp-iron-mon
Password = "4MvmdJSLRuIGy90YEe2LZNKDg-M42S8I6"
Monitor = yes
}
#
# Note, for a list of additional Device templates please
# see the directory <bacula-source>/examples/devices
# Or follow the following link:
# http://www.bacula.org/git/cgit.cgi/bacula/tree/bacula/examples/devices?h=Branch-7.4
#
#
# Devices supported by this Storage daemon
# To connect, the Director's bacula-dir.conf must have the
# same Name and MediaType.
#
#
# Define a Virtual autochanger
#
Autochanger {
Name = FileChgr1
Device = FileChgr1-Dev1, FileChgr1-Dev2
Changer Command = ""
Changer Device = /dev/null
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
#
# Define a second Virtual autochanger
#
Autochanger {
Name = FileChgr2
Device = FileChgr2-Dev1, FileChgr2-Dev2
Changer Command = ""
Changer Device = /dev/null
}
Device {
Name = FileChgr2-Dev1
Media Type = File2
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
Device {
Name = FileChgr2-Dev2
Media Type = File2
Archive Device = /nonexistant/path/to/file/archive/dir
LabelMedia = yes; # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
Maximum Concurrent Jobs = 5
}
#
# An autochanger device with two drives
#
#Autochanger {
# Name = Autochanger
# Device = Drive-1
# Device = Drive-2
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
#}
#Device {
# Name = Drive-1 #
# Drive Index = 0
# Media Type = DLT-8000
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# #
# # Enable the Alert command only if you have the mtx package loaded
# # Note, apparently on some systems, tapeinfo resets the SCSI controller
# # thus if you turn this on, make sure it does not reset your SCSI
# # controller. I have never had any problems, and smartctl does
# # not seem to cause such problems.
# #
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#Device {
# Name = Drive-2 #
# Drive Index = 1
# Media Type = DLT-8000
# Archive Device = /dev/nst1
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = yes
# # Enable the Alert command only if you have the mtx package loaded
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-2 tape drive
#
#Device {
# Name = LTO-2
# Media Type = LTO-2
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 3GB
## Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
## Changer Device = /dev/sg0
## AutoChanger = yes
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-3 tape drive
#
#Device {
# Name = LTO-3
# Media Type = LTO-3
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 4GB
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A Linux or Solaris LTO-4 tape drive
#
#Device {
# Name = LTO-4
# Media Type = LTO-4
# Archive Device = /dev/nst0
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# Maximum File Size = 5GB
# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d"
# Changer Device = /dev/sg0
# AutoChanger = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# # Enable the Alert command only if you have the mtx package loaded
## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
## If you have smartctl, enable this, it has more info than tapeinfo
## Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# An HP-UX tape drive
#
#Device {
# Name = Drive-1 #
# Drive Index = 0
# Media Type = DLT-8000
# Archive Device = /dev/rmt/1mnb
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes;
# RemovableMedia = yes;
# RandomAccess = no;
# AutoChanger = no
# Two EOF = yes
# Hardware End of Medium = no
# Fast Forward Space File = no
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/rmt/1mnb
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# #
# # Enable the Alert command only if you have the mtx package loaded
# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'"
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# A FreeBSD tape drive
#
#Device {
# Name = DDS-4
# Description = "DDS-4 for FreeBSD"
# Media Type = DDS-4
# Archive Device = /dev/nsa1
# AutomaticMount = yes; # when device opened, read it
# AlwaysOpen = yes
# Offline On Unmount = no
# Hardware End of Medium = no
# BSF at EOM = yes
# Backward Space Record = no
# Fast Forward Space File = no
# TWO EOF = yes
# #
# # New alert command in Bacula 9.0.0
# # Note: you must have the sg3_utils (rpms) or the
# # sg3-utils (deb) installed on your system.
# # and you must set the correct control device that
# # corresponds to the Archive Device
# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nsa1
# Alert Command = "/etc/bacula/scripts/tapealert %l"
#
# If you have smartctl, enable this, it has more info than tapeinfo
# Alert Command = "sh -c 'smartctl -H -l error %c'"
#}
#
# Send all messages to the Director,
# mount messages also are sent to the email address
#
Messages {
Name = Standard
director = temp-iron-dir = all
}

View File

@ -0,0 +1,12 @@
#
# This file has been autogenerated during package installation and
# holds defaults for new Bacula packages installed on this system. It
# is used only when you install a new Bacula package, and can be
# safely removed at any time.
DIRPASSWD=3C28A3DhJVCEoPqm8T6c5D9mmyjlZdaSf
DIRMPASSWD=e-8O6VmwLjMITumbNEZEEiXSkiAjjf6bu
SDPASSWD=dA5Tbqzqo4hPGJAEFvy7zD7wGdQZe6HVn
SDMPASSWD=4MvmdJSLRuIGy90YEe2LZNKDg-M42S8I6
FDPASSWD=aMyJeb4FOPQvCCK7CZdMB0dGm0oxWS26k
FDMPASSWD=0-uGad5qtutFyTPlzsjmdyLDiVaR9ZuBR

View File

@ -0,0 +1,33 @@
print fail_time
print my_name
print exename
print exepath
print assert_msg
print db_engine_name
print version
print host_os
print distname
print distver
print host_name
print dist_name
show env TestName
bt
thread apply all bt
f 0
info locals
f 1
info locals
f 2
info locals
f 3
info locals
f 4
info locals
f 5
info locals
f 6
info locals
f 7
info locals
detach
quit

View File

@ -0,0 +1,397 @@
#!/bin/sh
#
# Bacula interface to virtual autoloader using disk storage
#
# Written by Kern Sibbald
#
# 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.
# If you set in your Device resource
#
# Changer Command = "path-to-this-script/disk-changer %c %o %S %a %d"
# you will have the following input to this script:
#
# So Bacula will always call with all the following arguments, even though
# in come cases, not all are used. Note, the Volume name is not always
# included.
#
# disk-changer "changer-device" "command" "slot" "archive-device" "drive-index" "volume"
# $1 $2 $3 $4 $5 $6
#
# By default the autochanger has 10 Volumes and 1 Drive.
#
# Note: For this script to work, you *must" specify
# Device Type = File
# in each of the Devices associated with your AutoChanger resource.
#
# changer-device is the name of a file that overrides the default
# volumes and drives. It may have:
# maxslot=n where n is one based (default 10)
# maxdrive=m where m is zero based (default 1 -- i.e. 2 drives)
#
# This code can also simulate barcodes. You simply put
# a list of the slots and barcodes in the "base" directory/barcodes.
# See below for the base directory definition. Example of a
# barcodes file:
# /var/bacula/barcodes
# 1:Vol001
# 2:Vol002
# ...
#
# archive-device is the name of the base directory where you want the
# Volumes stored appended with /drive0 for the first drive; /drive1
# for the second drive, ... For example, you might use
# /var/bacula/drive0 Note: you must not have a trailing slash, and
# the string (e.g. /drive0) must be unique, and it must not match
# any other part of the directory name. These restrictions could be
# easily removed by any clever script jockey.
#
# Full example: disk-changer /var/bacula/conf load 1 /var/bacula/drive0 0 TestVol001
#
# The Volumes will be created with names slot1, slot2, slot3, ... maxslot in the
# base directory. In the above example the base directory is /var/bacula.
# However, as with tapes, their Bacula Volume names will be stored inside the
# Volume label. In addition to the Volumes (e.g. /var/bacula/slot1,
# /var/bacula/slot3, ...) this script will create a /var/bacula/loadedn
# file to keep track of what Slot is loaded. You should not change this file.
#
# Modified 8 June 2010 to accept Volume names from the calling program as arg 6.
# In this case, rather than storing the data in slotn, it is stored in the
# Volume name. Note: for this to work, Volume names may not include spaces.
#
wd=/var/lib/bacula
#
# log whats done
#
# to turn on logging, uncomment the following line
#touch $wd/disk-changer.log
#
dbgfile="$wd/disk-changer.log"
debug() {
if test -f $dbgfile; then
echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
fi
}
#
# Create a temporary file
#
make_temp_file() {
TMPFILE=`mktemp -t mtx.XXXXXXXXXX`
if test x${TMPFILE} = x; then
TMPFILE="$wd/disk-changer.$$"
if test -f ${TMPFILE}; then
echo "Temp file security problem on: ${TMPFILE}"
exit 1
fi
fi
}
# check parameter count on commandline
#
check_parm_count() {
pCount=$1
pCountNeed=$2
if test $pCount -lt $pCountNeed; then
echo "usage: disk-changer ctl-device command [slot archive-device drive-index]"
echo " Insufficient number of arguments arguments given."
if test $pCount -lt 2; then
echo " Mimimum usage is first two arguments ..."
else
echo " Command expected $pCountNeed arguments"
fi
exit 1
fi
}
#
# Strip off the final name in order to get the Directory ($dir)
# that we are dealing with.
#
get_dir() {
bn=`basename $device`
dir=`echo "$device" | sed -e s%/$bn%%g`
if [ ! -d $dir ]; then
echo "ERROR: Autochanger directory \"$dir\" does not exist."
echo " You must create it."
exit 1
fi
}
#
# Get the Volume name from the call line, or directly from
# the volslotn information.
#
get_vol() {
havevol=0
debug "vol=$volume"
if test "x$volume" != x && test "x$volume" != "x*NONE*" ; then
debug "touching $dir/$volume"
touch $dir/$volume
echo "$volume" >$dir/volslot${slot}
havevol=1
elif [ -f $dir/volslot${slot} ]; then
volume=`cat $dir/volslot${slot}`
havevol=1
fi
}
# Setup arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
drive=$5
volume=$6
# set defaults
maxdrive=1
maxslot=10
# Pull in conf file
if [ -f $ctl ]; then
. $ctl
fi
# Check for special cases where only 2 arguments are needed,
# all others are a minimum of 5
#
case $2 in
list|listall)
check_parm_count $# 2
;;
slots)
check_parm_count $# 2
;;
transfer)
check_parm_count $# 4
if [ $slot -gt $maxslot ]; then
echo "Slot ($slot) out of range (1-$maxslot)"
debug "Error: Slot ($slot) out of range (1-$maxslot)"
exit 1
fi
;;
*)
check_parm_count $# 5
if [ $drive -gt $maxdrive ]; then
echo "Drive ($drive) out of range (0-$maxdrive)"
debug "Error: Drive ($drive) out of range (0-$maxdrive)"
exit 1
fi
if [ $slot -gt $maxslot ]; then
echo "Slot ($slot) out of range (1-$maxslot)"
debug "Error: Slot ($slot) out of range (1-$maxslot)"
exit 1
fi
;;
esac
debug "Parms: $ctl $cmd $slot $device $drive $volume $havevol"
case $cmd in
unload)
debug "Doing disk -f $ctl unload $slot $device $drive $volume"
get_dir
if [ -f $dir/loaded${drive} ]; then
ld=`cat $dir/loaded${drive}`
else
echo "Storage Element $slot is Already Full"
debug "Unload error: $dir/loaded${drive} is already unloaded"
exit 1
fi
if [ $slot -eq $ld ]; then
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
unlink ${device}.add 2>/dev/null >/dev/null
rm -f ${device} ${device}.add
else
echo "Storage Element $slot is Already Full"
debug "Unload error: $dir/loaded${drive} slot=$ld is already unloaded"
exit 1
fi
;;
load)
debug "Doing disk $ctl load $slot $device $drive $volume"
get_dir
i=0
# Check if slot already in a drive
while [ $i -le $maxdrive ]; do
if [ -f $dir/loaded${i} ]; then
ld=`cat $dir/loaded${i}`
else
ld=0
fi
if [ $ld -eq $slot ]; then
echo "Drive ${i} Full (Storage element ${ld} loaded)"
debug "Load error: Cannot load Slot=${ld} in drive=$drive. Already in drive=${i}"
exit 1
fi
i=`expr $i + 1`
done
# Check if we have a Volume name
get_vol
if [ $havevol -eq 0 ]; then
# check if slot exists
if [ ! -f $dir/slot${slot} ] ; then
echo "source Element Address $slot is Empty"
debug "Load error: source Element Address $slot is Empty"
exit 1
fi
fi
if [ -f $dir/loaded${drive} ]; then
ld=`cat $dir/loaded${drive}`
else
ld=0
fi
if [ $ld -ne 0 ]; then
echo "Drive ${drive} Full (Storage element ${ld} loaded)"
echo "Load error: Drive ${drive} Full (Storage element ${ld} loaded)"
exit 1
fi
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
unlink ${device}.add 2>/dev/null >/dev/null
rm -f ${device} ${device}.add
if [ $havevol -ne 0 ]; then
ln -s $dir/$volume $device
ln -s $dir/${volume}.add ${device}.add
rtn=$?
else
ln -s $dir/slot${slot} $device
ln -s $dir/slot${slot}.add ${device}.add
rtn=$?
fi
if [ $rtn -eq 0 ]; then
echo $slot >$dir/loaded${drive}
fi
exit $rtn
;;
list)
debug "Doing disk -f $ctl -- to list volumes"
get_dir
if [ -f $dir/barcodes ]; then
cat $dir/barcodes
else
i=1
while [ $i -le $maxslot ]; do
slot=$i
volume=
get_vol
if [ $havevol -eq 0 ]; then
echo "$i:"
else
echo "$i:$volume"
fi
i=`expr $i + 1`
done
fi
exit 0
;;
listall)
# ***FIXME*** must add new Volume stuff
make_temp_file
debug "Doing disk -f $ctl -- to list volumes"
get_dir
if [ ! -f $dir/barcodes ]; then
exit 0
fi
# we print drive content seen by autochanger
# and we also remove loaded media from the barcode list
i=0
while [ $i -le $maxdrive ]; do
if [ -f $dir/loaded${i} ]; then
ld=`cat $dir/loaded${i}`
v=`awk -F: "/^$ld:/"' { print $2 }' $dir/barcodes`
echo "D:$i:F:$ld:$v"
echo "^$ld:" >> $TMPFILE
fi
i=`expr $i + 1`
done
# Empty slots are not in barcodes file
# When we detect a gap, we print missing rows as empty
# At the end, we fill the gap between the last entry and maxslot
grep -v -f $TMPFILE $dir/barcodes | sort -n | \
perl -ne 'BEGIN { $cur=1 }
if (/(\d+):(.+)?/) {
if ($cur == $1) {
print "S:$1:F:$2\n"
} else {
while ($cur < $1) {
print "S:$cur:E\n";
$cur++;
}
}
$cur++;
}
END { while ($cur < '"$maxslot"') { print "S:$cur:E\n"; $cur++; } } '
rm -f $TMPFILE
exit 0
;;
transfer)
# ***FIXME*** must add new Volume stuff
get_dir
make_temp_file
slotdest=$device
if [ -f $dir/slot{$slotdest} ]; then
echo "destination Element Address $slot is Full"
exit 1
fi
if [ ! -f $dir/slot${slot} ] ; then
echo "source Element Address $slot is Empty"
exit 1
fi
echo "Transfering $slot to $slotdest"
mv $dir/slot${slot} $dir/slot{$slotdest}
mv $dir/slot${slot}.add $dir/slot{$slotdest}.add
if [ -f $dir/barcodes ]; then
sed "s/^$slot:/$slotdest:/" > $TMPFILE
sort -n $TMPFILE > $dir/barcodes
fi
exit 0
;;
loaded)
debug "Doing disk -f $ctl $drive -- to find what is loaded"
get_dir
if [ -f $dir/loaded${drive} ]; then
a=`cat $dir/loaded${drive}`
else
a="0"
fi
debug "Loaded: drive=$drive is $a"
echo $a
exit
;;
slots)
debug "Doing disk -f $ctl -- to get count of slots"
echo $maxslot
;;
esac

View File

@ -0,0 +1,84 @@
#!/bin/sh
#
# Copyright (C) 2000-2018 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Bacula interface to get worm status of tape
#
# isworm %l (control device name)
#
# Typical output:
# sdparm --page=0x1D -f /dev/sg0
# /dev/st0: HP Ultrium 5-SCSI I5AW [tape]
# Medium configuration (SSC) mode page:
# WORMM 1 [cha: n, def: 1, sav: 1]
# WMLR 1 [cha: n, def: 1, sav: 1]
# WMFR 2 [cha: n, def: 2, sav: 2]
#
# Where WORMM is worm mode
# WMLR is worm mode label restrictions
# 0 - No blocks can be overwritten
# 1 - Some types of format labels may not be overwritten
# 2 - All format labels can be overwritten
# WMFR is worm mode filemark restrictions
# 0-1 - Reserved
# 2 - Any number of filemarks immediately preceding EOD can be
# overwritten except file mark closest to BOP (beginning of
# partition).
# 3 - Any number of filemarks immediately preceding the EOD
# can be overwritten
# 4-FF - Reserved
#
if [ x$1 = x ] ; then
echo "First argument missing. Must be device control name."
exit 1
fi
sdparm=`which sdparm`
if [ x${sdparm} = x ] ; then
echo "sdparm program not found, but is required."
exit 0
fi
#
# This should be the correct way to determine if the tape is WORM
# but it does not work for mhvtl. Comment out the next 5 lines
# and the code that follows will detect correctly on mhtvl.
#
worm=`$sdparm --page=0x1D -f $1 |grep " *WORMM"|cut -b12-16|sed "s:^ *::"`
if [ $? = 0 ] ; then
echo $worm
exit 0
fi
tapeinfo=`which tapeinfo`
if [ x${tapeinfo} = x ] ; then
echo "tapeinfo program not found, but is required."
exit 1
fi
#
# Unfortunately IBM and HP handle the Medium Type differently,
# so we detect the vendor and get the appropriate Worm flag.
#
vendor=`$tapeinfo -f $1|grep "^Vendor ID:"|cut -b13-15`
if [ x$vendor = xHP ] ; then
worm=`$tapeinfo -f $1|grep "^Medium Type: 0x"|cut -b16-16`
echo $worm
exit 0
fi
if [ x$vendor = xIBM ] ; then
worm=`$tapeinfo -f $1|grep "^Medium Type: 0x"|cut -b17-17`
if [ x$worm = xc ]; then
echo "1"
exit 0
fi
if [ x$worm = xC ]; then
echo "1"
exit 0
fi
fi
echo "0"
exit 0

View File

@ -0,0 +1,353 @@
#!/bin/sh
#
# 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.
#
# If you set in your Device resource
#
# Changer Command = "path-to-this-script/mtx-changer %c %o %S %a %d"
# you will have the following input to this script:
#
# So Bacula will always call with all the following arguments, even though
# in come cases, not all are used.
#
# mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index"
# $1 $2 $3 $4 $5
#
# for example:
#
# mtx-changer /dev/sg0 load 1 /dev/nst0 0 (on a Linux system)
#
# will request to load the first cartidge into drive 0, where
# the SCSI control channel is /dev/sg0, and the read/write device
# is /dev/nst0.
#
# The commands are:
# Command Function
# unload unload a given slot
# load load a given slot
# loaded which slot is loaded?
# list list Volume names (requires barcode reader)
# slots how many slots total?
# listall list all info
# transfer
#
# Slots are numbered from 1 ...
# Drives are numbered from 0 ...
#
#
# If you need to an offline, refer to the drive as $4
# e.g. mt -f $4 offline
#
# Many changers need an offline after the unload. Also many
# changers need a sleep 60 after the mtx load.
#
# N.B. If you change the script, take care to return either
# the mtx exit code or a 0. If the script exits with a non-zero
# exit code, Bacula will assume the request failed.
#
# myversion must be the same as version in mtx-changer.conf
myversion=2
# source our conf file
if test ! -f /etc/bacula/scripts/mtx-changer.conf ; then
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "ERROR: /etc/bacula/scripts/mtx-changer.conf file not found!!!!"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
exit 1
fi
. /etc/bacula/scripts/mtx-changer.conf
if test "${version}" != "${myversion}" ; then
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "ERROR: /etc/bacula/scripts/mtx-changer.conf has wrong version. Wanted ${myversion}, got ${version} !!!"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
exit 1
fi
MTX=/usr/sbin/mtx
if test ${debug_log} -ne 0 ; then
touch /var/lib/bacula/mtx.log
fi
dbgfile="/var/lib/bacula/mtx.log"
debug() {
if test -f $dbgfile -a ${debug_level} -ge $1; then
echo "`date +%m%d-%H:%M:%S.%N|cut -c1-16` ${chgr_id} $2" >> $dbgfile
fi
}
#
# Create a temporary file
#
make_temp_file() {
TMPFILE=`mktemp /var/lib/bacula/mtx.XXXXXXXXXX`
if test x${TMPFILE} = x; then
TMPFILE="/var/lib/bacula/mtx.$$"
if test -f ${TMPFILE}; then
echo "ERROR: Temp file security problem on: ${TMPFILE}"
exit 1
fi
fi
}
#
# Create a temporary file for stderr
#
# Note, this file is used because sometime mtx emits
# unexpected error messages followed by the output
# expected during success.
# So we separate STDOUT and STDERR in
# certain of the mtx commands. The contents of STDERR
# is then printed after the STDOUT produced by mtx
# thus we sometimes get better changer results.
#
make_err_file() {
ERRFILE=`mktemp /var/lib/bacula/mtx.err.XXXXXXXXXX`
if test x${ERRFILE} = x; then
ERRFILE="/var/lib/bacula/mtx.err.$$"
if test -f ${ERRFILE}; then
echo "ERROR: Temp file security problem on: ${ERRFILE}"
exit 1
fi
fi
}
#
# The purpose of this function to wait a maximum
# time for the drive. It will
# return as soon as the drive is ready, or after
# waiting a maximum of 300 seconds.
# Note, this is very system dependent, so if you are
# not running on Linux, you will probably need to
# re-write it, or at least change the grep target.
# We've attempted to get the appropriate OS grep targets
# in the code at the top of this script.
#
wait_for_drive() {
i=0
while [ $i -le 300 ]; do # Wait max 300 seconds
if mt -f $1 status 2>&1 | grep "${ready}" >/dev/null 2>&1; then
break
fi
debug $dbglvl "Device $1 - not ready, retrying..."
sleep 1
i=`expr $i + 1`
done
}
# check parameter count on commandline
#
check_parm_count() {
pCount=$1
pCountNeed=$2
if test $pCount -lt $pCountNeed; then
echo "ERROR: usage: mtx-changer ctl-device command [slot archive-device drive-index]"
echo " Insufficient number of arguments given."
if test $pCount -lt 2; then
echo " Mimimum usage is first two arguments ..."
else
echo " Command expected $pCountNeed arguments"
fi
exit 1
fi
}
# Check for special cases where only 2 arguments are needed,
# all others are a minimum of 5
#
case $2 in
list|listall)
check_parm_count $# 2
;;
slots)
check_parm_count $# 2
;;
transfer)
check_parm_count $# 4
;;
*)
check_parm_count $# 5
;;
esac
# Setup arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
drive=$5
debug $dbglvl "Parms: $ctl $cmd $slot $device $drive"
case $cmd in
unload)
if test ${offline} -eq 1 ; then
mt -f $device offline
fi
if test ${offline_sleep} -ne 0 ; then
sleep ${offline_sleep}
fi
make_err_file
for i in 1 2 3 4 5 ; do
debug $idbglvl "Doing mtx -f $ctl unload slot=$slot drv=$drive"
${MTX} -f $ctl unload $slot $drive 2>${ERRFILE}
rtn=$?
if test $rtn -eq 0 ; then
break
fi
grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null
if test $? -ne 0 ; then
break
fi
sleep $i
done
cat ${ERRFILE}
rm -f ${ERRFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl unload slot=$slot drv=$drive"
fi
exit $rtn
;;
load)
make_err_file
for i in 1 2 3 4 5 ; do
debug $idbglvl "Doing mtx -f $ctl load slot=$slot drv=$drive"
${MTX} -f $ctl load $slot $drive 2>${ERRFILE}
rtn=$?
if test $rtn -eq 0 ; then
break
fi
grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null
if test $? -ne 0 ; then
break
fi
sleep $i
done
if test ${load_sleep} -ne 0 ; then
sleep ${load_sleep}
fi
wait_for_drive $device
cat ${ERRFILE}
rm -f ${ERRFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl load slot=$slot drv=$drive"
fi
exit $rtn
;;
list)
make_temp_file
if test ${inventory} -ne 0 ; then
${MTX} -f $ctl inventory
fi
debug $dbglvl "Doing mtx -f $ctl list"
${MTX} -f $ctl status >${TMPFILE}
rtn=$?
if test ${vxa_packetloader} -ne 0 ; then
cat ${TMPFILE} | grep " *Storage Element [0-9]*:.*Full" | sed "s/ Storage Element //" | sed "s/Full :VolumeTag=//"
else
cat ${TMPFILE} | grep " Storage Element [0-9]*:.*Full" | awk "{print \$3 \$4}" | sed "s/Full *\(:VolumeTag=\)*//"
fi
cat ${TMPFILE} | grep "^Data Transfer Element [0-9]*:Full (Storage Element [0-9]" | awk '{printf "%s:%s\n",$7,$10}'
rm -f ${TMPFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl list"
fi
exit $rtn
;;
listall)
# Drive content: D:Drive num:F:Slot loaded:Volume Name
# D:0:F:2:vol2 or D:Drive num:E
# D:1:F:42:vol42
# D:3:E
#
# Slot content:
# S:1:F:vol1 S:Slot num:F:Volume Name
# S:2:E or S:Slot num:E
# S:3:F:vol4
#
# Import/Export tray slots:
# I:10:F:vol10 I:Slot num:F:Volume Name
# I:11:E or I:Slot num:E
# I:12:F:vol40
make_temp_file
if test ${inventory} -ne 0 ; then
${MTX} -f $ctl inventory
fi
debug $dbglvl "Doing mtx -f $ctl -- to list all"
${MTX} -f $ctl status >${TMPFILE}
rtn=$?
# can be converted to awk+sed+cut, see below
perl -ne '
/Data Transfer Element (\d+):Empty/ && print "D:$1:E\n";
/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "D:$1:F:$2:$4\n";
/Storage Element (\d+):Empty/ && print "S:$1:E\n";
/Storage Element (\d+):Full( :VolumeTag=(.+))?/ && print "S:$1:F:$3\n";
/Storage Element (\d+) IMPORT.EXPORT:Empty/ && print "I:$1:E\n";
/Storage Element (\d+) IMPORT.EXPORT:Full( :VolumeTag=(.+))?/ && print "I:$1:F:$3\n";' ${TMPFILE}
# If perl isn't installed, you can use by those commands
#cat ${TMPFILE} | grep "Data Transfer Element" | awk "{print \"D:\"\$4 \$7 \$9 \$10}" | sed "s/=/:/" | sed "s/Full/F:/" | sed "s/Empty/E/"
#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep -v "IMPORT/EXPORT" | awk "{print \"S:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep "IMPORT/EXPORT" | awk "{print \"I:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
rm -f ${TMPFILE} >/dev/null 2>&1
exit $rtn
;;
transfer)
slotdest=$device
debug $dbglvl "Doing transfer from $slot to $slotdest"
${MTX} -f $ctl transfer $slot $slotdest
rtn=$?
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl transfer from=$slot to=$slotdest"
fi
exit $rtn
;;
loaded)
make_temp_file
debug $idbglvl "Doing mtx -f $ctl $drive -- to find what is loaded"
${MTX} -f $ctl status >${TMPFILE}
rtn=$?
cat ${TMPFILE} | grep "^Data Transfer Element $drive:Full" | awk "{print \$7}"
cat ${TMPFILE} | grep "^Data Transfer Element $drive:Empty" | awk "{print 0}"
rm -f ${TMPFILE} >/dev/null 2>&1
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl loaded drv=$drive"
fi
exit $rtn
;;
slots)
debug $dbglvl "Doing mtx -f $ctl -- to get count of slots"
${MTX} -f $ctl status | grep " *Storage Changer" | awk "{print \$5}"
rtn=$?
if test $rtn -ne 0 ; then
debug $idbglvl "FAIL: mtx -f $ctl slots"
fi
;;
esac

View File

@ -0,0 +1,89 @@
#
# Copyright (C) 2000-2015 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
#
# This file is sourced by the mtx-changer script every time it runs.
# You can put your site customization here, and when you do an
# upgrade, the process should not modify this file. Thus you
# preserve your mtx-changer configuration.
#
# We update the version when an incompatible change
# to mtx-changer or this conf file is made, such as
# adding a new required variable.
version=2
# Set to 1 if you want to do offline before unload
offline=0
# Set to amount of time in seconds to wait after an offline
offline_sleep=0
# Set to amount of time in seconds to wait after a load
load_sleep=0
# Set to 1 to do an inventory before a status. Not normally needed.
inventory=0
# If you have a VXA PacketLoader, it might display a different
# Storage Element line, so try setting the following to 1
vxa_packetloader=0
#
# Debug logging
#
# If you have multiple SD's, set this differently for each one
# so you know which message comes from which one. This can
# be any string, and will appear in each debug message just
# after the time stamp.
chgr_id=0
# Set to 1 if you want debug info written to a log
debug_log=0
# Set to debug level you want to see
# 0 is off
# 10 is important events (load, unload, loaded)
# 100 is everything
# Note debug_log must be set to 1 for anything to be generated
#
debug_level=10
# Debug levels by importance
# Normally you do not need to change this
dbglvl=100
# More important messages
idbglvl=10
#
# mt status output
# SunOS No Additional Sense
# FreeBSD Current Driver State: at rest.
# Linux ONLINE
# Note Debian has a different mt than the standard Linux version.
# When no tape is in the drive it waits 2 minutes.
# When a tape is in the drive, it prints user unfriendly output.
# Note, with Ubuntu Gusty (8.04), there are two versions of mt,
# so we attempt to figure out which one.
#
OS=`uname`
case ${OS} in
SunOS)
ready="No Additional Sense"
;;
FreeBSD)
ready="Current Driver State: at rest."
;;
Linux)
ready="ONLINE"
if test -f /etc/debian_version ; then
mt --version|grep "mt-st" >/dev/null 2>&1
if test $? -eq 1 ; then
ready="drive status"
fi
fi
;;
esac

View File

@ -0,0 +1,68 @@
#!/bin/sh
#
# Copyright (C) 2000-2016 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Bacula interface to tapeinfo to get tape alerts
#
# tapealert %l (control device name)
#
# Note: you must have in your SD Device resource:
# Alert Command = /full-path/tapealert %l
# Control Device = /dev/sg0n (where this is the scsi control
# device for the device you are using).
#
# Note: to test
# 1. uncomment out the DEBUG=1 line below
# 2. Possibly remove or add TapeAlert[nn]: that you want to test.
# Note, the message following the : is not used.
# 3. Run Bacula
#
#DEBUG=1
tapeinfo=`which tapeinfo`
if [ x${tapeinfo} = x ] ; then
echo "tapeinfo program not found, but is required."
exit 1
fi
if [ x$1 = x ] ; then
echo "First argument missing. Must be device control name."
exit 1
fi
if [ x$DEBUG = x ] ; then
$tapeinfo -f $1 |grep "^TapeAlert" - |cut -b1-13
exit $?
else
# For testing only
cat <<EOF |grep "^TapeAlert" - |cut -b1-13
Product Type: Tape Drive
Vendor ID: 'IBM '
Product ID: 'ULTRIUM-TD6 '
Revision: 'G350'
Attached Changer API: No
SerialNumber: 'F3A2930090'
TapeAlert[3]: Hard Error: Uncorrectable read/write error.
TapeAlert[5]: Read Failure: Tape faulty or tape drive broken.
TapeAlert[39]: Undefined.
MinBlock: 1
MaxBlock: 8388608
SCSI ID: 9
SCSI LUN: 0
Ready: yes
BufferedMode: yes
Medium Type: 0x58
Density Code: 0x58
BlockSize: 0
DataCompEnabled: yes
DataCompCapable: yes
DataDeCompEnabled: yes
CompType: 0xff
DeCompType: 0xff
EOF
fi