Implemented issue #129: Stop/Start Commands.

Implemented issue #136: Add stderr back into protocol layer.

There were also miscellaneous bug fixes and improvements to buffering in IO.pm.
This commit is contained in:
David Steele
2015-10-08 11:43:56 -04:00
parent e488f7bb19
commit ddd4c14773
66 changed files with 6963 additions and 3016 deletions
+76 -149
View File
@@ -19,84 +19,12 @@ use Scalar::Util qw(blessed);
use lib dirname($0) . '/../lib';
use BackRest::Archive;
use BackRest::Common::Exception;
use BackRest::Common::Exit;
use BackRest::Common::Lock;
use BackRest::Common::Log;
use BackRest::Config::Config;
use BackRest::File;
####################################################################################################################################
# Operation constants
####################################################################################################################################
use constant OP_MAIN => 'Main';
use constant OP_MAIN_SAFE_EXIT => OP_MAIN . '::safeExit';
####################################################################################################################################
# safeExit
#
# Terminate all threads and SSH connections when the script is terminated.
####################################################################################################################################
my $iThreadMax = 1;
sub safeExit
{
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$iExitCode
) =
logDebugParam
(
OP_MAIN_SAFE_EXIT, \@_,
{name => 'iExitCode', required => false}
);
commandStop();
# Stop threads if threading is enabled
my $iThreadsStopped = 0;
if ($iThreadMax > 1)
{
&log(DEBUG, "stop ${iThreadMax} threads");
# Don't fail if the threads cannot be stopped
eval
{
$iThreadsStopped = threadGroupDestroy();
};
if ($@ && defined($iExitCode))
{
&log(WARN, "unable to stop threads: $@");
}
}
# Don't fail if protocol cannot be destroyed
eval
{
protocolDestroy();
};
if ($@ && defined($iExitCode))
{
&log(WARN, "unable to shutdown protocol: $@");
}
# Exit with code when defined
if (defined($iExitCode))
{
exit $iExitCode;
}
# Else the process was terminated on a signal or exception
&log(ERROR, 'process terminated on signal or exception' . ($iThreadsStopped > 0 ? "${iThreadsStopped} threads stopped" : ''));
}
$SIG{TERM} = \&safeExit;
$SIG{HUP} = \&safeExit;
$SIG{INT} = \&safeExit;
####################################################################################################################################
# START EVAL BLOCK TO CATCH ERRORS AND STOP THREADS
####################################################################################################################################
@@ -116,16 +44,20 @@ eval
# Generate help and exit
configHelp($ARGV[1], $ARGV[2], commandTest(CMD_VERSION), $bConfigResult);
safeExit(0);
exitSafe(0);
}
# Set test options
!optionGet(OPTION_TEST, false) or
testSet(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY), optionGet(OPTION_TEST_POINT, false));
################################################################################################################################
# Process remote commands
################################################################################################################################
if (commandTest(CMD_REMOTE))
{
# Turn all logging off
logLevelSet(OFF, OFF);
# Set log levels
logLevelSet(OFF, REMOTE);
# Load module dynamically
require BackRest::Protocol::RemoteMinion;
@@ -134,21 +66,26 @@ eval
# Create the remote object
my $oRemote = new BackRest::Protocol::RemoteMinion
(
optionGet(OPTION_COMMAND),
optionGet(OPTION_BUFFER_SIZE),
optionGet(OPTION_COMPRESS_LEVEL),
optionGet(OPTION_COMPRESS_LEVEL_NETWORK)
optionGet(OPTION_COMPRESS_LEVEL_NETWORK),
protocolTimeoutGet()
);
# !!! Would like to remove this check and allow a test lock
if (optionGet(OPTION_COMMAND) ne 'test' && !optionTest(OPTION_PROCESS))
{
lockAcquire(optionGet(OPTION_COMMAND), undef, true, optionGet(OPTION_PROCESS, false));
}
# Process remote requests
safeExit($oRemote->process());
exitSafe($oRemote->process());
}
# Set the log levels
logLevelSet(optionGet(OPTION_LOG_LEVEL_FILE), optionGet(OPTION_LOG_LEVEL_CONSOLE));
# Set test options
!optionGet(OPTION_TEST) or testSet(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY));
# Log the command start
commandStart();
@@ -157,7 +94,21 @@ eval
################################################################################################################################
if (commandTest(CMD_ARCHIVE_PUSH) || commandTest(CMD_ARCHIVE_GET))
{
safeExit(new BackRest::Archive()->process());
exitSafe(new BackRest::Archive()->process());
}
################################################################################################################################
# Process start/stop commands
################################################################################################################################
if (commandTest(CMD_START))
{
lockStart();
exitSafe(0);
}
elsif (commandTest(CMD_STOP))
{
lockStop();
exitSafe(0);
}
################################################################################################################################
@@ -169,16 +120,12 @@ eval
require BackRest::Info;
BackRest::Info->import();
safeExit(new BackRest::Info()->process());
exitSafe(new BackRest::Info()->process());
}
################################################################################################################################
# Acquire the command lock
################################################################################################################################
# Load module dynamically
require BackRest::Common::Lock;
BackRest::Common::Lock->import();
lockAcquire(commandGet());
################################################################################################################################
@@ -191,8 +138,8 @@ eval
################################################################################################################################
if (optionTest(OPTION_THREAD_MAX) && optionGet(OPTION_THREAD_MAX) > 1)
{
# Set local thread-max so safeExit knows to stop them on exit
$iThreadMax = optionGet(OPTION_THREAD_MAX);
# Set local thread-max so exitSafe knows to stop them on exit
exitInit(optionGet(OPTION_THREAD_MAX));
# Load module dynamically
require BackRest::Protocol::ThreadGroup;
@@ -201,17 +148,6 @@ eval
threadGroupCreate();
}
################################################################################################################################
# Initialize the default file object
################################################################################################################################
my $oFile = new BackRest::File
(
optionGet(OPTION_STANZA),
optionRemoteTypeTest(BACKUP) ? optionGet(OPTION_REPO_REMOTE_PATH) : optionGet(OPTION_REPO_PATH),
optionRemoteType(),
protocolGet()
);
################################################################################################################################
# RESTORE
################################################################################################################################
@@ -227,58 +163,49 @@ eval
BackRest::Restore->import();
# Do the restore
new BackRest::Restore
(
$oFile
)->process;
new BackRest::Restore()->process();
safeExit(0);
exitSafe(0);
}
################################################################################################################################
# Make sure backup and expire command happen on the backup side
################################################################################################################################
if (optionRemoteTypeTest(BACKUP))
else
{
confess &log(ERROR, 'backup and expire commands must run on the backup host');
############################################################################################################################
# Make sure backup and expire commands happen on the backup side
############################################################################################################################
if (optionRemoteTypeTest(BACKUP))
{
confess &log(ERROR, 'backup and expire commands must run on the backup host');
}
############################################################################################################################
# BACKUP
############################################################################################################################
if (commandTest(CMD_BACKUP))
{
# Load module dynamically
require BackRest::Backup;
BackRest::Backup->import();
new BackRest::Backup()->process();
commandSet(CMD_EXPIRE);
}
############################################################################################################################
# EXPIRE
############################################################################################################################
if (commandTest(CMD_EXPIRE))
{
# Load module dynamically
require BackRest::Expire;
BackRest::Expire->import();
new BackRest::Expire()->process();
}
}
################################################################################################################################
# BACKUP
################################################################################################################################
if (commandTest(CMD_BACKUP))
{
# Load module dynamically
require BackRest::Backup;
BackRest::Backup->import();
new BackRest::Backup
(
$oFile
)->process();
commandSet(CMD_EXPIRE);
}
################################################################################################################################
# EXPIRE
################################################################################################################################
if (commandTest(CMD_EXPIRE))
{
# Load module dynamically
require BackRest::Expire;
BackRest::Expire->import();
new BackRest::Expire
(
$oFile
)->process();
}
# Release the command lock
lockRelease();
safeExit(0);
exitSafe(0);
};
####################################################################################################################################
@@ -291,9 +218,9 @@ if ($@)
# If a backrest exception then return the code - don't confess
if (blessed($oMessage) && $oMessage->isa('BackRest::Common::Exception'))
{
safeExit($oMessage->code());
exitSafe($oMessage->code());
}
safeExit();
exitSafe(-1);
confess $oMessage;
}