1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/lib/pgBackRest/Common/Exit.pm
David Steele 18fd25233b New simpler configuration and consistent project/exe/path naming.
* The repo-path option now always refers to the repository where backups and archive are stored, whether local or remote, so the repo-remote-path option has been removed. The new spool-path option can be used to define a location for queueing WAL segments when archiving asynchronously. Otherwise, a local repository is no longer required.

* Implemented a new config format which should be far simpler to use. See the User Guide and Configuration Reference for details but for a simple configuration all options can now be placed in the stanza section. Options that are shared between stanzas can be placed in the [global] section. More complex configurations can still make use of command sections though this should be a rare use case.

* The default configuration filename is now pgbackrest.conf instead of pg_backrest.conf. This was done for consistency with other naming changes but also to prevent old config files from being loaded accidentally.

* The default repository name was changed from /var/lib/backup to /var/lib/pgbackrest.

* Lock files are now stored in /tmp/pgbackrest by default. These days /run/pgbackrest would be the preferred location but that would require init scripts which are not part of this release. The lock-path option can be used to configure the lock directory.

* Log files are now stored in /var/log/pgbackrest by default and no longer have the date appended so they can be managed with logrotate. The log-path option can be used to configure the lock directory.

* Executable filename changed from pg_backrest to pgbackrest.
2016-04-14 09:30:54 -04:00

165 lines
5.7 KiB
Perl

####################################################################################################################################
# COMMON EXIT MODULE
####################################################################################################################################
package pgBackRest::Common::Exit;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use Exporter qw(import);
our @EXPORT = qw();
use File::Basename qw(dirname);
use Scalar::Util qw(blessed);
use lib dirname($0) . '/../lib';
use pgBackRest::Common::Exception;
use pgBackRest::Common::Lock;
use pgBackRest::Common::Log;
use pgBackRest::Config::Config;
####################################################################################################################################
# Operation constants
####################################################################################################################################
use constant OP_EXIT => 'Exit';
use constant OP_EXIT_SAFE => OP_EXIT . '::exitSafe';
####################################################################################################################################
# Signal constants
####################################################################################################################################
use constant SIGNAL_HUP => 'HUP';
use constant SIGNAL_INT => 'INT';
use constant SIGNAL_TERM => 'TERM';
####################################################################################################################################
# Hook important signals into exitSafe function
####################################################################################################################################
$SIG{&SIGNAL_HUP} = sub {exitSafe(-1, SIGNAL_HUP)};
$SIG{&SIGNAL_INT} = sub {exitSafe(-1, SIGNAL_INT)};
$SIG{&SIGNAL_TERM} = sub {exitSafe(-1, SIGNAL_TERM)};
####################################################################################################################################
# Module variables
####################################################################################################################################
my $iThreadMax = 1; # Total threads that were started for processing
my $bRemote = false; # Is the process a remote?
####################################################################################################################################
# exitInit
#
# Initialize exit so it knows if threads need to be terminated.
####################################################################################################################################
sub exitInit
{
my $iThreadMaxParam = shift;
my $bRemoteParam = shift;
if (defined($iThreadMaxParam) && $iThreadMaxParam > 1)
{
# Load module dynamically
require pgBackRest::Protocol::ThreadGroup;
pgBackRest::Protocol::ThreadGroup->import();
$iThreadMax = $iThreadMaxParam;
}
if (defined($bRemoteParam))
{
$bRemote = $bRemoteParam;
}
}
push @EXPORT, qw(exitInit);
####################################################################################################################################
# exitSafe
#
# Terminate all threads and SSH connections when the script is terminated.
####################################################################################################################################
sub exitSafe
{
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$iExitCode,
$strSignal
) =
logDebugParam
(
OP_EXIT_SAFE, \@_,
{name => 'iExitCode'},
{name => 'strSignal', 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))
{
my $oMessage = $@;
if (blessed($oMessage) && $oMessage->isa('pgBackRest::Common::Exception'))
{
&log(WARN, 'unable to shutdown protocol (' . $oMessage->code() . '): ' . $oMessage->message());
exit $oMessage->code();
}
&log(WARN, "unable to shutdown protocol: $oMessage");
}
# Don't fail if the lock can't be released
eval
{
lockRelease(false);
};
# Exit with code when defined
if ($iExitCode != -1)
{
exit $iExitCode;
}
# Log error based on where the signal came from
&log(ERROR, 'process terminated ' .
(defined($strSignal) ? "on a ${strSignal} signal" : 'due to an unhandled exception') .
($iThreadsStopped > 0 ? ", ${iThreadsStopped} threads stopped" : ''),
defined($strSignal) ? ERROR_TERM : ERROR_UNHANDLED_EXCEPTION);
# If terminated by a signal exit with 0 code
exit ERROR_TERM if defined($strSignal);
# Return from function and log return values if any
return logDebugReturn($strOperation);
}
push @EXPORT, qw(exitSafe);
1;