Skip to content

Commit 73a6915

Browse files
committed
[Issue #228]: add strict mode to get_data_file_headers()
1 parent ac1ff37 commit 73a6915

File tree

4 files changed

+52
-20
lines changed

4 files changed

+52
-20
lines changed

src/data.c

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -823,10 +823,11 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out,
823823
/* get headers for this file */
824824
if (use_headers && tmp_file->n_headers > 0)
825825
headers = get_data_file_headers(&(backup->hdr_map), tmp_file,
826-
parse_program_version(backup->program_version));
826+
parse_program_version(backup->program_version),
827+
true);
827828

828829
if (use_headers && !headers && tmp_file->n_headers > 0)
829-
elog(ERROR, "Failed to get headers for file \"%s\"", from_fullpath);
830+
elog(ERROR, "Failed to get page headers for file \"%s\"", from_fullpath);
830831

831832
/*
832833
* Restore the file.
@@ -1599,10 +1600,13 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
15991600
elog(ERROR, "Cannot open file \"%s\": %s",
16001601
fullpath, strerror(errno));
16011602

1602-
headers = get_data_file_headers(hdr_map, file, backup_version);
1603+
headers = get_data_file_headers(hdr_map, file, backup_version, false);
16031604

16041605
if (!headers && file->n_headers > 0)
1605-
elog(ERROR, "Failed to get headers for file \"%s\"", fullpath);
1606+
{
1607+
elog(WARNING, "Cannot get page headers for file \"%s\"", fullpath);
1608+
return false;
1609+
}
16061610

16071611
/* calc CRC of backup file */
16081612
INIT_FILE_CRC32(use_crc32c, crc);
@@ -2124,8 +2128,9 @@ send_pages(ConnectionArgs* conn_arg, const char *to_fullpath, const char *from_f
21242128
* array of headers.
21252129
*/
21262130
BackupPageHeader2*
2127-
get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version)
2131+
get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict)
21282132
{
2133+
bool success = false;
21292134
FILE *in = NULL;
21302135
size_t read_len = 0;
21312136
pg_crc32 hdr_crc;
@@ -2145,42 +2150,55 @@ get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version)
21452150
in = fopen(hdr_map->path, PG_BINARY_R);
21462151

21472152
if (!in)
2148-
elog(ERROR, "Cannot open header file \"%s\": %s", hdr_map->path, strerror(errno));
2153+
{
2154+
elog(strict ? ERROR : WARNING, "Cannot open header file \"%s\": %s", hdr_map->path, strerror(errno));
2155+
return NULL;
2156+
}
21492157
/* disable buffering for header file */
21502158
setvbuf(in, NULL, _IONBF, BUFSIZ);
21512159

21522160
if (fseek(in, file->hdr_off, SEEK_SET))
2153-
elog(ERROR, "Cannot seek to position %lu in page header map \"%s\": %s",
2161+
{
2162+
elog(strict ? ERROR : WARNING, "Cannot seek to position %lu in page header map \"%s\": %s",
21542163
file->hdr_off, hdr_map->path, strerror(errno));
2164+
goto cleanup;
2165+
}
21552166

21562167
/*
21572168
* The actual number of headers in header file is n+1, last one is a dummy header,
21582169
* used for calculation of read_len for actual last header.
21592170
*/
21602171
read_len = (file->n_headers+1) * sizeof(BackupPageHeader2);
21612172

2162-
/* allocate memory for compressed and uncompressed headers */
2163-
headers = pgut_malloc(read_len);
2164-
memset(headers, 0, read_len);
2173+
/* allocate memory for compressed headers */
21652174
zheaders = pgut_malloc(file->hdr_size);
21662175
memset(zheaders, 0, file->hdr_size);
21672176

21682177
if (fread(zheaders, 1, file->hdr_size, in) != file->hdr_size)
2169-
elog(ERROR, "Cannot read header file at offset: %li len: %i \"%s\": %s",
2178+
{
2179+
elog(strict ? ERROR : WARNING, "Cannot read header file at offset: %li len: %i \"%s\": %s",
21702180
file->hdr_off, file->hdr_size, hdr_map->path, strerror(errno));
2181+
goto cleanup;
2182+
}
21712183

21722184
// elog(INFO, "zsize: %i, size: %i", file->hdr_size, read_len);
21732185

2186+
/* allocate memory for uncompressed headers */
2187+
headers = pgut_malloc(read_len);
2188+
memset(headers, 0, read_len);
2189+
21742190
z_len = do_decompress(headers, read_len, zheaders, file->hdr_size,
21752191
ZLIB_COMPRESS, &errormsg);
21762192
if (z_len <= 0)
21772193
{
21782194
if (errormsg)
2179-
elog(ERROR, "An error occured during metadata decompression for file \"%s\": %s",
2195+
elog(strict ? ERROR : WARNING, "An error occured during metadata decompression for file \"%s\": %s",
21802196
file->rel_path, errormsg);
21812197
else
2182-
elog(ERROR, "An error occured during metadata decompression for file \"%s\": %i",
2198+
elog(strict ? ERROR : WARNING, "An error occured during metadata decompression for file \"%s\": %i",
21832199
file->rel_path, z_len);
2200+
2201+
goto cleanup;
21842202
}
21852203

21862204
/* validate checksum */
@@ -2189,13 +2207,26 @@ get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version)
21892207
FIN_FILE_CRC32(true, hdr_crc);
21902208

21912209
if (hdr_crc != file->hdr_crc)
2192-
elog(ERROR, "Header map for file \"%s\" crc mismatch \"%s\" offset: %lu, len: %lu, current: %u, expected: %u",
2210+
{
2211+
elog(strict ? ERROR : WARNING, "Header map for file \"%s\" crc mismatch \"%s\" "
2212+
"offset: %lu, len: %lu, current: %u, expected: %u",
21932213
file->rel_path, hdr_map->path, file->hdr_off, read_len, hdr_crc, file->hdr_crc);
2214+
goto cleanup;
2215+
}
21942216

2195-
if (fclose(in))
2196-
elog(ERROR, "Cannot close file \"%s\"", hdr_map->path);
2217+
success = true;
2218+
2219+
cleanup:
21972220

21982221
pg_free(zheaders);
2222+
if (in && fclose(in))
2223+
elog(ERROR, "Cannot close file \"%s\"", hdr_map->path);
2224+
2225+
if (!success)
2226+
{
2227+
pg_free(headers);
2228+
headers = NULL;
2229+
}
21992230

22002231
return headers;
22012232
}

src/merge.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,8 @@ merge_files(void *arg)
10821082
/* Copy header metadata from old map into a new one */
10831083
tmp_file->n_headers = file->n_headers;
10841084
headers = get_data_file_headers(&(arguments->full_backup->hdr_map), file,
1085-
parse_program_version(arguments->full_backup->program_version));
1085+
parse_program_version(arguments->full_backup->program_version),
1086+
true);
10861087

10871088
/* sanity */
10881089
if (!headers && file->n_headers > 0)

src/pg_probackup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ extern pid_t check_postmaster(const char *pgdata);
10201020
extern bool validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
10211021
uint32 checksum_version, uint32 backup_version, HeaderMap *hdr_map);
10221022

1023-
extern BackupPageHeader2* get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version);
1023+
extern BackupPageHeader2* get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict);
10241024
extern void write_page_headers(BackupPageHeader2 *headers, pgFile *file, HeaderMap *hdr_map, bool is_merge);
10251025
extern void init_header_map(pgBackup *backup);
10261026
extern void cleanup_header_map(HeaderMap *hdr_map);

src/restore.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ restore_files(void *arg)
11441144
/* Restore destination file */
11451145
if (dest_file->is_datafile && !dest_file->is_cfs)
11461146
{
1147-
/* enable stdio buffering for local destination non-data file */
1147+
/* enable stdio buffering for local destination data file */
11481148
if (!fio_is_remote_file(out))
11491149
setvbuf(out, out_buf, _IOFBF, STDIO_BUFSIZE);
11501150
/* Destination file is data file */
@@ -1155,7 +1155,7 @@ restore_files(void *arg)
11551155
}
11561156
else
11571157
{
1158-
/* disable stdio buffering for local destination data file */
1158+
/* disable stdio buffering for local destination nonedata file */
11591159
if (!fio_is_remote_file(out))
11601160
setvbuf(out, NULL, _IONBF, BUFSIZ);
11611161
/* Destination file is non-data file */

0 commit comments

Comments
 (0)