#!/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 { if ($DBname eq "PG") { $rc=&PG_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 not supported for $DBname"); 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 backup directory] \n dumpxCATdb -b [-V] <-p> [path to backup 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 PG_bindump Uses the PostgreSQL Database supplied backup utility to backup the database =cut #----------------------------------------------------------------------------- sub PG_bindump { my $msg; my $rc=0; my $pgcmddir = "/usr/bin"; # get path to Postgresql commands if running 9.X version my $cmd = "rpm -qa | grep postgresql"; my @output=xCAT::Utils->runcmd($cmd, 0); if ($::RUNCMD_RC != 0) { my $message = "\nPostgreSQL is not installed. If on AIX, it should be first obtained from the xcat dependency tarballs and installed before running this command.\n If on Linux, install from the OS CDs."; xCAT::MsgUtils->message("E", " $cmd failed. $message"); exit(1); } # check if 9.X release, setup different if (grep(/postgresql9/, @output)) { # postgresql 9.x # figure out which 9.x release and build path # for example 9.x release /usr/pgsql-9.x/bin my @parseout= split(/\-/, $output[0]); my @ptflevel= split ("postgresql9",$parseout[0]); my $postgres9=@ptflevel[1]; # set it to the PTF level $pgcmddir = "/usr/pgsql-9.$postgres9/bin"; # pg cmds location } # Get database, admin from cfgloc file 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,$admin,$pw) = split(/\|/, $info); my ($info1,$info2) = split(/=/,$db); my ($dbname,$host) = split(/;/,$info2); # create backup file name my $backupfile="$::PATH/pgbackup.$$"; my $cmd="$pgcmddir/pg_dump $dbname -f $backupfile -U postgres -F custom"; my $info=xCAT::Utils->runcmd($cmd, -1); if ($::RUNCMD_RC != 0) { xCAT::MsgUtils->message("E", "$cmd failed"); 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); }