提交 b4bf1ed1 编写于 作者: A Adam Berlin 提交者: Adam Berlin

Validate symlink target before adding symlink to basebackup TAR.

Symlink targets are only allowed to be 100 characters long according
to the TAR format we use to send base backups.

Send a warning to the user that the symlink target path is too long,
and that the symlink directory will not be included in the backup.
上级 a42e8b91
......@@ -90,6 +90,7 @@
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/tarrable.h"
#include "utils/tqual.h"
#include "catalog/heap.h"
......@@ -100,9 +101,6 @@
#include "miscadmin.h"
#define MAX_TARABLE_SYMLINK_PATH_LENGTH 100
/* GUC variables */
char *default_tablespace = NULL;
char *temp_tablespaces = NULL;
......
......@@ -49,6 +49,7 @@
#include "utils/guc.h"
#include "utils/ps_status.h"
#include "utils/snapmgr.h"
#include "utils/tarrable.h"
#include "utils/timestamp.h"
......@@ -285,6 +286,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
#if defined(HAVE_READLINK) || defined(WIN32)
rllen = readlink(fullpath, linkpath, sizeof(linkpath));
if (rllen < 0)
{
ereport(WARNING,
......@@ -292,11 +294,12 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
fullpath)));
continue;
}
else if (rllen >= sizeof(linkpath))
else if (rllen >= MAX_TARABLE_SYMLINK_PATH_LENGTH)
{
ereport(WARNING,
(errmsg("symbolic link \"%s\" target is too long",
fullpath)));
(errmsg("symbolic link \"%s\" target is too long and will not be added to the backup",
fullpath),
errdetail("The symbolic link with target \"%s\" is too long. Symlink targets with length greater than %d characters would be truncated.", linkpath, MAX_TARABLE_SYMLINK_PATH_LENGTH)));
continue;
}
linkpath[rllen] = '\0';
......
......@@ -2,7 +2,7 @@ use strict;
use warnings;
use Cwd;
use TestLib;
use Test::More tests => 34;
use Test::More tests => 40;
program_help_ok('pg_basebackup');
program_version_ok('pg_basebackup');
......@@ -124,6 +124,35 @@ SKIP: {
ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
psql 'postgres', "DROP TABLESPACE tblspc2;";
my $twenty_characters = '11111111112222222222';
my $longer_tempdir = "$tempdir/some_long_directory_path_$twenty_characters$twenty_characters$twenty_characters$twenty_characters$twenty_characters";
my $some_backup_dir = "$tempdir/backup_dir";
my $some_other_backup_dir = "$tempdir/other_backup_dir";
mkdir "$longer_tempdir";
mkdir "$some_backup_dir";
psql 'postgres', "CREATE TABLESPACE too_long_tablespace LOCATION '$longer_tempdir';";
command_warns_like([
'pg_basebackup',
'-D', "$some_backup_dir",
'--target-gp-dbid', '99'],
qr/WARNING: symbolic link ".*" target is too long and will not be added to the backup/,
'basebackup with a tablespace that has a very long location should warn target is too long.');
mkdir "$some_other_backup_dir";
command_warns_like([
'pg_basebackup',
'-D', "$some_other_backup_dir",
'--target-gp-dbid', '99'],
qr/The symbolic link with target ".*" is too long. Symlink targets with length greater than 100 characters would be truncated./,
'basebackup with a tablespace that has a very long location should warn link not added to the backup.');
command_fails_like([
'ls', "$some_other_backup_dir/pg_tblspc/*"],
qr/No such file/,
'tablespace directory should be empty');
}
command_fails(
......
/*-------------------------------------------------------------------------
*
* tarrable.h
*
*
* Copyright (c) 2019-Present Pivotal Software, Inc.
*
*
* IDENTIFICATION
* src/include/utils/tarrable.h
*
*-------------------------------------------------------------------------
*/
#ifndef TARRABLE_H
#define TARRABLE_H
#define MAX_TARABLE_SYMLINK_PATH_LENGTH 100
#endif /* TARRABLE_H */
......@@ -42,6 +42,8 @@ our @EXPORT = qw(
program_version_ok
program_options_handling_ok
command_like
command_warns_like
command_fails_like
issues_sql_like
$tmp_check
......@@ -387,14 +389,26 @@ sub command_like
like($stdout, $expected_stdout, "$test_name: matches");
}
sub command_fails_like
sub command_warns_like
{
my ($cmd, $expected_sql, $test_name) = @_;
truncate $test_server_logfile, 0;
my $result = run_log($cmd);
my ($cmd, $expected_stderr, $test_name) = @_;
my ($stdout, $stderr);
print("# Running: " . join(" ", @{$cmd}) . "\n");
my $result = run $cmd, '>', \$stdout, '2>', \$stderr;
ok($result, "@$cmd exit code 0");
my $log = slurp_file($test_server_logfile);
like($log, $expected_sql, "$test_name: SQL found in server log");
like($stderr, $expected_stderr, "$test_name: matches.");
}
sub command_fails_like
{
my ($cmd, $expected_stderr, $test_name) = @_;
my ($stdout, $stderr);
print("# Running: " . join(" ", @{$cmd}) . "\n");
my $result = run $cmd, '>', \$stdout, '2>', \$stderr;
ok(!$result, "expected failure: got @$cmd exit code 0");
like($stderr, $expected_stderr, "$test_name: not match expected stderr");
}
1;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册