mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
de7fc37f88
Refactor storage layer to allow for new repository filesystems using drivers. (Reviewed by Cynthia Shang.) Refactor IO layer to allow for new compression formats, checksum types, and other capabilities using filters. (Reviewed by Cynthia Shang.)
152 lines
4.7 KiB
Perl
152 lines
4.7 KiB
Perl
####################################################################################################################################
|
|
# Protocol File
|
|
####################################################################################################################################
|
|
package pgBackRest::Protocol::Storage::File;
|
|
use parent '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 pgBackRest::Common::Exception;
|
|
use pgBackRest::Common::Log;
|
|
|
|
####################################################################################################################################
|
|
# CONSTRUCTOR
|
|
####################################################################################################################################
|
|
sub new
|
|
{
|
|
my $class = shift;
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
my
|
|
(
|
|
$strOperation,
|
|
$oProtocol, # Master or minion protocol
|
|
$oFileIo, # File whose results will be returned via protocol
|
|
) =
|
|
logDebugParam
|
|
(
|
|
__PACKAGE__ . '->new', \@_,
|
|
{name => 'oProtocol', trace => true},
|
|
{name => 'oFileIo', required => false, trace => true},
|
|
);
|
|
|
|
# Create class
|
|
my $self = $class->SUPER::new($oProtocol->io()->id() . ' file');
|
|
bless $self, $class;
|
|
|
|
# Set variables
|
|
$self->{oProtocol} = $oProtocol;
|
|
$self->{oFileIo} = $oFileIo;
|
|
|
|
# Set read/write
|
|
$self->{bWrite} = false;
|
|
|
|
# Return from function and log return values if any
|
|
return logDebugReturn
|
|
(
|
|
$strOperation,
|
|
{name => 'self', value => $self}
|
|
);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# read - read block from protocol
|
|
####################################################################################################################################
|
|
sub read
|
|
{
|
|
my $self = shift;
|
|
my $rtBuffer = shift;
|
|
|
|
my $lBlockSize;
|
|
|
|
# Read the block header and make sure it's valid
|
|
my $strBlockHeader = $self->{oProtocol}->io()->readLine();
|
|
|
|
if ($strBlockHeader !~ /^BRBLOCK[0-9]+$/)
|
|
{
|
|
confess &log(ERROR, "invalid block header '${strBlockHeader}'", ERROR_FILE_READ);
|
|
}
|
|
|
|
# Get block size from the header
|
|
$lBlockSize = substr($strBlockHeader, 7);
|
|
|
|
# Read block if size > 0
|
|
if ($lBlockSize > 0)
|
|
{
|
|
$self->{oProtocol}->io()->read($rtBuffer, $lBlockSize, true);
|
|
}
|
|
|
|
# Return the block size
|
|
return $lBlockSize;
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# write - write block to protocol
|
|
####################################################################################################################################
|
|
sub write
|
|
{
|
|
my $self = shift;
|
|
my $rtBuffer = shift;
|
|
|
|
# Set write
|
|
$self->{bWrite} = true;
|
|
|
|
# Get the buffer size
|
|
my $lBlockSize = defined($rtBuffer) ? length($$rtBuffer) : 0;
|
|
|
|
# Write if size > 0 (0 ends the copy stream so it should only be done in close())
|
|
if ($lBlockSize > 0)
|
|
{
|
|
# Write block header to the protocol stream
|
|
$self->{oProtocol}->io()->writeLine("BRBLOCK${lBlockSize}");
|
|
|
|
# Write block if size
|
|
$self->{oProtocol}->io()->write($rtBuffer);
|
|
}
|
|
|
|
return length($$rtBuffer);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# close - set the result hash
|
|
####################################################################################################################################
|
|
sub close
|
|
{
|
|
my $self = shift;
|
|
|
|
# Close if protocol is defined (to prevent this from running more than once)
|
|
if (defined($self->{oProtocol}))
|
|
{
|
|
# If writing output terminator
|
|
if ($self->{bWrite})
|
|
{
|
|
$self->{oProtocol}->io()->writeLine("BRBLOCK0");
|
|
}
|
|
|
|
# On master read the results
|
|
if ($self->{oProtocol}->master())
|
|
{
|
|
($self->{rhResult}) = $self->{oProtocol}->outputRead();
|
|
|
|
# Minion will send one more output message after file is closed which can be ignored
|
|
$self->{oProtocol}->outputRead();
|
|
}
|
|
# On minion write the results
|
|
else
|
|
{
|
|
$self->{oProtocol}->outputWrite($self->{oFileIo}->{rhResult});
|
|
}
|
|
|
|
# Delete protocol to prevent close from running again
|
|
delete($self->{oProtocol});
|
|
}
|
|
}
|
|
|
|
1;
|