Bacula and Bareos
CentOS 6.5 Install
yum install mysql-server mysql-devel
service mysqld start chkconfig mysqld on mysqladmin -u root password Y0uR3l173P455w0rd
yum install bareos-database-mysql yum install bareos
/usr/lib/bareos/scripts/create_bareos_database -u root -p /usr/lib/bareos/scripts/make_bareos_tables -u root -p /usr/lib/bareos/scripts/grant_bareos_privileges -u root -p
service bareos-dir start service bareos-sd start service bareos-fd start
Links
- http://www.unixmen.com/install-and-configure-bacula-server-in-centos-6-4-rhel-6-4/
- http://www.bareos.org/en/documentation.html
- http://doc.bareos.org/master/html/bareos-manual-main-reference.html
Archlinux GUI Admin
yaourt bareos-bat
Configure On CentOS 6.5
nano /etc/bareos/vchanger
</pre>
- !/bin/sh
- Bacula interface to virtual autochanger using removable disk drives
- Based (somewhat) on the "disk-changer" script from bacula 1.39.26
- Vchanger is a Bacula autochanger script that emulates a conventional
- magazine-based tape library device using removable disk drives.
- Partitions on the removable drives are used as virtual magazines,
- where each "magazine" contains the same number of virtual slots. Each
- "slot" holds one virtual tape, where a "tape" is a regular file that
- Bacula treats as a "Device Type = File" volume.
- This script will be invoked by Bacula using the Bacula Autochanger
- Interface and will be passed the following arguments:
- vchanger "changer-device" "command" "slot" "archive-device" "drive-index"
- $1 $2 $3 #4 #5
- See the Bacula documentation and the Bacula Removable Disk Howto for
- further details.
- Copyright (C) 2006 Josh Fisher
- Permission to use, copy, modify, distribute, and sell this software
- and its documentation for any purpose is hereby granted without fee,
- provided that the above copyright notice appear in all copies. This
- software is provided "as is" without express or implied warranty.
- This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- $Id: vchanger,v 0.7.4 2006/12/01 09:29:04 jfisher Exp $
- log whats done
- to turn on logging, uncomment the following line
- touch $wd/vchanger.log
- Write to a log file
- To log debugging info, create file /var/bacula/vchanger.log
- with write permission for bacula-sd user. To stop logging,
- delete file /var/bacula/vchanger.log
dbgfile="/var/bacula/vchanger.log" function debug() {
if test -e $dbgfile; then
echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
fi
}
- Return length of string $1
if [ `uname` = "FreeBSD" ] then
function strlen () { expr -- "$1" : ".*" }
else
function strlen () { expr length $1 }
fi
- Prepend zeros to $1 and return a string that is $2 characters long
function mklen () {
o1=$1 while [ `eval strlen ${o1}` -lt ${2} ]; do o1="0${o1}" done echo $o1
}
- Get uid of $1 (or current user if $1 empty)
function get_uid() {
id $1 2>/dev/null | cut -d ' ' -f 1 | sed "s/uid=//" | cut -d '(' -f 1
}
- Initialize autochanger's state directory if not already initialized
function init_statedir() {
debug "Initializing $statedir" # Create state directory if needed if [ ! -d "${statedir}" ]; then if [ "$su_uid" != "" ]; then su -c "mkdir ${statedir} &>/dev/null" $su_uid else mkdir ${statedir} &>/dev/null fi if [ $? -ne 0 ]; then echo "Could not create ${statedir}" exit 1 fi chmod 770 ${statedir} &>/dev/null if [ $? -ne 0 ]; then echo "Could not chmod ${statedir}" exit 1 fi fi # Create nextmag file to hold max magazine index used if [ ! -f "${statedir}/nextmag" ]; then if [ "$su_uid" != "" ]; then su -c "echo 0 >${statedir}/nextmag" $su_uid else
echo 0 >${statedir}/nextmag
fi if [ $? -ne 0 ]; then echo "Could not create ${statedir}/nextmag" exit 1 fi chmod 660 ${statedir}/nextmag if [ $? -ne 0 ]; then echo "Could not chmod ${statedir}/nextmag" exit 1 fi fi # Check nextmag value nextmag=`cat "${statedir}/nextmag"` if [ $? -ne 0 -o "${nextmag}" == "" -o $nextmag -lt 0 -o $nextmag -gt 99 ]; then echo "${statedir}/nextmag has invalid value" return 1 fi # Create 'loaded' files for each virtual drive that hold the slot # number currently loaded in that 'drive' i=0 while [ $i -le $maxdrive ]; do if [ ! -f "${statedir}/loaded${i}" ]; then if [ "$su_uid" != "" ]; then su -c "echo 0 >${statedir}/loaded${i}" $su_uid else echo 0 >${statedir}/loaded${i} fi if [ $? -ne 0 ]; then echo "Could not create ${statedir}/loaded${i}" exit 1 fi if [ "$su_uid" != "" ]; then su -c "chmod 660 ${statedir}/loaded${i}" $su_uid else chmod 660 ${statedir}/loaded${i} fi if [ $? -ne 0 ]; then echo "Could not chmod ${statedir}/loaded${i}" exit 1 fi fi i=`expr ${i} + 1` done
}
- Get magazine index of currently loaded magazine
function get_magazine() {
debug "Get magazine index" # Check for mountpoint dir if [ ! -d ${mountpoint} ]; then echo "No magazine loaded at ${mountpoint}" exit 1 fi # Check magazine for existing index if [ ! -f "${mountpoint}/index" ]; then echo "00" return 1 fi mi=`cat "${mountpoint}/index"` if [ $? -ne 0 ]; then echo "Failed to read ${mountpoint}/index" exit 1 fi # must be 1-99 if [ $mi -lt 1 -o $mi -gt 99 ]; then echo "Magazine has invalid index ${mi}" exit 1 fi # make magazine index 2 digits eval mklen ${mi} 2 return 0
}
- Initialize magazine if not already initialized
function init_magazine() {
debug "Initializing magazine" # Get max magazine index that has been used nextmag=`cat "${statedir}/nextmag"` if [ $? -ne 0 -o "${nextmag}" == "" ]; then echo "Failed to read ${statedir}/nextmag" exit 1 fi # Check magazine for existing index if [ -f "${mountpoint}/index" ]; then # retrieve existing magazine index mi=`cat "${mountpoint}/index"` if [ $? -ne 0 ]; then echo "Failed to read ${mountpoint}/index" exit 1 fi # must be 1-99 if [ $mi -lt 1 -o $mi -gt 99 ]; then echo "Magazine has invalid index ${mi}" exit 1 fi else # new magazine, so assign it the next avail index mi=`expr ${nextmag} + 1` if [ $mi -lt 0 -o $mi -gt 99 ]; then echo "Max magazines exceeded" exit 1 fi if [ "$su_uid" != "" ]; then su -c "echo ${mi} >${mountpoint}/index" $su_uid else echo ${mi} >${mountpoint}/index fi if [ $? -ne 0 ]; then echo "Failed to write ${mountpoint}/index" exit 1 fi chmod 640 ${mountpoint}/index 2>/dev/null fi # make sure max index used is up to date if [ $mi -gt $nextmag ]; then echo $mi 2>/dev/null >"${statedir}/nextmag" if [ $? -ne 0 ]; then echo "Failed to update ${statedir}/nextmag" exit 1 fi fi # make magazine index 2 digits magindex=`eval mklen ${mi} 2` # setup slot files (ie. virtual tapes) i=1 while [ $i -le $magslots ]; do s=`eval mklen ${i} 3` f="${mountpoint}/m${magindex}s${s}" if [ ! -f "${f}" ]; then if [ "$su_uid" != "" ]; then su -c "touch ${f} &>/dev/null" $su_uid else touch ${f} &>/dev/null fi if [ $? -ne 0 ]; then echo "Failed to create ${f}" exit 1 fi fi i=`expr ${i} + 1` done return 0
}
- Get sd status with bconsole
function bconsole_sd_status() {
debug "Doing 'status storage' with bconsole" $bconsole <<EOD_SDSTAT
status storage=$baculasd quit EOD_SDSTAT }
- Delete volume with bconsole param1 = slot
function bconsole_delete_volume() {
debug "Doing 'delete volume' with bconsole" s=`eval mklen $1 3` $bconsole <<EOD_DELVOL
delete volume=m${magindex}s${s} yes quit EOD_DELVOL }
- Label volumes from barcodes with bconsole
function bconsole_label_barcodes() {
debug "Doing 'label barcodes' with bconsole" $bconsole <<EOD_SDSTAT
label storage=$baculasd pool=$purgepool drive=0 barcodes yes quit EOD_SDSTAT }
- Checks if any of magazine's volumes are in use
function volumes_in_use() {
debug "Checking for in use volumes" inuse="" bconsole_sd_status | while read f; do #echo $f a=`echo ${f} | grep ^${magindex}` if [ "$a" != "" -a "$inuse" == "" ]; then inuse=`echo $f | cut -d ' ' -f 1` fi done if [ "$inuse" != "" ]; then echo $inuse fi
}
- Unload all drives
function unload_drives() {
debug "Unloading all drives" vuse=`eval volumes_in_use` if [ "${vuse}" != "" ]; then return 1 fi i=0 while [ $i -le $maxdrive ]; do unlink "${statedir}/drive${i}" 2>/dev/null >/dev/null echo "0" >"${statedir}/loaded${i}" i=`expr ${i} + 1` done return 0
}
- check parameter count on commandline
function check_parm_count() {
pCount=$1 pCountNeed=$2 if test $pCount -lt $pCountNeed; then
echo "usage: vchanger 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
}
- Setup arguments
check_parm_count $# 2 ctl=$1 cmd=$2 slot=$3 device=$4 drive=$5
- Setup default config values
baculasd= baculasd_user=bacula bconsole="/etc/bacula/bconsole" magslots=10 maxdrive=0 mountpoint= purgepool="Scratch" statedir=
- Pull in conf file
if [ -f $ctl ]; then
. $ctl
else
echo "Config file ${ctl} not found" exit 1
fi
- When invoked by root, create files/dirs as bacula-sd user
su_uid= myuid=`eval get_uid` if [ "$myuid" == "0" -a "$baculasd_user" != "" ]; then
buid=`eval get_uid $baculasd_user` if [ "$buid" == "" ]; then echo "bacula-sd user $baculasd_user not found" exit 1 fi if [ "$buid" != "0" ]; then su_uid=baculasd_user fi
fi
- check for required config values
if [ "${mountpoint}" == "" ]; then
echo "Required variable 'mountpoint' not defined in ${ctl}" exit 1
fi if [ "${baculasd}" == "" ]; then
echo "Required variable 'baculasd' not defined in ${ctl}" exit 1
fi if [ "${statedir}" == "" ]; then
echo "Required variable 'statedir' not defined in ${ctl}" exit 1
fi if [ "${magslots}" == "" -o $magslots -lt 1 -o $magslots -gt 999 ]; then
echo "Ivalid value for 'magslots' in ${ctl}" exit 1
fi if [ "${maxdrive}" == "" -o $maxdrive -lt 0 -o $maxdrive -ge $magslots ]; then
echo "Invalid value for 'maxdrive' in ${ctl}" exit 1
fi if [ "${bconsole}" == "" -o ! -f "${bconsole}" ]; then
echo "Ivalid value for 'bconsole' in ${ctl}" exit 1
fi if [ "${purgepool}" == "" ]; then
echo "Invalid value for 'purgepool' in ${ctl}" exit 1
fi
- attempt to set defaults for params not specified on command line
if [ "${drive}" == "" ]; then
drive=0
fi if [ "${device}" == "" ]; then
device="${statedir}/drive${drive}"
fi
- make sure archive device makes sense
if [ "${device}" != "${statedir}/drive${drive}" ]; then
echo "Param 4 (archive device) must be ${statedir}/driveN," echo " where N is the drive number passed as param 5" exit 1
fi
- Initialize state directory for this autochanger
init_statedir
debug "Parms: $ctl $cmd $slot $device $drive"
- Process command
case $cmd in
list) check_parm_count $# 2 debug "Doing list command" init_magazine if [ $? -ne 0 ]; then echo "Magazine Not Loaded" exit 1 fi i=1 while [ $i -le $magslots ]; do s=`eval mklen ${i} 3` echo "${i}:m${magindex}s${s}" i=`expr ${i} + 1` done ;; slots) check_parm_count $# 2 debug "Doing slots command" echo $magslots ;; load) check_parm_count $# 5 debug "Doing load slot $slot into drive $drive" if [ $drive -gt $maxdrive ]; then echo "Drive ($drive) out of range (0-${maxdrive})" exit 1 fi if [ $slot -gt $magslots ]; then echo "Slot ($slot) out of range (1-$magslots)" exit 1 fi ld=`cat "${statedir}/loaded${drive}"` if [ $? -ne 0 ]; then echo "Failed to read ${statedir}/loaded${drive}" exit 1 fi if [ $ld -eq 0 ]; then unlink "${device}" &>/dev/null # make sure slot is not loaded in another drive i=0 while [ $i -le $maxdrive ]; do if [ $i -ne $drive ]; then ldi=`cat "${statedir}/loaded${i}"` if [ $ldi -eq $slot ]; then echo "Storage Element ${slot} Empty (loaded in drive ${i})" exit 1 fi fi i=`expr ${i} + 1` done init_magazine if [ $? -ne 0 ]; then echo "Magazine Not Loaded" exit 1 fi s=`eval mklen ${slot} 3` if [ "$su_uid" != "" ]; then su -c "ln -s '${mountpoint}/m${magindex}s${s}' '${device}'" $su_uid else ln -s "${mountpoint}/m${magindex}s${s}" "${device}" fi echo $slot >"${statedir}/loaded${drive}" else echo "Drive ${drive} Full (Storage element ${ld} loaded)" exit 1 fi ;; unload) check_parm_count $# 5 debug "Doing unload drive $drive into slot $slot" if [ $drive -gt $maxdrive ]; then echo "Drive ($drive) out of range (0-${maxdrive})" exit 1 fi if [ $slot -gt $magslots ]; then echo "Slot ($slot) out of range (1-$magslots)" exit 1 fi ld=`cat "${statedir}/loaded${drive}"` if [ $? -ne 0 ]; then echo "Failed to read ${statedir}/loaded${drive}" exit 1 fi if [ $slot -eq $ld ]; then echo "0" >"${statedir}/loaded${drive}" if [ $? -ne 0 ]; then echo "Failed to write ${statedir}/loaded${drive}" exit 1 fi unlink "${device}" 2>/dev/null >/dev/null exit 0 fi if [ $ld -eq 0 ]; then echo "Drive ${drive} Is Empty" exit 1 else echo "Storage Element ${slot} is Already Full" exit 1 fi ;; loaded) check_parm_count $# 5 debug "Doing loaded command for drive $drive" if [ $drive -gt $maxdrive ]; then echo "Drive ($drive) out of range (0-${maxdrive})" exit 1 fi if [ $slot -gt $magslots ]; then echo "Slot ($slot) out of range (1-$magslots)" exit 1 fi cat "${statedir}/loaded${drive}" ;; purge) check_parm_count $# 2 debug "Doing purge command" magindex=`eval get_magazine` if [ "$magazine" == "00" ]; then echo No magazine loaded fi cm="" while [ "$cm" != "y" -a "$cm" != "n" ]; do echo -n "Purge all volumes on magazine $magindex (y/n)? " read cm if [ "$cm" == "Y" ]; then cm="y" fi if [ "$cm" == "N" ]; then cm="n" fi done if [ "$cm" == "n" ]; then exit 0 fi echo "Unloading $baculasd drives" unload_drives if [ $? -ne 0 ]; then echo Volume `eval volumes_in_use` in use...aborting exit 1 fi echo "Deleting magazine $magindex volumes" i=1 while [ $i -le $magslots ]; do bconsole_delete_volume $i &>/tmp/vclog rm -f "${mountpoint}/m${magindex}s${s}" echo "deleted volume m${magindex}s${s}" i=`expr ${i} + 1` done echo "Doing 'label barcodes' to re-create magazine's volumes" bconsole_label_barcodes | while read f; do echo $f done ;; *) echo "Command not recognized" exit 1 ;;
esac
exit 0
- eof
</pre>