Erik,
> I would appreciate receiving a copy of your script since I have the same
> problem and haven't done anything yet to solve it :-)
No problem.
bacula_next_volumes is the same as next_volumes.sh from my
previous mail.
prompt% bacula_next_volumes -h
Usage: bacula_next_volumes [options]
Outputs the volumes that are required for the next jobs.
Where the valid options are
-c, --client Bacula client, ie hostname.
-d, --debug Output debug information.
-h, --help Output this usage information.
-m, --mail Send email.
-n, --mount Mount all volumes.
-q, --quiet No output if no volumes required.
-r, --recipient Who gets mail (set to [EMAIL PROTECTED]).
-u, --unmount Unmount volumes that need changing.
Sorry about the state of the script, I got it working and lost
interest in optimising it. I'm sure the queries can be done
in SQL but I don't know how yet, maybe I'll do it on a quiet
day ;)
Do what you like with the script, but if you find something
better please let me know.
Cheers,
Bill
--
Bill Hill w: http://www.hgu.mrc.ac.uk/Users/Bill.Hill
MRC Human Genetics Unit e: [EMAIL PROTECTED]
Crewe Road t: +44-131-3322471x2130
Edinburgh EH4 2XU, UK. f: +44-131-4678456
#!/usr/bin/perl
# \file bacula_next_volumes
# \author Bill Hill
# \date January 2007
# \version $Id$
# \par
# Address:
# MRC Human Genetics Unit,
# Western General Hospital,
# Edinburgh, EH4 2XU, UK.
# \par
# Copyright (C) 2006 Medical research Council, UK.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program 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. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
# \brief Mails notice of the required volumes for the bacula dump.
# \todo Quite inefficient code, should cache status.
# \bug None known.
use strict;
use warnings;
use File::Spec::Unix;
use Getopt::Long;
my $debug = 0;
my $help = 0;
my $bcCmd = "/opt/bacula/sbin/bconsole";
my $bcOpts = "-c /opt/bacula/etc/bconsole.conf";
my $hostName = "server";
my $nJobVols = 0;
my $quiet = 0;
my @jobVols = ();
my @jobVolDevs = ();
my $nJobDevs = 0;
my @jobDevs = ();
my $nDevMounted = 0;
my @devMounted = ();
my $nDevToMount = 0;
my @devToMount = ();
my $outBuf = "";
my $nNewVol = 0;
my $progname = "bacula_next_volumes";
my $mailCmd = "/opt/bacula/sbin/bsmtp";
my $mailHost = 'smtp.some.where';
my $mailFrom = '[EMAIL PROTECTED]';
my $mailRecipient = '[EMAIL PROTECTED]';
my $sendMail = 0;
my $mount = 0;
my $unmount = 0;
my $state = 0;
sub showUsage
{
print STDERR "Usage: $progname [options]\n";
print STDERR "Outputs the volumes that are required for the next jobs.\n";
print STDERR "Where the valid options are\n";
print STDERR " -c, --client Bacula client, ie hostname.\n";
print STDERR " -d, --debug Output debug information.\n";
print STDERR " -h, --help Output this usage information.\n";
print STDERR " -m, --mail Send email.\n";
print STDERR " -n, --mount Mount all volumes.\n";
print STDERR " -q, --quiet No output if no volumes required.\n";
print STDERR " -r, --recipient Who gets mail (set to $mailRecipient).\n";
print STDERR " -u, --unmount Unmount volumes that need changing.\n";
}
sub showGlobals
{
print STDERR "bcCmd = $bcCmd\n";
print STDERR "bcOpts = $bcOpts\n";
print STDERR "hostName = $hostName\n";
print STDERR "debug = $debug\n";
print STDERR "help = $help\n";
print STDERR "progname = $progname\n";
print STDERR "quiet = $quiet\n";
print STDERR "state = $state\n";
print STDERR "nNewVol = $nNewVol\n";
print STDERR "outBuf = $outBuf\n";
print STDERR "mailCmd = $mailCmd\n";
print STDERR "mailHost = $mailHost\n";
print STDERR "mailFrom = $mailFrom\n";
print STDERR "mailRecipient = $mailRecipient\n";
print STDERR "sendMail = $sendMail\n";
print STDERR "mount = $mount\n";
print STDERR "unmount = $unmount\n";
print STDERR "nJobVols = $nJobVols\n";
for(my $jIdx = 0; $jIdx < $nJobVols; ++$jIdx)
{
print STDERR "$jobVols[$jIdx][0] " .
"$jobVols[$jIdx][1] " .
"$jobVols[$jIdx][2] " .
"$jobVols[$jIdx][3] " .
"$jobVols[$jIdx][4] " .
"$jobVols[$jIdx][5] " .
"$jobVols[$jIdx][6]\n";
}
print STDERR "nJobDevs = $nJobDevs\n";
for(my $jIdx = 0; $jIdx < $nJobDevs; ++$jIdx)
{
print STDERR "$jobDevs[$jIdx][0] " .
"$jobDevs[$jIdx][1]\n";
}
print STDERR "nDevMounted = $nDevMounted\n";
for(my $jIdx = 0; $jIdx < $nDevMounted; ++$jIdx)
{
print STDERR "$devMounted[$jIdx][0] " .
"$devMounted[$jIdx][1]\n";
}
print STDERR "nDevToMount = $nDevToMount\n";
for(my $jIdx = 0; $jIdx < $nDevToMount; ++$jIdx)
{
print STDERR "$devToMount[$jIdx][0] " .
"$devToMount[$jIdx][1]\n";
}
}
sub makeExit
{
my $code = $_[0];
my $mesg = $_[1];
if(length($mesg) > 0)
{
print STDERR "$progname: $mesg\n";
}
exit($code);
}
sub associateJobsVolumesDevices
{
for(my $jIdx = 0; $jIdx < $nJobVols; ++$jIdx)
{
$jobVolDevs[$jIdx][0] = $jobVols[$jIdx][5];
$jobVolDevs[$jIdx][1] = $jobVols[$jIdx][6];
$jobVolDevs[$jIdx][2] = "unknown";
for(my $dIdx = 0; $dIdx < $nJobDevs; ++$dIdx)
{
if($jobVols[$jIdx][5] eq $jobDevs[$dIdx][0])
{
$jobVolDevs[$jIdx][2] = $jobDevs[$dIdx][1];
last;
}
}
}
}
sub addVolumesForJobs
{
for(my $jIdx = 0; $jIdx < $nJobVols; ++$jIdx)
{
$outBuf = $outBuf .
" Job \"$jobVolDevs[$jIdx][0]\" " .
"will use \"$jobVolDevs[$jIdx][1]\" " .
"mounted in \"$jobVolDevs[$jIdx][2]\"\n";
}
}
sub calcVolumesToBeMounted
{
my $cnt = 0;
for(my $jIdx = 0; $jIdx < $nJobVols; ++$jIdx)
{
for(my $dIdx = 0; $dIdx < $nDevMounted; ++$dIdx)
{
if(($jobVolDevs[$jIdx][2] eq $devMounted[$dIdx][0]) &&
($jobVolDevs[$jIdx][1] eq $devMounted[$dIdx][1]))
{
++$cnt;
}
}
}
return $nJobVols - $cnt;
}
sub addVolumesToBeMounted
{
$nDevToMount = 0;
for(my $jIdx = 0; $jIdx < $nJobVols; ++$jIdx)
{
my $fnd = 0;
for(my $dIdx = 0; $dIdx < $nDevMounted; ++$dIdx)
{
if(($jobVolDevs[$jIdx][2] eq $devMounted[$dIdx][0]) &&
($jobVolDevs[$jIdx][1] eq $devMounted[$dIdx][1]))
{
$fnd = 1;
}
}
if($fnd == 0)
{
$devToMount[$nDevToMount++][0] = $jobVolDevs[$jIdx][2];
$outBuf = $outBuf .
" \"$jobVolDevs[$jIdx][1]\" in \"$jobVolDevs[$jIdx][2]\"\n";
}
}
}
sub mountVolumes
{
for(my $jIdx = 0; $jIdx < $nDevToMount; ++$jIdx)
{
system("echo \"mount storage=$devToMount[$jIdx][0]\" | $bcCmd $bcOpts");
}
}
sub unmountVolumes
{
for(my $jIdx = 0; $jIdx < $nDevToMount; ++$jIdx)
{
system("echo \"unmount storage=$devToMount[$jIdx][0]\" | $bcCmd $bcOpts");
}
}
## Main ##
# Parse command line options
Getopt::Long::config('no_ignore_case');
GetOptions (
"c|client=s" => \$hostName,
"d|debug" => \$debug,
"h|help" => \$help,
"m|mail" => \$sendMail,
"n|mount" => \$mount,
"q|quiet" => \$quiet,
"r|recipient=s" => \$mailRecipient,
"u|unmount" => \$unmount
);
if($debug != 0)
{
&showGlobals();
}
# Show usage and exit if appropriate
if($help)
{
&showUsage();
makeExit(0, "");
}
# Collect job - volume association data
if(!(-e $bcCmd))
{
makeExit(1, "$bcCmd not found.");
}
open(CMD, "echo \"status all\" | $bcCmd $bcOpts |") or
&makeExit("cant execute $bcCmd.");
$state = 0;
while (<CMD>)
{
if($state == 0)
{
if(/^Scheduled Jobs:/)
{
$state = 1;
}
}
elsif($state == 1)
{
if(/^==========*/)
{
$state = 2;
}
}
elsif($state == 2)
{
if(/^====[\t ]*$/)
{
$state = 4;
}
else
{
my $field;
my $fieldIdx = 0;
for $field ( split )
{
$jobVols[$nJobVols][$fieldIdx] = $field;
++$fieldIdx;
}
if($jobVols[$nJobVols][1] eq "Backup")
{
++$nJobVols;
}
}
}
}
close(CMD);
# Collect job - storage device association data
if(!(-e $bcCmd))
{
makeExit(1, "$bcCmd not found.");
}
open(CMD, "echo \"show jobs\" | $bcCmd $bcOpts |") or
&makeExit("cant execute $bcCmd.");
$state = 0;
while (<CMD>)
{
if($state == 0)
{
if(/^Job:\s+name=(\S+)\s+/)
{
$jobDevs[$nJobDevs][0] = $1;
$state = 1;
}
}
elsif($state == 1)
{
if(/^\s*DeviceName=(\S+)\s+/)
{
$jobDevs[$nJobDevs][1] = $1;
++$nJobDevs;
$state = 0;
}
}
}
close(CMD);
# Collect storage device mount status.
if(!(-e $bcCmd))
{
makeExit(1, "$bcCmd not found.");
}
open(CMD, "echo \"status all\" | $bcCmd $bcOpts |") or
&makeExit("cant execute $bcCmd.");
$state = 0;
while (<CMD>)
{
if($state == 0)
{
if(/^Device status:\s*$/)
{
$state = 1;
}
}
elsif($state == 1)
{
if(/^Device "(\S+)" \S+ is mounted with Volume="(\S+)" Pool="\S+"/)
{
$devMounted[$nDevMounted][0] = $1;
$devMounted[$nDevMounted][1] = $2;
++$nDevMounted;
}
elsif(/^====/)
{
$state = 0;
}
}
}
close(CMD);
# Form statements which associate jobs, volumes and devices
&associateJobsVolumesDevices();
$nNewVol = &calcVolumesToBeMounted();
if($nNewVol > 1)
{
$outBuf = $outBuf . "$nNewVol new volumes need to be mounted:\n";
&addVolumesToBeMounted();
}
elsif($nNewVol == 1)
{
$outBuf = $outBuf . "1 new volume needs to be mounted:\n";
&addVolumesToBeMounted();
}
else
{
$outBuf = $outBuf . "No new volumes need to be mounted.\n";
}
$outBuf = $outBuf . "\n";
$outBuf = $outBuf . "The following volumes will be used:\n";
&addVolumesForJobs();
# Send mail giving notice of the required volumes
if(($quiet == 0) || ($nNewVol > 0))
{
if($sendMail == 0)
{
print $outBuf;
}
else
{
open(CMD, "| $mailCmd " .
"-h $mailHost " .
"-f \"" . $mailFrom . "\" " .
"-s \"Bacula: Dump setup for $hostName\" " .
$mailRecipient) or
&makeExit("cant execute bsmtp.");
print CMD $outBuf;
close(CMD);
}
}
# Mount and unmount volumes as required
if($mount != 0)
{
&mountVolumes();
}
if($unmount != 0)
{
&unmountVolumes();
}
if($debug > 0)
{
&showGlobals();
}
&makeExit(0, "");
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bacula-users mailing list
Bacula-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-users