#!/usr/local/bin/perl -w # # This sample script, weekend.pl, was written to show how you can use # the NBU modules to find all the tapes used by all the FULL backups from # a specific weekend. # # The script takes 2 optional arguments: # -d turns on debugging in the NBU modules which basically allows you # to see which NetBackup commands are invoked during the data gathering # -a YYYYMMDD sets the effective date of the run, the default being today # # The script looks backwards in time for the preceding Friday and analyzes # the weekend from Friday at 6pm through Monday morning at 6am. use strict; use Getopt::Std; use Time::Local; my %opts; getopts('d?a:', \%opts); use NBU; NBU->debug($opts{'d'}); # # See if the user provided an effective date on the command line my ($mm, $dd, $yyyy); if (!$opts{'a'}) { my ($s, $m, $h, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(); $year += 1900; $mm = $mon + 1; $dd = $mday; $yyyy = $year; } else { $opts{'a'} =~ /^([\d]{4})([\d]{2})([\d]{2})$/; $mm = $2; $dd = $3; $yyyy = $1; } # # The effective date of this weekend analysis run is either the current # time, or the time specified with the -a option. # Here we run it back and forth through the timelocal and localtime functions # to learn what day of the week this is. The wday variable contains this # information with 0 being a Sunday my $effectiveDate = timelocal(0, 0, 0, $dd, $mm-1, $yyyy); my ($s, $m, $h, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($effectiveDate); print "Effective date for this run is ".localtime($effectiveDate)."\n"; # # Our analysis would like to start at 6pm local time of the Friday going into the weekend # First we locate midnight on Friday, i.e. the morning of the Friday we are interested in my $lastFriday = $effectiveDate - (24 * 60 * 60) * (($wday + 2) % 7); # # Now we add 18 hours to get to 6pm on Friday my $weekendStart = $lastFriday + (18 * 60 * 60); # # The weekend ends Monday morning at 6am local time: my $weekendEnd = $lastFriday + (78 * 60 * 60); print "Analyzing the weekend from ".localtime($weekendStart)." through ".localtime($weekendEnd)."\n"; # # Populate our knowledge of all images in the NetBackup environment # An image is no more than a completed backup job NBU::Media->populate(1); NBU::Image->populate; # # Create a local list of all these images my @l = NBU::Image->list; print "The full image database contains $#l images\n"; # # Initialize some local counters and an associative array to hold # all the volumes that were used by the images we are interested in my %inUse; my ($total, $totalSize) = (0, 0); # # Loop over all the images, picking and choosing only the ones we # care about for my $image (@l) { # Skip empty images next if (!defined($image->size)); # Images created over the weekend only, please next unless (($image->ctime >= $weekendStart) && ($image->ctime < $weekendEnd)); # Only interested in FULL backups next unless ($image->schedule->type eq "FULL"); # And we can skip disk based volumes as we can't eject those :-) next unless ($image->removable); # # If we get this far we have an image we are interested in # Increment the count of images $total += 1; # Keep track of the amount of data in all the images. Image sizes are # reported in Kilo Bytes, and here we convert to Mega Bytes to keep from # overflowing the counter my $size = $image->size / 1024; $totalSize += $size; # And tag the tape volumes that were used by all the fragments foreach my $fragment ($image->fragments) { my $volume = $fragment->volume; # # If a policy includes multiple copies, one if the copy's # fragments could still have been written to disk... Skip # those volumes here. next unless ($volume->removable); $inUse{$fragment->volume->id} = $fragment->volume; } } my $totalGBytes = sprintf("%.2f", $totalSize/1024); print "$total completed backup images wrote ${totalGBytes}GB of data\n"; # # Now gather the list of all the volumes we tagged along the way: my @volumesUsed = (values %inUse); print "These images used ".@volumesUsed." volumes\n"; print "As of ".localtime()." these volumes can be found at:\n"; foreach my $volume (@volumesUsed) { print " ".$volume->id; if (defined($volume->robot)) { print " located in robot ".$volume->robot->id; print ", slot ".$volume->slot; } else { print " offsite"; } print "\n"; }