Hello,
I have written a couple of scripts around bacula.
The first is a tape cleaner of sorts.. This script has no error
checking whatsoever..
It grabs every tape library connected to a server and blanks all tapes
using all available drives. If you want to blank all libraries and all
tapes as quickly as possible, This script is for you,
its quick and dirty it threads off per library and per drive. You need
lsscsi installed before running this and mt-st and mtx.
I wrote it to blank all tapes after labelling them during test runs
dealing with 2 libraries with 40 tapes each it aint fun to try erasing
all of the labels before stopping test runs.
If I get the Time I will update this with some proper error checking
and will also update it to ask before erasing a library and probably
to be able to select a subset of the tapes rather than everything..
Should make it a pretty decent tool. (Its been tested on Qualstar
4440 series with odd number of tape drives 2 libraries connected to 1
sd total of 7 physical tape drives sleep may need to be slightly
changed depending on the speed of your drives )
The second two scripts allow every other day / weekofmonth /
weekofyear / month / year rotation.
Its set to allow even rotations to occur, it grabs localtime so doesnt
require any arguments to be passed to it.
Basically thats it, some one else might find these useful
Ive also written some automated rpm generators if anyone is
interested. downloads and patches and adds configs etc properly (
splits off into bacula-dir, bacula-sd, bacula-fd tested on centos 5 /
rhel 5)
Thanks,
Vamegh
#!/usr/bin/perl
#### Vamegh Special
### Unload all tapes from tape drive
### then rewind all tapes then write
### end of file on tape which should
### clean up all of the tapes.
## Gnu/Gpl v2
use POSIX ();
use threads;
use Thread::Semaphore;
use Thread::Queue;
use File::Path;
use File::Copy;
## Declaring what I need to get this working.
my %drv_libs ;
my @libraries ;
my @drive_names ;
my $proc_libraries ;
my @libdrives ;
my $tmp = "/tmp";
my $thread_safe;
@libdrives = `lsscsi -g|egrep "(medium)|(tape)"|tr -d ":[]-"|awk '{print \$6}'`;
$tapendrive = &TapeLibs_n_Drives;
foreach $proc_libraries (threads->list) {
# Don't join the main thread or ourselves
if ($proc_libraries->tid && !threads::equal($proc_libraries, threads->self)) {
$proc_libraries->join;
}
}
foreach $clean_tape (threads->list) {
#Don't join the main thread or ourselves
if ($clean_tape->tid && !threads::equal($clean_tape, threads->self)) {
$clean_tape->join;
}
}
sub TapeLibs_n_Drives {
foreach (@libdrives) {
chomp;
$check = $_;
next if $check =~ /\/dev\/st3/;
if ($check =~ /\/dev\/st[0-9]*/){ $drive = $check; }
if ($check =~ /\/dev\/sg[0-9]*/){ $libs = $check; }
if (!$drive) {
#print "No drives yet\n";
} else {
push( @{$drv_libs{$libs}}, $drive );
$drive='';
}
}
foreach $lib (sort keys %drv_libs) {
@drive_names = @{$drv_libs{$lib}};
$drive_total = @{$drv_libs{$lib}};
$proc_libraries = threads->new(\&proc_libs,$lib);
}
}
sub proc_libs {
$lib = $_[0];
@tapes = `mtx -f $lib status|grep "Storage Element [0-9]*[:]Full"|awk '{print \$3}'|awk -F: '{print \$1}'`;
foreach (@tapes) { chomp; }
print "in \$cleanlibrary async tapes available : @tapes\n";
&Check_Drives($lib, @drive_names);
&Clean_Drives($lib, @drive_names);
}
sub Check_Drives {
@drives = @_;
$check_lib=shift(@drives);
print "In Check_Drives library: \t$check_lib \n";
print "In Check_Drives available drives: [EMAIL PROTECTED] \n";
@drives_full = `mtx -f $check_lib status|grep "Data Transfer Element [0-9]*:Full"|awk '{print \$4}'|awk -F: '{print \$1}'`;
foreach (@drives_full) { chomp; }
print "Loaded Drives: [EMAIL PROTECTED] ";
@slots_empty = `mtx -f $check_lib status|grep "Data Transfer Element [0-9]*:Full"|awk '{print \$7}'`;
foreach (@slots_empty) { chomp; }
print "Empty Slots: [EMAIL PROTECTED]";
for ($x=0; $x<@drives_full; $x++) {
$d=$drives_full[$x];
$slot = $slots_empty[$x];
print "seems like $drives[$d] ($d) has a tape in it going to eject now \n" ;
print "ejecting tape in: $drives[$d] \n";
`mt -f $drives[$d] eject`;
print "unloading tape in: $drives[$d] ($d) into $slot \n";
`mtx -f $check_lib unload $slot $d`;
print "should be all done for $drives[$d] \n";
}
}
sub Clean_Drives {
@drives = @_;
$clean_lib=shift(@drives);
print "In Clean_Drives library = $clean_lib \n";
print "In Clean_Drives the drives are : @drives \n";
my $a = "0";
my $driveTot = @drives;
my $q = new Thread::Queue;
$thread_safe = Thread::Semaphore->new($driveTot);
#for (my $a=0;$a<@tapes;$a+$driveTot) {
while ($a<@tapes) {
my $countTapes = \$a;
for (my $i=0; $i<@drives; $i++) {
$tape = $tapes[$$countTapes];
$drive = $drives[$i];
#print "\n \$a now $a and \$countTapes = $$countTapes In for drive loop => \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape \n";
#print "tape == $tape\n";
my $clean_tape = threads->new(\&process_clean,$clean_lib,$tape,$drive,$i);
#&process_clean($clean_lib,$tape,$drive,$i);
$$countTapes++;
sleep 15;
}
print "\nWaiting for $$countTapese to be dealt with first before jumping through the whole list\n\n";
sleep 170;
}
}
sub process_clean {
@params = @_;
$clean_lib = shift(@params);
$tape = shift(@params);
$drive = shift(@params);
$i = shift(@params);
$thread_safe->down(1);
print "In process_clean => \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape \n";
### Lets start the actual processing
#print "\nPausing for 15 seconds to give time for arm in $clean_lib to unload tape into $drive\n";
#sleep 20;
print "\n loading tape: $tape into $i \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape\n";
`mtx -f $clean_lib load $tape $i`;
print "\nrewinding for tape: $tape \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape\n";
`mt -f $drive rewind`;
print "\nwriting weof for tape: $tape \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape \n";
`mt -f $drive weof`;
print "\nejecting tape: $tape \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape \n";
`mt -f $drive eject`;
#print "\nPausing for 15 seconds to give time for $drive to eject and get ready to be unloaded\n";
#sleep 15;
print "\nunloading $drive and putting $tape back into slot \tlibrary: $clean_lib \tdrive: $drive \ttape: $tape \n";
`mtx -f $clean_lib unload $tape $i`;
$thread_safe->up(1);
}
#!/usr/bin/perl -w
use strict;
##################################################################################
# #
# Even/odd calculator for bacula rotation #
# #
# A year is composed of 12 months or 52 weeks or 365/366 days #
# #
# Easiest way of doing per day/week/month or even yearly rotation #
# If the number divides by 2 with no remainder it should be even. #
# Otherwise its gotta be odd.. #
# #
# So with this logic in mind. Lets start working out what day we are in, #
# What week we are in and what month we are in.. #
# If it doesnt divide by 2 cleanly were in an odd hour/day/month week etc.. #
# #
# Only use this script on even jobs so if its an even period the job is not #
# cancelled !! #
# #
# Original idea from Robert L Mathews, Tiger Technologies #
# http://www.krugle.org/examples/p-uUnXDaHlgJF43EUq/backup-every-other-week.txt #
# Original script worked out via seconds. #
# This is a complete rewrite which should #
# be very flexible using a different technique but same idea #
# #
# Vamegh Hedayati #
##################################################################################
my $date;
my $year;
my $month;
my $weekofmonth;
my $weekofyear;
my $day;
my $divider=2;
my $mon;
sub make_date {
my ($sec,$min,$hour,$mday,$amon,$ayear,$wday,$yday,$isdst)=localtime(time);
#print "localtime(time) is %4d-%02d-%02d %02d:%02d:%02d", $year+1900,$amon+1,$mday,$yday,$hour,$min,$sec;
$year=$ayear+1900;
$month=$amon+1;
## To work out the week, the number of days should be divided by 7 we dont need the remainder.
## so get rid of that and we know what week we are in.. if that then divided by 2 gives us no
## remainder we know we are in an even week otherwise it should be odd right ?
## works out week number in month
my $mweek = $mday / 7;
($weekofmonth, undef) = split('\.', $mweek);
## Week of year rotation below
my $yweek = $yday / 7;
($weekofyear, undef) = split('\.', $yweek);
$weekofyear+=1; ## 0-51 weeks (+1 gives 1-52 weeks ) should be correct havent thoroughly tested
my $day = $mday;
$date="$year-$month-$mday -- $hour:$min:$sec";
}
&make_date;
## I only need this for monthly rotations.
## Change the variable for yearly / <monthly> / weekly / daily rotations..
if ($month%2==0) {
print "Date: $date --> running the job as it should be an even job\n" ;
} else {
print "Date: $date --> we are in an odd month Job Should get cancelled\n";
print "Date: $date --> JOB_CANCELLED_ON_PURPOSE\n";
exit 1;
}
##################EOF##################
#!/usr/bin/perl -w
use strict;
##################################################################################
# #
# Even/odd calculator for bacula rotation #
# #
# A year is composed of 12 months or 52 weeks or 365/366 days #
# #
# Easiest way of doing per day/week/month or even yearly rotation #
# If the number divides by 2 with no remainder it should be even. #
# Otherwise its gotta be odd.. #
# #
# So with this logic in mind. Lets start working out what day we are in, #
# What week we are in and what month we are in.. #
# If it doesnt divide by 2 cleanly were in an odd hour/day/month week etc.. #
# #
# Only use this script on odd jobs so if its an even period the job is not #
# cancelled !! #
# #
# Original idea from Robert L Mathews, Tiger Technologies #
# http://www.krugle.org/examples/p-uUnXDaHlgJF43EUq/backup-every-other-week.txt #
# Original script worked out via seconds. #
# This is a complete rewrite which should #
# be very flexible using a different technique but same idea #
# #
# Vamegh Hedayati #
##################################################################################
my $date;
my $year;
my $month;
my $weekofmonth;
my $weekofyear;
my $day;
my $divider=2;
sub make_date {
my ($sec,$min,$hour,$mday,$amon,$ayear,$wday,$yday,$isdst)=localtime(time);
#printf "%4d-%02d-%02d %02d:%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min,$sec;
$year=$ayear+1900;
$month=$amon+1;
## To work out the week, the number of days should be divided by 7 we dont need the remainder.
## so get rid of that and we know what week we are in.. if that then divided by 2 gives us no
## remainder we know we are in an even week otherwise it should be odd right ?
## works out week number in month
my $mweek = $mday / 7;
($weekofmonth, undef) = split('\.', $mweek);
## Week of year rotation below
my $yweek = $yday / 7;
($weekofyear, undef) = split('\.', $yweek);
$weekofyear+=1; ## 0-51 weeks (+1 gives 1-52 weeks ) should be correct havent thoroughly tested
my $day = $mday;
$date="$year-$month-$mday $hour:$min:$sec";
}
&make_date;
## I only need this for monthly rotations.
## Change the variable for yearly / <monthly> / weekly / daily rotations..
if ($month%2==0) {
print "Date: $date --> we are in an even month Job Should get cancelled\n";
print "Date: $date --> JOB_CANCELLED_ON_PURPOSE\n";
exit 1;
} else {
print "Date: $date --> running the job as it should be an odd job\n" ;
}
##################EOF##################
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bacula-users mailing list
Bacula-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-users