xcat-core/xCAT-client/sbin/restorexCATdb
2012-06-01 15:17:08 +00:00

332 lines
9.2 KiB
Perl

#!/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 restorexCATdb
restorexCATdb -p <directory containing db restore .csv files>
restorexCATdb -b -p <directory binary database backup>
=cut
#-----------------------------------------------------------------------------
# Main
my $rc = 0;
&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_binrestore;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Restore Complete. You can now restart the daemons.");
} else {
xCAT::MsgUtils->message("E", "Restore Failed.");
}
exit $rc;
} else {
if ($DBname eq "PG") {
$rc=&PG_binrestore;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Restore Complete.");
} else {
xCAT::MsgUtils->message("I", "Restore Failed.");
}
exit $rc;
} else {
xCAT::MsgUtils->message("E",
"Binary dump (-b) is not supported for $DBname");
exit 1;
}
}
}
# read all the *.csv files from the input directory and restore the database
opendir DIRPATH, $::PATH;
if ($? != 0)
{
my $msg = " Unable to read directory $::PATH \n";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
# read tables to skip during restore from site.skiptables attribute
my @output2=xCAT::Utils->get_site_attribute('skiptables');
my @skiptbls;
if (@output2) {
@skiptbls = split (/\,/,$output2[0]);
}
my @files = readdir(DIRPATH);
foreach my $table (@files)
{
if ($table ne '.' and $table ne '..')
{
my $tablename = $::PATH;
$tablename .= "/";
$tablename .= $table;
if ( (!$::ALL) && (($table =~ /^eventlog/) || ($table =~ /^auditlog/))) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip teal tables
if ( $table =~ /^x_teal/ ) {
if ($::VERBOSEREST) {
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 and table in the site.skiptables attribute
if (@skiptbls) {
my ($tmptable,$suffix) = split(/\./,$table);
chomp $tmptable;
if (grep(/^$tmptable$/, @skiptbls)) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $tmptable\n");
}
next;
}
}
my $cmd = "tabrestore $tablename";
my @errout = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "Error running $cmd, @errout\n");
} else {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Restoring $table.\n");
}
}
}
}
closedir DIRPATH;
xCAT::MsgUtils->message("I", "Restore of Database Complete.");
exit $rc;
#-----------------------------------------------------------------------------
=head3 parse_args
Parses for input
=cut
#-----------------------------------------------------------------------------
sub parse_args
{
my $msg;
my $usagemsg =
" restorexCATdb -h \n restorexCATdb -v \n restorexCATdb [-a] [-V] <-p> [path to restore .csv files]\n restorexCATdb -b [-V] <-t> [timestamp on restore backup file] <-p> [path to restore backup file]";
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
if (
!GetOptions(
'a|all' => \$::ALL,
'b|binary' => \$::BINARY,
'p|path=s' => \$::PATH,
't|timestamp=s' => \$::TIMESTAMP,
'h|help' => \$::HELP,
'V|verbose' => \$::VERBOSEREST,
'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 = " -p with path to database files is required \n";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
if (!(-e $::PATH))
{
my $msg = " Input path must exist \n";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
}
#-----------------------------------------------------------------------------
=head3 DB2_binrestore
Uses the DB2 Database supplied restore utility to restore the database
=cut
#-----------------------------------------------------------------------------
sub DB2_binrestore
{
my $msg;
my $rc=0;
if (!($::TIMESTAMP)){
xCAT::MsgUtils->message("E", "To restore from a binary backup, the timestamp of the backup must be provided with the -t option.");
return 1;
}
# check to see if xcatd running. Cannot restore if it is
my $cmd = "ps -ef | grep xcatd";
my @output=xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC == 0) { # found something
if (grep(/xcatd: SSL listener/, @output)) { # xcatd running
xCAT::MsgUtils->message("E", "xcatd is still accessing the database. All applications accessing the DB2 database must be stopped before you can restore.");
return 1;
}
}
# 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);
# Hopefully nothing else is accessing the database, so try restore
$cmd="db2 restore db xcatdb user xcatdb using $pw from $::PATH taken at $::TIMESTAMP";
$rc = &rundb2cmd($cmd); # must su to xcatdb
if ($rc != 0)
{
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
}
# Now roll forward any tranactions since the backup
$cmd="db2 rollforward database xcatdb to end of logs and complete";
$rc = &rundb2cmd($cmd); # must su to xcatdb
if ($rc != 0)
{
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
}
return 0;
}
#-----------------------------------------------------------------------------
=head3 PG_binrestore
Uses the PostgreSQL Database supplied backup utility to restore the database
=cut
#-----------------------------------------------------------------------------
sub PG_binrestore
{
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);
# restore from backup file
my $cmd="$pgcmddir/pg_restore $::PATH -U postgres -d $dbname -c ";
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);
}