Coincidentally, I wrote this just last week:
#!/usr/bin/perl
use Data::Dumper;
# Each line of bpdbjobs output has a fairly long, complicated format
# described in the PDF: NetBackup Commands for UNIX and Linux.
my $lineformat =
[
'jobid', 'jobtype', 'state', 'status', 'class',
'schedule', 'client', 'server', 'started', 'elapsed',
'ended', 'stunit', 'try', 'operation', 'kbytes',
'files', 'pathlastwritten', 'percent', 'jobpid', 'owner',
'subtype', 'classtype', 'schedule_type', 'priority', 'group',
'masterserver', 'retentionunits', 'retentionperiod', 'compression',
'kbyteslastwritten', 'fileslastwritten',
'filelistcount'
=> [
'files',
],
'trycount',
=> [
'trypid', 'trystunit', 'tryserver', 'trystarted',
'tryelapsed',
'tryended', 'trystatus', 'trystatusdescription',
'trystatuscount'
=> [
'trystatuslines',
],
'trybyteswritten', 'tryfileswritten',
],
# Fields below taken from DWR's python script on
# Curtis Preston's backupcentral.com wiki.
'parentjob', 'kbpersec', 'copy', 'robot', 'vault',
'profile', 'session', 'ejecttapes', 'srcstunit', 'srcserver',
'srcmedia', 'dstmedia', 'stream', 'suspendable', 'resumable',
'restartable', 'datamovement', 'frozenimage', 'backupid',
'killable',
'controllinghost',
# Plus one unaccounted for.
'unknown',
];
my %valuenames =
(
'jobtype'
=> [
'backup', 'archive', 'restore', 'verify',
'duplication',
'import', 'dbbackup', 'vault', 'label', 'erase',
'tpreq', 'tpclean', 'tpformat', 'vmphyinv', 'dqts',
'dbrecover', 'mcontents',
],
'schedule_type'
=> [
'FULL', 'INCR', 'UBAK', 'UARC', 'CINC',
],
'state'
=> [
'queued', 'active', 'waiting for retry', 'done',
],
'subtype'
=> [
'immediate', 'scheduled', 'user-initiated',
],
);
sub parse_bpdbjobs {
my ($fields, $format, $repeat) = @_;
unless (ref $fields) {
chomp $fields;
# split on unescaped commas; perl has variable-length
# lookahead but not lookbehind in regexps, so we work
# with reversed strings, then un-reverse each field *and*
# return the entire list of fields to normal order.
$fields = [ reverse map { scalar reverse }
# comma, NOT followed
by:
# a
backslash,
# followed
by any even number of backslashes,
# followed
by a non-backslash or end-of-string.
split(/,(?!\\(?:\\\\)*(?:[^\\]|$))/,
scalar reverse($fields)) ];
}
$format = $lineformat unless (defined $format);
$repeat = 1 unless (defined $repeat);
my @result;
for (my $i = 0; $i < $repeat; $i++) {
my %item = ();
my $prev_field;
foreach my $format_field (@$format) {
if (ref $format_field) {
# sublist; expect number of repetitions given by
the previous field
my $sublist = parse_bpdbjobs($fields,
$format_field, $prev_field);
# hack: name the sublist by the first field in
it
$item{$format_field->[0]} =
$sublist;
} else {
# scalar; convert to english if necessary and store
it.
my $field = shift @$fields;
if (exists $valuenames{$format_field}
&& $field =~ /\d+/) {
$field =
$valuenames{$format_field}->[$field] || $field;
}
$item{$format_field} = $field;
$prev_field = $field;
}
}
# Single field (as in list of files or list of try status
lines)
# should not bother with encapsulation in a hash.
if (@$format == 1) {
push @result, values %item;
} else {
push @result, \%item;
}
}
return \@result;
}
open JOBS, '-|', '/opt/openv/netbackup/bin/admincmd/bpdbjobs', '-all_columns'
or die "Couldn't run bpdbjobs: $!";
while (<JOBS>) {
my $job = parse_bpdbjobs($_)->[0];
# Can now refer to:
# $job->{'jobid'},
# $job->{'files'}->[0],
# $job->{'trypid'}->[0]->{'trystatus'},
#
$job->{'trypid'}->[0]->{'trystatuslines'}->[0],
# etc.
print Dumper($job);
# ... Do other stuff with $job here ...
}
close JOBS;
+----------------------------------------------------------------------
|This was sent by rmg AT ua DOT edu via Backup Central.
|Forward SPAM to abuse AT backupcentral DOT com.
+----------------------------------------------------------------------
_______________________________________________
Veritas-bu maillist - Veritas-bu AT mailman.eng.auburn DOT edu
http://mailman.eng.auburn.edu/mailman/listinfo/veritas-bu
|