Make sure the pg_dump tar archiver can handle members larger than 2 GB, but
does not create members larger than allowed by the tar format. Also, fix the generation of the tar header to conform to POSIX.
This commit is contained in:
parent
172f9a49e0
commit
38e444aae6
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.49 2002/08/27 18:57:26 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.50 2002/09/06 21:58:36 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -662,6 +662,15 @@ CREATE DATABASE foo WITH TEMPLATE = template0;
|
|||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Members of tar archives are limited to a size less than 8 GB.
|
||||||
|
(This is an inherent limitation of the tar file format.) Therefore
|
||||||
|
this format cannot be used if the textual representation of a table
|
||||||
|
exceeds that size. The total size of a tar archive and any of the
|
||||||
|
other output formats is not limited, except possibly by the
|
||||||
|
operating system.
|
||||||
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1 id="pg-dump-examples">
|
<refsect1 id="pg-dump-examples">
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.28 2002/09/04 20:31:34 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.29 2002/09/06 21:58:36 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -73,6 +73,17 @@ typedef struct
|
|||||||
ArchiveHandle *AH;
|
ArchiveHandle *AH;
|
||||||
} TAR_MEMBER;
|
} TAR_MEMBER;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum file size for a tar member: The limit inherent in the
|
||||||
|
* format is 2^33-1 bytes (nearly 8 GB). But we don't want to exceed
|
||||||
|
* what we can represent by an off_t.
|
||||||
|
*/
|
||||||
|
#ifdef INT64_IS_BUSTED
|
||||||
|
#define MAX_TAR_MEMBER_FILELEN INT_MAX
|
||||||
|
#else
|
||||||
|
#define MAX_TAR_MEMBER_FILELEN (((int64) 1 << Min(33, sizeof(off_t)*8 - 1)) - 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int hasSeek;
|
int hasSeek;
|
||||||
@ -1006,6 +1017,8 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
|
|||||||
*/
|
*/
|
||||||
fseeko(tmp, 0, SEEK_END);
|
fseeko(tmp, 0, SEEK_END);
|
||||||
th->fileLen = ftello(tmp);
|
th->fileLen = ftello(tmp);
|
||||||
|
if (th->fileLen > MAX_TAR_MEMBER_FILELEN)
|
||||||
|
die_horribly(AH, modulename, "archive member too large for tar format\n");
|
||||||
fseeko(tmp, 0, SEEK_SET);
|
fseeko(tmp, 0, SEEK_SET);
|
||||||
|
|
||||||
_tarWriteHeader(th);
|
_tarWriteHeader(th);
|
||||||
@ -1219,6 +1232,23 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility routine to print possibly larger than 32 bit integers in a
|
||||||
|
* portable fashion. Filled with zeros.
|
||||||
|
*/
|
||||||
|
static void print_val(char *s, uint64 val, unsigned int base, size_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = len; i > 0; i--)
|
||||||
|
{
|
||||||
|
int digit = val % base;
|
||||||
|
s[i - 1] = '0' + digit;
|
||||||
|
val = val / base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_tarWriteHeader(TAR_MEMBER *th)
|
_tarWriteHeader(TAR_MEMBER *th)
|
||||||
{
|
{
|
||||||
@ -1235,34 +1265,30 @@ _tarWriteHeader(TAR_MEMBER *th)
|
|||||||
sprintf(&h[100], "100600 ");
|
sprintf(&h[100], "100600 ");
|
||||||
|
|
||||||
/* User ID 8 */
|
/* User ID 8 */
|
||||||
sprintf(&h[108], " 04000 ");
|
sprintf(&h[108], "004000 ");
|
||||||
|
|
||||||
/* Group 8 */
|
/* Group 8 */
|
||||||
sprintf(&h[116], " 02000 ");
|
sprintf(&h[116], "002000 ");
|
||||||
|
|
||||||
/* File size 12 */
|
/* File size 12 - 11 digits, 1 space, no NUL */
|
||||||
/* FIXME: This goes only up to 2^30. -- What about larger files? */
|
print_val(&h[124], th->fileLen, 8, 11);
|
||||||
sprintf(&h[124], "%10o ", (unsigned int) th->fileLen);
|
sprintf(&h[135], " ");
|
||||||
|
|
||||||
/* Mod Time 12 */
|
/* Mod Time 12 */
|
||||||
sprintf(&h[136], "%10o ", (int) time(NULL));
|
sprintf(&h[136], "%011o ", (int) time(NULL));
|
||||||
|
|
||||||
/* Checksum 8 */
|
/* Checksum 8 */
|
||||||
sprintf(&h[148], "%6o ", lastSum);
|
sprintf(&h[148], "%06o ", lastSum);
|
||||||
|
|
||||||
/* Type 1 */
|
/* Type - regular file */
|
||||||
/* sprintf(&h[156], "%c", LF_NORMAL); */
|
|
||||||
sprintf(&h[156], "0");
|
sprintf(&h[156], "0");
|
||||||
|
|
||||||
/* Link tag 100 (NULL) */
|
/* Link tag 100 (NULL) */
|
||||||
|
|
||||||
/* Magic 8 */
|
/* Magic 6 + Version 2 */
|
||||||
sprintf(&h[257], "ustar ");
|
sprintf(&h[257], "ustar00");
|
||||||
|
|
||||||
/*
|
|
||||||
* GNU Version... sprintf(&h[257], "ustar"); sprintf(&h[263], "00");
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* User 32 */
|
/* User 32 */
|
||||||
sprintf(&h[265], "%.31s", ""); /* How do I get username reliably?
|
sprintf(&h[265], "%.31s", ""); /* How do I get username reliably?
|
||||||
* Do I need to? */
|
* Do I need to? */
|
||||||
@ -1272,15 +1298,15 @@ _tarWriteHeader(TAR_MEMBER *th)
|
|||||||
* I need to? */
|
* I need to? */
|
||||||
|
|
||||||
/* Maj Dev 8 */
|
/* Maj Dev 8 */
|
||||||
/* sprintf(&h[329], "%6o ", 0); */
|
sprintf(&h[329], "%6o ", 0);
|
||||||
|
|
||||||
/* Min Dev */
|
|
||||||
/* sprintf(&h[337], "%6o ", 0); */
|
|
||||||
|
|
||||||
|
/* Min Dev 8 */
|
||||||
|
sprintf(&h[337], "%6o ", 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
while ((sum = _tarChecksum(h)) != lastSum)
|
while ((sum = _tarChecksum(h)) != lastSum)
|
||||||
{
|
{
|
||||||
sprintf(&h[148], "%6o ", sum);
|
sprintf(&h[148], "%06o ", sum);
|
||||||
lastSum = sum;
|
lastSum = sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user