Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit57b5a96

Browse files
committed
Minimal fix for unterminated tar archive problem.
Commit23a1c65 improvedpg_basebackup's ability to parse tar archives, but also arrangedto parse them only when we need to make some modification to thecontents of the archive. That's a problem, because the serverdoesn't actually terminate tar archives. When the new parsinglogic was engaged, pg_basebackup would properly terminate thetar file, but when it was skipped, pg_basebackup would just writewhatever it got from the server, meaning that the terminatorwas missing.Most versions of tar are willing to overlook the missing terminator, butthe AIX buildfarm animals were not. Fix by inventing a new kind ofbbstreamer that just blindly adds a terminator, and using it whenever wedon't parse the tar archive.Discussion:http://postgr.es/m/CA+TgmoZbNzsWwM4BE5Jb_qHncY817DYZwGf+2-7hkMQ27ZwsMQ@mail.gmail.com
1 parentb0cf544 commit57b5a96

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

‎src/bin/pg_basebackup/bbstreamer.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ extern bbstreamer *bbstreamer_extractor_new(const char *basepath,
206206
void (*report_output_file) (constchar*));
207207

208208
externbbstreamer*bbstreamer_tar_parser_new(bbstreamer*next);
209+
externbbstreamer*bbstreamer_tar_terminator_new(bbstreamer*next);
209210
externbbstreamer*bbstreamer_tar_archiver_new(bbstreamer*next);
210211

211212
externbbstreamer*bbstreamer_recovery_injector_new(bbstreamer*next,

‎src/bin/pg_basebackup/bbstreamer_tar.c‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ const bbstreamer_ops bbstreamer_tar_archiver_ops = {
5959
.free=bbstreamer_tar_archiver_free
6060
};
6161

62+
staticvoidbbstreamer_tar_terminator_content(bbstreamer*streamer,
63+
bbstreamer_member*member,
64+
constchar*data,intlen,
65+
bbstreamer_archive_contextcontext);
66+
staticvoidbbstreamer_tar_terminator_finalize(bbstreamer*streamer);
67+
staticvoidbbstreamer_tar_terminator_free(bbstreamer*streamer);
68+
69+
constbbstreamer_opsbbstreamer_tar_terminator_ops= {
70+
.content=bbstreamer_tar_terminator_content,
71+
.finalize=bbstreamer_tar_terminator_finalize,
72+
.free=bbstreamer_tar_terminator_free
73+
};
74+
6275
/*
6376
* Create a bbstreamer that can parse a stream of content as tar data.
6477
*
@@ -442,3 +455,62 @@ bbstreamer_tar_archiver_free(bbstreamer *streamer)
442455
bbstreamer_free(streamer->bbs_next);
443456
pfree(streamer);
444457
}
458+
459+
/*
460+
* Create a bbstreamer that blindly adds two blocks of NUL bytes to the
461+
* end of an incomplete tarfile that the server might send us.
462+
*/
463+
bbstreamer*
464+
bbstreamer_tar_terminator_new(bbstreamer*next)
465+
{
466+
bbstreamer*streamer;
467+
468+
streamer=palloc0(sizeof(bbstreamer));
469+
*((constbbstreamer_ops**)&streamer->bbs_ops)=
470+
&bbstreamer_tar_terminator_ops;
471+
streamer->bbs_next=next;
472+
473+
returnstreamer;
474+
}
475+
476+
/*
477+
* Pass all the content through without change.
478+
*/
479+
staticvoid
480+
bbstreamer_tar_terminator_content(bbstreamer*streamer,
481+
bbstreamer_member*member,
482+
constchar*data,intlen,
483+
bbstreamer_archive_contextcontext)
484+
{
485+
/* Expect unparsed input. */
486+
Assert(member==NULL);
487+
Assert(context==BBSTREAMER_UNKNOWN);
488+
489+
/* Just forward it. */
490+
bbstreamer_content(streamer->bbs_next,member,data,len,context);
491+
}
492+
493+
/*
494+
* At the end, blindly add the two blocks of NUL bytes which the server fails
495+
* to supply.
496+
*/
497+
staticvoid
498+
bbstreamer_tar_terminator_finalize(bbstreamer*streamer)
499+
{
500+
charbuffer[2*TAR_BLOCK_SIZE];
501+
502+
memset(buffer,0,2*TAR_BLOCK_SIZE);
503+
bbstreamer_content(streamer->bbs_next,NULL,buffer,
504+
2*TAR_BLOCK_SIZE,BBSTREAMER_UNKNOWN);
505+
bbstreamer_finalize(streamer->bbs_next);
506+
}
507+
508+
/*
509+
* Free memory associated with a tar terminator.
510+
*/
511+
staticvoid
512+
bbstreamer_tar_terminator_free(bbstreamer*streamer)
513+
{
514+
bbstreamer_free(streamer->bbs_next);
515+
pfree(streamer);
516+
}

‎src/bin/pg_basebackup/pg_basebackup.c‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,10 +1073,14 @@ CreateBackupStreamer(char *archive_name, char *spclocation,
10731073

10741074
/*
10751075
* If we're doing anything that involves understanding the contents of
1076-
* the archive, we'll need to parse it.
1076+
* the archive, we'll need to parse it. If not, we can skip parsing it,
1077+
* but the tar files the server sends are not properly terminated, so
1078+
* we'll need to add the terminator here.
10771079
*/
10781080
if (must_parse_archive)
10791081
streamer=bbstreamer_tar_parser_new(streamer);
1082+
else
1083+
streamer=bbstreamer_tar_terminator_new(streamer);
10801084

10811085
/* Return the results. */
10821086
*manifest_inject_streamer_p=manifest_inject_streamer;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp