1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/lib/pgBackRest/Common/Io/Base.pm
David Steele d211c2b8b5 Fix possible truncated WAL segments when an error occurs mid-write.
The file write object destructors called close() and finalized the file even if it was not completely written.  This was an issue in both the C and Perl code.

Rewrite the destructors to simply free resources (like file handles) rather than calling the close() method.  This leaves the temp file in place for filesystems that use temp files.

Add unit tests to prevent regression.

Reported by blogh.
2019-02-15 11:52:39 +02:00

115 lines
4.1 KiB
Perl

####################################################################################################################################
# Base IO Module
####################################################################################################################################
package pgBackRest::Common::Io::Base;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use Exporter qw(import);
our @EXPORT = qw();
use Scalar::Util qw(blessed);
use pgBackRest::Common::Log;
####################################################################################################################################
# Package name constant
####################################################################################################################################
use constant COMMON_IO_BASE => __PACKAGE__;
push @EXPORT, qw(COMMON_IO_BASE);
####################################################################################################################################
# Default buffer max
####################################################################################################################################
use constant COMMON_IO_BUFFER_MAX => 4194304;
push @EXPORT, qw(COMMON_IO_BUFFER_MAX);
####################################################################################################################################
# new
####################################################################################################################################
sub new
{
my $class = shift;
# Create the class hash
my $self = {};
bless $self, $class;
# Assign function parameters, defaults, and log debug info
(
my $strOperation,
$self->{strId},
) =
logDebugParam
(
__PACKAGE__ . '->new', \@_,
{name => 'strId', trace => true},
);
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'self', value => $self}
);
}
####################################################################################################################################
# error - throw errors
####################################################################################################################################
sub error
{
my $self = shift;
my $iCode = shift;
my $strMessage = shift;
my $strDetail = shift;
logErrorResult($iCode, $strMessage, $strDetail);
}
####################################################################################################################################
# result - retrieve a result from io or a filter
####################################################################################################################################
sub result
{
my $self = shift;
my $strModule = shift;
if (!defined($strModule))
{
return $self->{rhResult};
}
return $self->{rhResult}{$strModule};
}
####################################################################################################################################
# resultAll - get all results
####################################################################################################################################
sub resultAll
{
shift->{rhResult};
}
####################################################################################################################################
# resultSet - set a result from io or a filter
####################################################################################################################################
sub resultSet
{
my $self = shift;
my $strModule = shift;
my $xResult = shift;
$self->{rhResult}{$strModule} = $xResult;
}
####################################################################################################################################
# Getters
####################################################################################################################################
sub className {blessed(shift)}
sub id {shift->{strId}}
1;