#!/usr/bin/perl # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html #(C)IBM Corp # BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } use lib "$::XCATROOT/lib/perl"; use Getopt::Long; use xCAT::MsgUtils; use xCAT::Utils; use strict; #----------------------------------------------------------------------------- =head1 dumpxCATdb dumpxCATdb -p See man page. =cut #----------------------------------------------------------------------------- # Main my $rc = 0; my $cmd; &parse_args; if ($::BINARY) { # not using xCAT to dump, using the database utility my $DBname = xCAT::Utils->get_DBName; if ($DBname eq "DB2") { $rc=&DB2_bindump; if ($rc == 0) { xCAT::MsgUtils->message("I", "Backup Complete."); } else { xCAT::MsgUtils->message("I", "Backup Failed."); } exit $rc; } else { xCAT::MsgUtils->message("E", "Binary dump (-b) is only supported for DB2"); exit 1; } } # Dump using xCAT utilities my @output = xCAT::Utils->runcmd("tabdump", 0); if ($::RUNCMD_RC != 0) { # error xCAT::MsgUtils->message("E", "Error running tabdump to get list of tables"); exit 1; } # Determine which table to skip my @output2; if ($ENV{'XCAT_SKIPTABLES'}) { @output2=$ENV{'XCAT_SKIPTABLES'}; } else { # read tables to skip from site.skiptables attribute @output2=xCAT::Utils->get_site_attribute('skiptables'); } my @skiptbls; if (@output2) { @skiptbls = split (/\,/,$output2[0]); } foreach my $table (@output) { # if not -a request , skip eventlog and auditlog if ( (!$::ALL) && (($table =~ /^eventlog/) || ($table =~ /^auditlog/))) { if ($::DUMPVERBOSE) { xCAT::MsgUtils->message("I", "Skipping $table\n"); } next; } # skip teal tables if ( $table =~ /^x_teal/ ) { if ($::DUMPVERBOSE) { xCAT::MsgUtils->message("I", "Skipping $table\n"); } next; } # skip ISNM tables except isnm_config if ( $table =~ /^isnm_perf/ ) { if ($::DUMPVERBOSE) { xCAT::MsgUtils->message("I", "Skipping $table\n"); } next; } # skip any table in the site.skiptables attribute if (grep(/^$table$/, @skiptbls)) { if ($::DUMPVERBOSE) { xCAT::MsgUtils->message("I", "Skipping $table\n"); } next; } $cmd = "tabdump -f $::PATH/$table.csv $table"; my @errout = xCAT::Utils->runcmd($cmd, 0); if ($::RUNCMD_RC != 0) { # error xCAT::MsgUtils->message("E", "Error running $cmd, @errout"); } else { if ($::DUMPVERBOSE) { xCAT::MsgUtils->message("I", "Dumping $table"); } } } xCAT::MsgUtils->message("I", "Backup Complete."); exit $rc; #----------------------------------------------------------------------------- =head3 parse_args Parses for input =cut #----------------------------------------------------------------------------- sub parse_args { my $msg; my $usagemsg = " dumpxCATdb -h \n dumpxCATdb -v \n dumpxCATdb [-a] [-V] <-p> [path to dump directory] \n dumpxCATdb -b [-V] <-p> [path to dump directory]"; Getopt::Long::Configure("posix_default"); Getopt::Long::Configure("no_gnu_compat"); Getopt::Long::Configure("bundling"); if ( !GetOptions( 'a|all' => \$::ALL, 'b|bin' => \$::BINARY, 'p|path=s' => \$::PATH, 'h|help' => \$::HELP, 'V|verbose' => \$::DUMPVERBOSE, 'v|version' => \$::VERSION ) ) { xCAT::MsgUtils->message("E", $usagemsg); exit 1; } if ($::HELP) { xCAT::MsgUtils->message("I", $usagemsg); exit 0; } if ($::VERSION) { my $version = xCAT::Utils->Version(); xCAT::MsgUtils->message("N", $version); exit 0; } if (!($::PATH)) { my $msg = " Requires -p with path to directory to hold db files."; xCAT::MsgUtils->message("E", $msg); exit 1; } if (!( -e $::PATH)) { my $msg = " Creating $::PATH for database dump"; xCAT::MsgUtils->message("I", $msg); my @output = xCAT::Utils->runcmd("mkdir -p $::PATH", 0); if ($::RUNCMD_RC != 0) { # error xCAT::MsgUtils->message("E", "Error running mkdir -p $::PATH"); exit 1; } } } #----------------------------------------------------------------------------- =head3 DB2_bindump Uses the DB2 Database supplied backup utility to backup the database =cut #----------------------------------------------------------------------------- sub DB2_bindump { my $msg; my $rc=0; # check to see if they are setup to do an online dump # Database has to have defined logretain RECOVERY and there # must already been taken an offline backup. my $cmd="db2 get database configuration for xcatdb > /tmp/db2output"; $rc = &rundb2cmd($cmd); # must su to xcatdb if ($rc != 0) { xCAT::MsgUtils->message("E", " $cmd error."); return 1; } # check to see if they setup log recover $cmd = " egrep -i \"Log retain for recovery enabled\" /tmp/db2output"; my @output=xCAT::Utils->runcmd($cmd, -1); if ($::RUNCMD_RC != 0) { xCAT::MsgUtils->message("E", "Log retain for recovery enabled (LOGRETAIN) = RECOVERY must be set to perform ONLINE Backups and one ONLINE backup must have been taken. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands."); return 1; } else { # check to see if LOGRETAIN is ON if (!grep(/ = RECOVERY/, @output)) { xCAT::MsgUtils->message("E", "Log retain for recovery enabled (LOGRETAIN) = RECOVERY must be set to perform ONLINE Backups and one ONLINE backup must have been taken. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands."); return 1; } } # check to see if they have one backup $cmd = " ls $::PATH"; @output=xCAT::Utils->runcmd($cmd, -1); if ($::RUNCMD_RC != 0) { xCAT::MsgUtils->message("E", "One ONLINE backup must have been taken and exist in $::PATH. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands."); return 1; } else { # check to see if LOGRETAIN is ON if (!grep(/XCATDB/, @output)) { xCAT::MsgUtils->message("E", "One ONLINE backup must have been taken and exist in $::PATH. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands."); return 1; } } # finally all checks ok, can take an ONLINE backup # get password from cfgloc my $cmd="cat /etc/xcat/cfgloc"; my $info=xCAT::Utils->runcmd($cmd, -1); if ($::RUNCMD_RC != 0) { xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc."); return 1; } chomp($info); my ($db,$inst,$pw) = split(/\|/, $info); my $cmd=" db2 backup db xcatdb user xcatdb using $pw ONLINE to $::PATH"; $rc = &rundb2cmd($cmd); # must su to xcatdb if ($rc != 0) { xCAT::MsgUtils->message("E", " $cmd error."); return 1; } return 0; } #----------------------------------------------------------------------------- =head3 rundb2cmd Run a commmand as the xcatdb instance id Input: command =cut #----------------------------------------------------------------------------- sub rundb2cmd { my $orgcmd = shift; my $rc = 0; my $cmd = "\'"; $cmd .= $orgcmd; $cmd .= ' 2>&1'; $cmd .= "\'"; system("su - xcatdb -c $cmd"); if ($? > 0) # error { $rc = $? >> 8; } return ($rc); }