mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-06-20 01:17:49 +02:00
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:
+76
-149
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user