#include "postgres_fe.h"
#include <time.h>
#include "pg_backup.h"
#include "libpq-fe.h"
#include "pqexpbuffer.h"
Go to the source code of this file.
Data Structures | |
struct | _z_stream |
struct | sqlparseInfo |
struct | _archiveHandle |
struct | _tocEntry |
Defines | |
#define | LOBBUFSIZE 16384 |
#define | GZCLOSE(fh) fclose(fh) |
#define | GZWRITE(p, s, n, fh) (fwrite(p, s, n, fh) * (s)) |
#define | GZREAD(p, s, n, fh) fread(p, s, n, fh) |
#define | Z_DEFAULT_COMPRESSION (-1) |
#define | K_VERS_MAJOR 1 |
#define | K_VERS_MINOR 12 |
#define | K_VERS_REV 0 |
#define | BLK_DATA 1 |
#define | BLK_BLOBS 3 |
#define | K_VERS_1_0 (( (1 * 256 + 0) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_2 (( (1 * 256 + 2) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_3 (( (1 * 256 + 3) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_4 (( (1 * 256 + 4) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_5 (( (1 * 256 + 5) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_6 (( (1 * 256 + 6) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_7 (( (1 * 256 + 7) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_8 (( (1 * 256 + 8) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_9 (( (1 * 256 + 9) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_10 (( (1 * 256 + 10) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_11 (( (1 * 256 + 11) * 256 + 0) * 256 + 0) |
#define | K_VERS_1_12 (( (1 * 256 + 12) * 256 + 0) * 256 + 0) |
#define | K_VERS_MAX (( (1 * 256 + 12) * 256 + 255) * 256 + 0) |
#define | K_OFFSET_POS_NOT_SET 1 |
#define | K_OFFSET_POS_SET 2 |
#define | K_OFFSET_NO_DATA 3 |
#define | WORKER_OK 0 |
#define | WORKER_CREATE_DONE 10 |
#define | WORKER_INHIBIT_DATA 11 |
#define | WORKER_IGNORED_ERRORS 12 |
#define | appendStringLiteralAHX(buf, str, AH) appendStringLiteral(buf, str, (AH)->public.encoding, (AH)->public.std_strings) |
#define | appendByteaLiteralAHX(buf, str, len, AH) appendByteaLiteral(buf, str, len, (AH)->public.std_strings) |
Typedefs | |
typedef struct _z_stream | z_stream |
typedef z_stream * | z_streamp |
typedef enum T_Action | T_Action |
typedef void(* | ClosePtr )(struct _archiveHandle *AH) |
typedef void(* | ReopenPtr )(struct _archiveHandle *AH) |
typedef void(* | ArchiveEntryPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef void(* | StartDataPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef size_t(* | WriteDataPtr )(struct _archiveHandle *AH, const void *data, size_t dLen) |
typedef void(* | EndDataPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef void(* | StartBlobsPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef void(* | StartBlobPtr )(struct _archiveHandle *AH, struct _tocEntry *te, Oid oid) |
typedef void(* | EndBlobPtr )(struct _archiveHandle *AH, struct _tocEntry *te, Oid oid) |
typedef void(* | EndBlobsPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef int(* | WriteBytePtr )(struct _archiveHandle *AH, const int i) |
typedef int(* | ReadBytePtr )(struct _archiveHandle *AH) |
typedef size_t(* | WriteBufPtr )(struct _archiveHandle *AH, const void *c, size_t len) |
typedef size_t(* | ReadBufPtr )(struct _archiveHandle *AH, void *buf, size_t len) |
typedef void(* | SaveArchivePtr )(struct _archiveHandle *AH) |
typedef void(* | WriteExtraTocPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef void(* | ReadExtraTocPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef void(* | PrintExtraTocPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef void(* | PrintTocDataPtr )(struct _archiveHandle *AH, struct _tocEntry *te, RestoreOptions *ropt) |
typedef void(* | ClonePtr )(struct _archiveHandle *AH) |
typedef void(* | DeClonePtr )(struct _archiveHandle *AH) |
typedef char *(* | WorkerJobRestorePtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef char *(* | WorkerJobDumpPtr )(struct _archiveHandle *AH, struct _tocEntry *te) |
typedef char *(* | MasterStartParallelItemPtr )(struct _archiveHandle *AH, struct _tocEntry *te, T_Action act) |
typedef int(* | MasterEndParallelItemPtr )(struct _archiveHandle *AH, struct _tocEntry *te, const char *str, T_Action act) |
typedef size_t(* | CustomOutPtr )(struct _archiveHandle *AH, const void *buf, size_t len) |
typedef struct _archiveHandle | ArchiveHandle |
typedef struct _tocEntry | TocEntry |
Enumerations | |
enum | T_Action { ACT_DUMP, ACT_RESTORE } |
enum | sqlparseState { SQL_SCAN = 0, SQL_IN_SINGLE_QUOTE, SQL_IN_DOUBLE_QUOTE } |
enum | ArchiverStage { STAGE_NONE = 0, STAGE_INITIALIZING, STAGE_PROCESSING, STAGE_FINALIZING } |
enum | ArchiverOutput { OUTPUT_SQLCMDS = 0, OUTPUT_COPYDATA, OUTPUT_OTHERDATA } |
enum | teReqs { REQ_SCHEMA = 0x01, REQ_DATA = 0x02, REQ_SPECIAL = 0x04 } |
Functions | |
int | parallel_restore (struct ParallelArgs *args) |
void | on_exit_close_archive (Archive *AHX) |
void | warn_or_exit_horribly (ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE |
void void | WriteTOC (ArchiveHandle *AH) |
void | ReadTOC (ArchiveHandle *AH) |
void | WriteHead (ArchiveHandle *AH) |
void | ReadHead (ArchiveHandle *AH) |
void | WriteToc (ArchiveHandle *AH) |
void | ReadToc (ArchiveHandle *AH) |
void | WriteDataChunks (ArchiveHandle *AH, struct ParallelState *pstate) |
void | WriteDataChunksForTocEntry (ArchiveHandle *AH, TocEntry *te) |
ArchiveHandle * | CloneArchive (ArchiveHandle *AH) |
void | DeCloneArchive (ArchiveHandle *AH) |
teReqs | TocIDRequired (ArchiveHandle *AH, DumpId id) |
TocEntry * | getTocEntryByDumpId (ArchiveHandle *AH, DumpId id) |
bool | checkSeek (FILE *fp) |
size_t | WriteInt (ArchiveHandle *AH, int i) |
int | ReadInt (ArchiveHandle *AH) |
char * | ReadStr (ArchiveHandle *AH) |
size_t | WriteStr (ArchiveHandle *AH, const char *s) |
int | ReadOffset (ArchiveHandle *, pgoff_t *) |
size_t | WriteOffset (ArchiveHandle *, pgoff_t, int) |
void | StartRestoreBlobs (ArchiveHandle *AH) |
void | StartRestoreBlob (ArchiveHandle *AH, Oid oid, bool drop) |
void | EndRestoreBlob (ArchiveHandle *AH, Oid oid) |
void | EndRestoreBlobs (ArchiveHandle *AH) |
void | InitArchiveFmt_Custom (ArchiveHandle *AH) |
void | InitArchiveFmt_Null (ArchiveHandle *AH) |
void | InitArchiveFmt_Directory (ArchiveHandle *AH) |
void | InitArchiveFmt_Tar (ArchiveHandle *AH) |
bool | isValidTarHeader (char *header) |
int | ReconnectToServer (ArchiveHandle *AH, const char *dbname, const char *newUser) |
void | DropBlobIfExists (ArchiveHandle *AH, Oid oid) |
int | ahwrite (const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH) |
int | ahprintf (ArchiveHandle *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE |
int void | ahlog (ArchiveHandle *AH, int level, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE |
#define appendByteaLiteralAHX | ( | buf, | ||
str, | ||||
len, | ||||
AH | ||||
) | appendByteaLiteral(buf, str, len, (AH)->public.std_strings) |
Definition at line 386 of file pg_backup_archiver.h.
Referenced by _WriteBlobData(), and dump_lo_buf().
#define appendStringLiteralAHX | ( | buf, | ||
str, | ||||
AH | ||||
) | appendStringLiteral(buf, str, (AH)->public.encoding, (AH)->public.std_strings) |
Definition at line 383 of file pg_backup_archiver.h.
Referenced by _doSetSessionAuth().
#define BLK_BLOBS 3 |
Definition at line 72 of file pg_backup_archiver.h.
Referenced by _PrintTocData(), and _StartBlobs().
#define BLK_DATA 1 |
Definition at line 71 of file pg_backup_archiver.h.
Referenced by _PrintTocData(), and _StartData().
#define GZCLOSE | ( | fh | ) | fclose(fh) |
Definition at line 49 of file pg_backup_archiver.h.
Referenced by CloseArchive(), RestoreOutput(), and tarClose().
#define GZREAD | ( | p, | ||
s, | ||||
n, | ||||
fh | ||||
) | fread(p, s, n, fh) |
Definition at line 51 of file pg_backup_archiver.h.
Referenced by _tarReadRaw().
#define GZWRITE | ( | p, | ||
s, | ||||
n, | ||||
fh | ||||
) | (fwrite(p, s, n, fh) * (s)) |
Definition at line 50 of file pg_backup_archiver.h.
Referenced by ahwrite(), and tarWrite().
#define K_OFFSET_NO_DATA 3 |
Definition at line 101 of file pg_backup_archiver.h.
Referenced by _PrintTocData(), and ReadOffset().
#define K_OFFSET_POS_NOT_SET 1 |
Definition at line 99 of file pg_backup_archiver.h.
Referenced by _PrintTocData(), and ReadOffset().
#define K_OFFSET_POS_SET 2 |
Definition at line 100 of file pg_backup_archiver.h.
Referenced by ReadOffset().
#define K_VERS_1_0 (( (1 * 256 + 0) * 256 + 0) * 256 + 0) |
Definition at line 75 of file pg_backup_archiver.h.
Referenced by ReadHead(), and ReadInt().
#define K_VERS_1_10 (( (1 * 256 + 10) * 256 + 0) * 256 + 0) |
Definition at line 88 of file pg_backup_archiver.h.
Referenced by ReadHead(), and ReadToc().
#define K_VERS_1_11 (( (1 * 256 + 11) * 256 + 0) * 256 + 0) |
Definition at line 89 of file pg_backup_archiver.h.
Referenced by fix_dependencies(), and ReadToc().
#define K_VERS_1_12 (( (1 * 256 + 12) * 256 + 0) * 256 + 0) |
Definition at line 91 of file pg_backup_archiver.h.
#define K_VERS_1_2 (( (1 * 256 + 2) * 256 + 0) * 256 + 0) |
Definition at line 76 of file pg_backup_archiver.h.
Referenced by ReadHead().
#define K_VERS_1_3 (( (1 * 256 + 3) * 256 + 0) * 256 + 0) |
Definition at line 77 of file pg_backup_archiver.h.
Referenced by _readBlockHeader(), ReadToc(), and RestoreArchive().
#define K_VERS_1_4 (( (1 * 256 + 4) * 256 + 0) * 256 + 0) |
Definition at line 78 of file pg_backup_archiver.h.
Referenced by ReadHead().
#define K_VERS_1_5 (( (1 * 256 + 5) * 256 + 0) * 256 + 0) |
Definition at line 79 of file pg_backup_archiver.h.
Referenced by ReadToc().
#define K_VERS_1_6 (( (1 * 256 + 6) * 256 + 0) * 256 + 0) |
Definition at line 80 of file pg_backup_archiver.h.
Referenced by ReadToc().
#define K_VERS_1_7 (( (1 * 256 + 7) * 256 + 0) * 256 + 0) |
Definition at line 81 of file pg_backup_archiver.h.
Referenced by _discoverArchiveFormat(), _getObjectDescription(), _ReadExtraToc(), ReadHead(), and ReadOffset().
#define K_VERS_1_8 (( (1 * 256 + 8) * 256 + 0) * 256 + 0) |
Definition at line 83 of file pg_backup_archiver.h.
Referenced by ReadToc(), and RestoreArchive().
#define K_VERS_1_9 (( (1 * 256 + 9) * 256 + 0) * 256 + 0) |
Definition at line 86 of file pg_backup_archiver.h.
Referenced by ReadToc().
#define K_VERS_MAJOR 1 |
Definition at line 66 of file pg_backup_archiver.h.
#define K_VERS_MAX (( (1 * 256 + 12) * 256 + 255) * 256 + 0) |
Definition at line 95 of file pg_backup_archiver.h.
Referenced by ReadHead().
#define K_VERS_MINOR 12 |
Definition at line 67 of file pg_backup_archiver.h.
#define K_VERS_REV 0 |
Definition at line 68 of file pg_backup_archiver.h.
#define LOBBUFSIZE 16384 |
Definition at line 37 of file pg_backup_archiver.h.
Referenced by dumpBlobs(), InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), InitArchiveFmt_Null(), and InitArchiveFmt_Tar().
#define WORKER_CREATE_DONE 10 |
Definition at line 108 of file pg_backup_archiver.h.
Referenced by mark_work_done().
#define WORKER_IGNORED_ERRORS 12 |
Definition at line 110 of file pg_backup_archiver.h.
Referenced by _WorkerJobRestoreCustom(), _WorkerJobRestoreDirectory(), and mark_work_done().
#define WORKER_INHIBIT_DATA 11 |
Definition at line 109 of file pg_backup_archiver.h.
Referenced by mark_work_done().
#define WORKER_OK 0 |
Definition at line 107 of file pg_backup_archiver.h.
Referenced by restore_toc_entry().
#define Z_DEFAULT_COMPRESSION (-1) |
Definition at line 53 of file pg_backup_archiver.h.
Referenced by InitArchiveFmt_Tar(), and ParseCompressionOption().
typedef void(* ArchiveEntryPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 126 of file pg_backup_archiver.h.
typedef struct _archiveHandle ArchiveHandle |
typedef void(* ClonePtr)(struct _archiveHandle *AH) |
Definition at line 147 of file pg_backup_archiver.h.
typedef void(* ClosePtr)(struct _archiveHandle *AH) |
Definition at line 124 of file pg_backup_archiver.h.
typedef size_t(* CustomOutPtr)(struct _archiveHandle *AH, const void *buf, size_t len) |
Definition at line 157 of file pg_backup_archiver.h.
typedef void(* DeClonePtr)(struct _archiveHandle *AH) |
Definition at line 148 of file pg_backup_archiver.h.
typedef void(* EndBlobPtr)(struct _archiveHandle *AH, struct _tocEntry *te, Oid oid) |
Definition at line 134 of file pg_backup_archiver.h.
typedef void(* EndBlobsPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 135 of file pg_backup_archiver.h.
typedef void(* EndDataPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 130 of file pg_backup_archiver.h.
typedef int(* MasterEndParallelItemPtr)(struct _archiveHandle *AH, struct _tocEntry *te, const char *str, T_Action act) |
Definition at line 154 of file pg_backup_archiver.h.
typedef char*(* MasterStartParallelItemPtr)(struct _archiveHandle *AH, struct _tocEntry *te, T_Action act) |
Definition at line 152 of file pg_backup_archiver.h.
typedef void(* PrintExtraTocPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 144 of file pg_backup_archiver.h.
typedef void(* PrintTocDataPtr)(struct _archiveHandle *AH, struct _tocEntry *te, RestoreOptions *ropt) |
Definition at line 145 of file pg_backup_archiver.h.
typedef size_t(* ReadBufPtr)(struct _archiveHandle *AH, void *buf, size_t len) |
Definition at line 140 of file pg_backup_archiver.h.
typedef int(* ReadBytePtr)(struct _archiveHandle *AH) |
Definition at line 138 of file pg_backup_archiver.h.
typedef void(* ReadExtraTocPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 143 of file pg_backup_archiver.h.
typedef void(* ReopenPtr)(struct _archiveHandle *AH) |
Definition at line 125 of file pg_backup_archiver.h.
typedef void(* SaveArchivePtr)(struct _archiveHandle *AH) |
Definition at line 141 of file pg_backup_archiver.h.
typedef void(* StartBlobPtr)(struct _archiveHandle *AH, struct _tocEntry *te, Oid oid) |
Definition at line 133 of file pg_backup_archiver.h.
typedef void(* StartBlobsPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 132 of file pg_backup_archiver.h.
typedef void(* StartDataPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 128 of file pg_backup_archiver.h.
typedef char*(* WorkerJobDumpPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 151 of file pg_backup_archiver.h.
typedef char*(* WorkerJobRestorePtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 150 of file pg_backup_archiver.h.
typedef size_t(* WriteBufPtr)(struct _archiveHandle *AH, const void *c, size_t len) |
Definition at line 139 of file pg_backup_archiver.h.
typedef int(* WriteBytePtr)(struct _archiveHandle *AH, const int i) |
Definition at line 137 of file pg_backup_archiver.h.
typedef size_t(* WriteDataPtr)(struct _archiveHandle *AH, const void *data, size_t dLen) |
Definition at line 129 of file pg_backup_archiver.h.
typedef void(* WriteExtraTocPtr)(struct _archiveHandle *AH, struct _tocEntry *te) |
Definition at line 142 of file pg_backup_archiver.h.
Definition at line 62 of file pg_backup_archiver.h.
enum ArchiverOutput |
Definition at line 181 of file pg_backup_archiver.h.
{ OUTPUT_SQLCMDS = 0, /* emitting general SQL commands */ OUTPUT_COPYDATA, /* writing COPY data */ OUTPUT_OTHERDATA /* writing data as INSERT commands */ } ArchiverOutput;
enum ArchiverStage |
Definition at line 173 of file pg_backup_archiver.h.
{ STAGE_NONE = 0, STAGE_INITIALIZING, STAGE_PROCESSING, STAGE_FINALIZING } ArchiverStage;
enum sqlparseState |
Definition at line 159 of file pg_backup_archiver.h.
{ SQL_SCAN = 0, /* normal */ SQL_IN_SINGLE_QUOTE, /* '...' literal */ SQL_IN_DOUBLE_QUOTE /* "..." identifier */ } sqlparseState;
enum T_Action |
Definition at line 118 of file pg_backup_archiver.h.
{ ACT_DUMP, ACT_RESTORE } T_Action;
enum teReqs |
Definition at line 188 of file pg_backup_archiver.h.
{ REQ_SCHEMA = 0x01, /* want schema */ REQ_DATA = 0x02, /* want data */ REQ_SPECIAL = 0x04 /* for special TOC entries */ } teReqs;
int void ahlog | ( | ArchiveHandle * | AH, | |
int | level, | |||
const char * | fmt, | |||
... | ||||
) |
int ahprintf | ( | ArchiveHandle * | AH, | |
const char * | fmt, | |||
... | ||||
) |
int ahwrite | ( | const void * | ptr, | |
size_t | size, | |||
size_t | nmemb, | |||
ArchiveHandle * | AH | |||
) |
Definition at line 1406 of file pg_backup_archiver.c.
References _archiveHandle::CustomOutPtr, dump_lo_buf(), ExecuteSqlCommandBuf(), exit_horribly(), _archiveHandle::gzOut, GZWRITE, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, _archiveHandle::lo_buf_used, modulename, _archiveHandle::OF, remaining, RestoringToDB(), strerror(), and _archiveHandle::writingBlob.
Referenced by _LoadBlobs(), _PrintFileData(), _PrintTocData(), _WriteData(), ahprintf(), and ReadDataFromArchiveNone().
{ size_t res; if (AH->writingBlob) { size_t remaining = size * nmemb; while (AH->lo_buf_used + remaining > AH->lo_buf_size) { size_t avail = AH->lo_buf_size - AH->lo_buf_used; memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail); ptr = (const void *) ((const char *) ptr + avail); remaining -= avail; AH->lo_buf_used += avail; dump_lo_buf(AH); } memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining); AH->lo_buf_used += remaining; return size * nmemb; } else if (AH->gzOut) { res = GZWRITE(ptr, size, nmemb, AH->OF); if (res != (nmemb * size)) exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno)); return res; } else if (AH->CustomOutPtr) { res = AH->CustomOutPtr (AH, ptr, size * nmemb); if (res != (nmemb * size)) exit_horribly(modulename, "could not write to custom output routine\n"); return res; } else { /* * If we're doing a restore, and it's direct to DB, and we're * connected then send it to the DB. */ if (RestoringToDB(AH)) return ExecuteSqlCommandBuf(AH, (const char *) ptr, size * nmemb); else { res = fwrite(ptr, size, nmemb, AH->OF); if (res != nmemb) exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno)); return res; } } }
bool checkSeek | ( | FILE * | fp | ) |
Definition at line 3329 of file pg_backup_archiver.c.
References fseeko, ftello, and pgoff_t.
Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().
{ pgoff_t tpos; /* * If pgoff_t is wider than long, we must have "real" fseeko and not an * emulation using fseek. Otherwise report no seek capability. */ #ifndef HAVE_FSEEKO if (sizeof(pgoff_t) > sizeof(long)) return false; #endif /* Check that ftello works on this file */ errno = 0; tpos = ftello(fp); if (errno) return false; /* * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a * successful no-op even on files that are otherwise unseekable. */ if (fseeko(fp, tpos, SEEK_SET) != 0) return false; return true; }
ArchiveHandle* CloneArchive | ( | ArchiveHandle * | AH | ) |
Definition at line 4154 of file pg_backup_archiver.c.
References archModeRead, Assert, _archiveHandle::ClonePtr, ConnectDatabase(), _archiveHandle::connection, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::currWithOids, _restoreOptions::dbname, Archive::encoding, _archiveHandle::mode, Archive::n_errors, NULL, pg_encoding_to_char(), pg_malloc(), pg_strdup(), pghost, _restoreOptions::pghost, pgport, _restoreOptions::pgport, PQdb(), PQhost(), PQport(), PQsetClientEncoding(), PQuser(), _restoreOptions::promptPassword, _archiveHandle::public, _archiveHandle::ropt, _archiveHandle::savedPassword, _archiveHandle::sqlparse, TRI_NO, username, and _restoreOptions::username.
Referenced by ParallelBackupStart().
{ ArchiveHandle *clone; /* Make a "flat" copy */ clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle)); memcpy(clone, AH, sizeof(ArchiveHandle)); /* Handle format-independent fields */ memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse)); /* The clone will have its own connection, so disregard connection state */ clone->connection = NULL; clone->currUser = NULL; clone->currSchema = NULL; clone->currTablespace = NULL; clone->currWithOids = -1; /* savedPassword must be local in case we change it while connecting */ if (clone->savedPassword) clone->savedPassword = pg_strdup(clone->savedPassword); /* clone has its own error count, too */ clone->public.n_errors = 0; /* * Connect our new clone object to the database: In parallel restore the * parent is already disconnected, because we can connect the worker * processes independently to the database (no snapshot sync required). In * parallel backup we clone the parent's existing connection. */ if (AH->mode == archModeRead) { RestoreOptions *ropt = AH->ropt; Assert(AH->connection == NULL); /* this also sets clone->connection */ ConnectDatabase((Archive *) clone, ropt->dbname, ropt->pghost, ropt->pgport, ropt->username, ropt->promptPassword); } else { char *dbname; char *pghost; char *pgport; char *username; const char *encname; Assert(AH->connection != NULL); /* * Even though we are technically accessing the parent's database * object here, these functions are fine to be called like that * because all just return a pointer and do not actually send/receive * any data to/from the database. */ dbname = PQdb(AH->connection); pghost = PQhost(AH->connection); pgport = PQport(AH->connection); username = PQuser(AH->connection); encname = pg_encoding_to_char(AH->public.encoding); /* this also sets clone->connection */ ConnectDatabase((Archive *) clone, dbname, pghost, pgport, username, TRI_NO); /* * Set the same encoding, whatever we set here is what we got from * pg_encoding_to_char(), so we really shouldn't run into an error * setting that very same value. Also see the comment in * SetupConnection(). */ PQsetClientEncoding(clone->connection, encname); } /* Let the format-specific code have a chance too */ (clone->ClonePtr) (clone); Assert(clone->connection != NULL); return clone; }
void DeCloneArchive | ( | ArchiveHandle * | AH | ) |
Definition at line 4242 of file pg_backup_archiver.c.
References sqlparseInfo::curCmd, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::DeClonePtr, destroyPQExpBuffer(), free, _archiveHandle::savedPassword, and _archiveHandle::sqlparse.
{ /* Clear format-specific state */ (AH->DeClonePtr) (AH); /* Clear state allocated by CloneArchive */ if (AH->sqlparse.curCmd) destroyPQExpBuffer(AH->sqlparse.curCmd); /* Clear any connection-local state */ if (AH->currUser) free(AH->currUser); if (AH->currSchema) free(AH->currSchema); if (AH->currTablespace) free(AH->currTablespace); if (AH->savedPassword) free(AH->savedPassword); free(AH); }
void DropBlobIfExists | ( | ArchiveHandle * | AH, | |
Oid | oid | |||
) |
Definition at line 584 of file pg_backup_db.c.
References ahprintf(), _archiveHandle::connection, NULL, and PQserverVersion().
Referenced by _StartBlob(), and StartRestoreBlob().
{ /* * If we are not restoring to a direct database connection, we have to * guess about how to detect whether the blob exists. Assume new-style. */ if (AH->connection == NULL || PQserverVersion(AH->connection) >= 90000) { ahprintf(AH, "SELECT pg_catalog.lo_unlink(oid) " "FROM pg_catalog.pg_largeobject_metadata " "WHERE oid = '%u';\n", oid); } else { /* Restoring to pre-9.0 server, so do it the old way */ ahprintf(AH, "SELECT CASE WHEN EXISTS(" "SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u'" ") THEN pg_catalog.lo_unlink('%u') END;\n", oid, oid); } }
void EndRestoreBlob | ( | ArchiveHandle * | AH, | |
Oid | oid | |||
) |
Definition at line 1054 of file pg_backup_archiver.c.
References ahprintf(), _archiveHandle::connection, dump_lo_buf(), _archiveHandle::lo_buf_used, lo_close(), _archiveHandle::loFd, and _archiveHandle::writingBlob.
Referenced by _LoadBlobs().
{ if (AH->lo_buf_used > 0) { /* Write remaining bytes from the LO buffer */ dump_lo_buf(AH); } AH->writingBlob = 0; if (AH->connection) { lo_close(AH->connection, AH->loFd); AH->loFd = -1; } else { ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n"); } }
void EndRestoreBlobs | ( | ArchiveHandle * | AH | ) |
Definition at line 989 of file pg_backup_archiver.c.
References ahlog(), ahprintf(), _archiveHandle::blobCount, CommitTransaction(), _archiveHandle::connection, ngettext, _archiveHandle::ropt, and _restoreOptions::single_txn.
Referenced by _LoadBlobs().
{ if (!AH->ropt->single_txn) { if (AH->connection) CommitTransaction(AH); else ahprintf(AH, "COMMIT;\n\n"); } ahlog(AH, 1, ngettext("restored %d large object\n", "restored %d large objects\n", AH->blobCount), AH->blobCount); }
TocEntry* getTocEntryByDumpId | ( | ArchiveHandle * | AH, | |
DumpId | id | |||
) |
Definition at line 1597 of file pg_backup_archiver.c.
References buildTocEntryArrays(), NULL, and _archiveHandle::tocsByDumpId.
Referenced by SortTocFromFile(), TocIDRequired(), and WaitForCommands().
{ /* build index arrays if we didn't already */ if (AH->tocsByDumpId == NULL) buildTocEntryArrays(AH); if (id > 0 && id <= AH->maxDumpId) return AH->tocsByDumpId[id]; return NULL; }
void InitArchiveFmt_Custom | ( | ArchiveHandle * | AH | ) |
Definition at line 108 of file pg_backup_custom.c.
References _getFilePos(), _archiveHandle::ArchiveEntryPtr, archModeWrite, checkSeek(), _archiveHandle::ClonePtr, _archiveHandle::ClosePtr, lclContext::dataStart, _archiveHandle::DeClonePtr, _archiveHandle::EndBlobPtr, _archiveHandle::EndBlobsPtr, _archiveHandle::EndDataPtr, exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, _archiveHandle::fSpec, lclContext::hasSeek, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, _archiveHandle::MasterEndParallelItemPtr, _archiveHandle::MasterStartParallelItemPtr, _archiveHandle::mode, modulename, PG_BINARY_R, PG_BINARY_W, pg_malloc(), pg_malloc0(), _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, _archiveHandle::StartBlobPtr, _archiveHandle::StartBlobsPtr, _archiveHandle::StartDataPtr, strerror(), _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.
Referenced by _allocAH().
{ lclContext *ctx; /* Assuming static functions, this can be copied for each format. */ AH->ArchiveEntryPtr = _ArchiveEntry; AH->StartDataPtr = _StartData; AH->WriteDataPtr = _WriteData; AH->EndDataPtr = _EndData; AH->WriteBytePtr = _WriteByte; AH->ReadBytePtr = _ReadByte; AH->WriteBufPtr = _WriteBuf; AH->ReadBufPtr = _ReadBuf; AH->ClosePtr = _CloseArchive; AH->ReopenPtr = _ReopenArchive; AH->PrintTocDataPtr = _PrintTocData; AH->ReadExtraTocPtr = _ReadExtraToc; AH->WriteExtraTocPtr = _WriteExtraToc; AH->PrintExtraTocPtr = _PrintExtraToc; AH->StartBlobsPtr = _StartBlobs; AH->StartBlobPtr = _StartBlob; AH->EndBlobPtr = _EndBlob; AH->EndBlobsPtr = _EndBlobs; AH->ClonePtr = _Clone; AH->DeClonePtr = _DeClone; AH->MasterStartParallelItemPtr = _MasterStartParallelItem; AH->MasterEndParallelItemPtr = _MasterEndParallelItem; /* no parallel dump in the custom archive, only parallel restore */ AH->WorkerJobDumpPtr = NULL; AH->WorkerJobRestorePtr = _WorkerJobRestoreCustom; /* Set up a private area. */ ctx = (lclContext *) pg_malloc0(sizeof(lclContext)); AH->formatData = (void *) ctx; /* Initialize LO buffering */ AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE); ctx->filePos = 0; /* * Now open the file */ if (AH->mode == archModeWrite) { if (AH->fSpec && strcmp(AH->fSpec, "") != 0) { AH->FH = fopen(AH->fSpec, PG_BINARY_W); if (!AH->FH) exit_horribly(modulename, "could not open output file \"%s\": %s\n", AH->fSpec, strerror(errno)); } else { AH->FH = stdout; if (!AH->FH) exit_horribly(modulename, "could not open output file: %s\n", strerror(errno)); } ctx->hasSeek = checkSeek(AH->FH); } else { if (AH->fSpec && strcmp(AH->fSpec, "") != 0) { AH->FH = fopen(AH->fSpec, PG_BINARY_R); if (!AH->FH) exit_horribly(modulename, "could not open input file \"%s\": %s\n", AH->fSpec, strerror(errno)); } else { AH->FH = stdin; if (!AH->FH) exit_horribly(modulename, "could not open input file: %s\n", strerror(errno)); } ctx->hasSeek = checkSeek(AH->FH); ReadHead(AH); ReadToc(AH); ctx->dataStart = _getFilePos(AH, ctx); } }
void InitArchiveFmt_Directory | ( | ArchiveHandle * | AH | ) |
Definition at line 111 of file pg_backup_directory.c.
References _archiveHandle::ArchiveEntryPtr, archModeWrite, lclContext::blobsTocFH, cfclose(), cfopen_read(), _archiveHandle::ClonePtr, closedir(), _archiveHandle::ClosePtr, dirent::d_name, lclContext::dataFH, _archiveHandle::DeClonePtr, lclContext::directory, _archiveHandle::EndBlobPtr, _archiveHandle::EndBlobsPtr, _archiveHandle::EndDataPtr, exit_horribly(), _archiveHandle::format, _archiveHandle::formatData, _archiveHandle::fSpec, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, _archiveHandle::MasterEndParallelItemPtr, _archiveHandle::MasterStartParallelItemPtr, mkdir, _archiveHandle::mode, modulename, NULL, opendir(), PG_BINARY_R, pg_malloc(), pg_malloc0(), _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, readdir(), _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, setFilePath(), _archiveHandle::StartBlobPtr, _archiveHandle::StartBlobsPtr, _archiveHandle::StartDataPtr, strerror(), _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.
Referenced by _allocAH().
{ lclContext *ctx; /* Assuming static functions, this can be copied for each format. */ AH->ArchiveEntryPtr = _ArchiveEntry; AH->StartDataPtr = _StartData; AH->WriteDataPtr = _WriteData; AH->EndDataPtr = _EndData; AH->WriteBytePtr = _WriteByte; AH->ReadBytePtr = _ReadByte; AH->WriteBufPtr = _WriteBuf; AH->ReadBufPtr = _ReadBuf; AH->ClosePtr = _CloseArchive; AH->ReopenPtr = _ReopenArchive; AH->PrintTocDataPtr = _PrintTocData; AH->ReadExtraTocPtr = _ReadExtraToc; AH->WriteExtraTocPtr = _WriteExtraToc; AH->PrintExtraTocPtr = _PrintExtraToc; AH->StartBlobsPtr = _StartBlobs; AH->StartBlobPtr = _StartBlob; AH->EndBlobPtr = _EndBlob; AH->EndBlobsPtr = _EndBlobs; AH->ClonePtr = _Clone; AH->DeClonePtr = _DeClone; AH->WorkerJobRestorePtr = _WorkerJobRestoreDirectory; AH->WorkerJobDumpPtr = _WorkerJobDumpDirectory; AH->MasterStartParallelItemPtr = _MasterStartParallelItem; AH->MasterEndParallelItemPtr = _MasterEndParallelItem; /* Set up our private context */ ctx = (lclContext *) pg_malloc0(sizeof(lclContext)); AH->formatData = (void *) ctx; ctx->dataFH = NULL; ctx->blobsTocFH = NULL; /* Initialize LO buffering */ AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE); /* * Now open the TOC file */ if (!AH->fSpec || strcmp(AH->fSpec, "") == 0) exit_horribly(modulename, "no output directory specified\n"); ctx->directory = AH->fSpec; if (AH->mode == archModeWrite) { struct stat st; bool is_empty = false; /* we accept an empty existing directory */ if (stat(ctx->directory, &st) == 0 && S_ISDIR(st.st_mode)) { DIR *dir = opendir(ctx->directory); if (dir) { struct dirent *d; is_empty = true; while ((d = readdir(dir))) { if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) { is_empty = false; break; } } closedir(dir); } } if (!is_empty && mkdir(ctx->directory, 0700) < 0) exit_horribly(modulename, "could not create directory \"%s\": %s\n", ctx->directory, strerror(errno)); } else { /* Read Mode */ char fname[MAXPGPATH]; cfp *tocFH; setFilePath(AH, fname, "toc.dat"); tocFH = cfopen_read(fname, PG_BINARY_R); if (tocFH == NULL) exit_horribly(modulename, "could not open input file \"%s\": %s\n", fname, strerror(errno)); ctx->dataFH = tocFH; /* * The TOC of a directory format dump shares the format code of the * tar format. */ AH->format = archTar; ReadHead(AH); AH->format = archDirectory; ReadToc(AH); /* Nothing else in the file, so close it again... */ if (cfclose(tocFH) != 0) exit_horribly(modulename, "could not close TOC file: %s\n", strerror(errno)); ctx->dataFH = NULL; } }
void InitArchiveFmt_Null | ( | ArchiveHandle * | AH | ) |
Definition at line 51 of file pg_backup_null.c.
References archModeRead, _archiveHandle::ClonePtr, _archiveHandle::ClosePtr, _archiveHandle::DeClonePtr, _archiveHandle::EndBlobPtr, _archiveHandle::EndBlobsPtr, _archiveHandle::EndDataPtr, exit_horribly(), _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, _archiveHandle::mode, NULL, pg_malloc(), _archiveHandle::PrintTocDataPtr, _archiveHandle::ReopenPtr, _archiveHandle::StartBlobPtr, _archiveHandle::StartBlobsPtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, and _archiveHandle::WriteDataPtr.
Referenced by _allocAH().
{ /* Assuming static functions, this can be copied for each format. */ AH->WriteDataPtr = _WriteData; AH->EndDataPtr = _EndData; AH->WriteBytePtr = _WriteByte; AH->WriteBufPtr = _WriteBuf; AH->ClosePtr = _CloseArchive; AH->ReopenPtr = NULL; AH->PrintTocDataPtr = _PrintTocData; AH->StartBlobsPtr = _StartBlobs; AH->StartBlobPtr = _StartBlob; AH->EndBlobPtr = _EndBlob; AH->EndBlobsPtr = _EndBlobs; AH->ClonePtr = NULL; AH->DeClonePtr = NULL; /* Initialize LO buffering */ AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE); /* * Now prevent reading... */ if (AH->mode == archModeRead) exit_horribly(NULL, "this format cannot be read\n"); }
void InitArchiveFmt_Tar | ( | ArchiveHandle * | AH | ) |
Definition at line 135 of file pg_backup_tar.c.
References archModeWrite, checkSeek(), exit_horribly(), lclContext::FH, lclContext::filePos, lclContext::hasSeek, lclContext::isSpecialScript, LOBBUFSIZE, modulename, NULL, PG_BINARY_R, PG_BINARY_W, pg_malloc(), pg_malloc0(), ReadHead(), ReadToc(), strerror(), tarClose(), lclContext::tarFH, lclContext::tarFHpos, tarOpen(), and Z_DEFAULT_COMPRESSION.
Referenced by _allocAH().
{ lclContext *ctx; /* Assuming static functions, this can be copied for each format. */ AH->ArchiveEntryPtr = _ArchiveEntry; AH->StartDataPtr = _StartData; AH->WriteDataPtr = _WriteData; AH->EndDataPtr = _EndData; AH->WriteBytePtr = _WriteByte; AH->ReadBytePtr = _ReadByte; AH->WriteBufPtr = _WriteBuf; AH->ReadBufPtr = _ReadBuf; AH->ClosePtr = _CloseArchive; AH->ReopenPtr = NULL; AH->PrintTocDataPtr = _PrintTocData; AH->ReadExtraTocPtr = _ReadExtraToc; AH->WriteExtraTocPtr = _WriteExtraToc; AH->PrintExtraTocPtr = _PrintExtraToc; AH->StartBlobsPtr = _StartBlobs; AH->StartBlobPtr = _StartBlob; AH->EndBlobPtr = _EndBlob; AH->EndBlobsPtr = _EndBlobs; AH->ClonePtr = NULL; AH->DeClonePtr = NULL; AH->MasterStartParallelItemPtr = NULL; AH->MasterEndParallelItemPtr = NULL; AH->WorkerJobDumpPtr = NULL; AH->WorkerJobRestorePtr = NULL; /* * Set up some special context used in compressing data. */ ctx = (lclContext *) pg_malloc0(sizeof(lclContext)); AH->formatData = (void *) ctx; ctx->filePos = 0; ctx->isSpecialScript = 0; /* Initialize LO buffering */ AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE); /* * Now open the tar file, and load the TOC if we're in read mode. */ if (AH->mode == archModeWrite) { if (AH->fSpec && strcmp(AH->fSpec, "") != 0) { ctx->tarFH = fopen(AH->fSpec, PG_BINARY_W); if (ctx->tarFH == NULL) exit_horribly(modulename, "could not open TOC file \"%s\" for output: %s\n", AH->fSpec, strerror(errno)); } else { ctx->tarFH = stdout; if (ctx->tarFH == NULL) exit_horribly(modulename, "could not open TOC file for output: %s\n", strerror(errno)); } ctx->tarFHpos = 0; /* * Make unbuffered since we will dup() it, and the buffers screw each * other */ /* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */ ctx->hasSeek = checkSeek(ctx->tarFH); if (AH->compression < 0 || AH->compression > 9) AH->compression = Z_DEFAULT_COMPRESSION; /* Don't compress into tar files unless asked to do so */ if (AH->compression == Z_DEFAULT_COMPRESSION) AH->compression = 0; /* * We don't support compression because reading the files back is not * possible since gzdopen uses buffered IO which totally screws file * positioning. */ if (AH->compression != 0) exit_horribly(modulename, "compression is not supported by tar archive format\n"); } else { /* Read Mode */ if (AH->fSpec && strcmp(AH->fSpec, "") != 0) { ctx->tarFH = fopen(AH->fSpec, PG_BINARY_R); if (ctx->tarFH == NULL) exit_horribly(modulename, "could not open TOC file \"%s\" for input: %s\n", AH->fSpec, strerror(errno)); } else { ctx->tarFH = stdin; if (ctx->tarFH == NULL) exit_horribly(modulename, "could not open TOC file for input: %s\n", strerror(errno)); } /* * Make unbuffered since we will dup() it, and the buffers screw each * other */ /* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */ ctx->tarFHpos = 0; ctx->hasSeek = checkSeek(ctx->tarFH); /* * Forcibly unmark the header as read since we use the lookahead * buffer */ AH->readHeader = 0; ctx->FH = (void *) tarOpen(AH, "toc.dat", 'r'); ReadHead(AH); ReadToc(AH); tarClose(AH, ctx->FH); /* Nothing else in the file... */ } }
bool isValidTarHeader | ( | char * | header | ) |
Definition at line 1029 of file pg_backup_tar.c.
References memcmp(), and tarChecksum().
Referenced by _discoverArchiveFormat().
{ int sum; int chk = tarChecksum(header); sscanf(&header[148], "%8o", &sum); if (sum != chk) return false; /* POSIX tar format */ if (memcmp(&header[257], "ustar\0", 6) == 0 && memcmp(&header[263], "00", 2) == 0) return true; /* GNU tar format */ if (memcmp(&header[257], "ustar \0", 8) == 0) return true; /* not-quite-POSIX format written by pre-9.3 pg_dump */ if (memcmp(&header[257], "ustar00\0", 8) == 0) return true; return false; }
void on_exit_close_archive | ( | Archive * | AHX | ) |
Definition at line 281 of file parallel.c.
References ShutdownInformation::AHX, archive_close_connection(), and on_exit_nicely().
Referenced by main().
{ shutdown_info.AHX = AHX; on_exit_nicely(archive_close_connection, &shutdown_info); }
int parallel_restore | ( | struct ParallelArgs * | args | ) |
Definition at line 3815 of file pg_backup_archiver.c.
References _doSetFixedOutputState(), ParallelArgs::AH, Assert, _archiveHandle::connection, Archive::n_errors, NULL, _archiveHandle::public, restore_toc_entry(), _archiveHandle::ropt, and ParallelArgs::te.
Referenced by _WorkerJobRestoreCustom(), and _WorkerJobRestoreDirectory().
{ ArchiveHandle *AH = args->AH; TocEntry *te = args->te; RestoreOptions *ropt = AH->ropt; int status; _doSetFixedOutputState(AH); Assert(AH->connection != NULL); AH->public.n_errors = 0; /* Restore the TOC item */ status = restore_toc_entry(AH, te, ropt, true); return status; }
void ReadHead | ( | ArchiveHandle * | AH | ) |
Definition at line 3229 of file pg_backup_archiver.c.
References _archiveHandle::archdbname, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, _archiveHandle::compression, _archiveHandle::createDate, exit_horribly(), _archiveHandle::format, _archiveHandle::intSize, K_VERS_1_0, K_VERS_1_10, K_VERS_1_2, K_VERS_1_4, K_VERS_1_7, K_VERS_MAX, modulename, _archiveHandle::offSize, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::readHeader, ReadInt(), ReadStr(), tm, _archiveHandle::version, _archiveHandle::vmaj, _archiveHandle::vmin, _archiveHandle::vrev, and write_msg().
Referenced by InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), and InitArchiveFmt_Tar().
{ char tmpMag[7]; int fmt; struct tm crtm; /* * If we haven't already read the header, do so. * * NB: this code must agree with _discoverArchiveFormat(). Maybe find a * way to unify the cases? */ if (!AH->readHeader) { if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5) exit_horribly(modulename, "unexpected end of file\n"); if (strncmp(tmpMag, "PGDMP", 5) != 0) exit_horribly(modulename, "did not find magic string in file header\n"); AH->vmaj = (*AH->ReadBytePtr) (AH); AH->vmin = (*AH->ReadBytePtr) (AH); if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0))) /* Version > 1.0 */ AH->vrev = (*AH->ReadBytePtr) (AH); else AH->vrev = 0; AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0; if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) exit_horribly(modulename, "unsupported version (%d.%d) in file header\n", AH->vmaj, AH->vmin); AH->intSize = (*AH->ReadBytePtr) (AH); if (AH->intSize > 32) exit_horribly(modulename, "sanity check on integer size (%lu) failed\n", (unsigned long) AH->intSize); if (AH->intSize > sizeof(int)) write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n"); if (AH->version >= K_VERS_1_7) AH->offSize = (*AH->ReadBytePtr) (AH); else AH->offSize = AH->intSize; fmt = (*AH->ReadBytePtr) (AH); if (AH->format != fmt) exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n", AH->format, fmt); } if (AH->version >= K_VERS_1_2) { if (AH->version < K_VERS_1_4) AH->compression = (*AH->ReadBytePtr) (AH); else AH->compression = ReadInt(AH); } else AH->compression = Z_DEFAULT_COMPRESSION; #ifndef HAVE_LIBZ if (AH->compression != 0) write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n"); #endif if (AH->version >= K_VERS_1_4) { crtm.tm_sec = ReadInt(AH); crtm.tm_min = ReadInt(AH); crtm.tm_hour = ReadInt(AH); crtm.tm_mday = ReadInt(AH); crtm.tm_mon = ReadInt(AH); crtm.tm_year = ReadInt(AH); crtm.tm_isdst = ReadInt(AH); AH->archdbname = ReadStr(AH); AH->createDate = mktime(&crtm); if (AH->createDate == (time_t) -1) write_msg(modulename, "WARNING: invalid creation date in header\n"); } if (AH->version >= K_VERS_1_10) { AH->archiveRemoteVersion = ReadStr(AH); AH->archiveDumpVersion = ReadStr(AH); } }
int ReadInt | ( | ArchiveHandle * | AH | ) |
Definition at line 1733 of file pg_backup_archiver.c.
References _archiveHandle::intSize, K_VERS_1_0, _archiveHandle::ReadBytePtr, sign, and _archiveHandle::version.
Referenced by _CustomReadFunc(), _LoadBlobs(), _readBlockHeader(), _ReadExtraToc(), _skipBlobs(), _skipData(), ReadHead(), ReadOffset(), ReadStr(), and ReadToc().
{ int res = 0; int bv, b; int sign = 0; /* Default positive */ int bitShift = 0; if (AH->version > K_VERS_1_0) /* Read a sign byte */ sign = (*AH->ReadBytePtr) (AH); for (b = 0; b < AH->intSize; b++) { bv = (*AH->ReadBytePtr) (AH) & 0xFF; if (bv != 0) res = res + (bv << bitShift); bitShift += 8; } if (sign) res = -res; return res; }
int ReadOffset | ( | ArchiveHandle * | , | |
pgoff_t * | ||||
) |
Definition at line 1638 of file pg_backup_archiver.c.
References exit_horribly(), i, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, K_OFFSET_POS_SET, K_VERS_1_7, modulename, _archiveHandle::offSize, pgoff_t, _archiveHandle::ReadBytePtr, ReadInt(), and _archiveHandle::version.
Referenced by _ReadExtraToc().
{ int i; int off; int offsetFlg; /* Initialize to zero */ *o = 0; /* Check for old version */ if (AH->version < K_VERS_1_7) { /* Prior versions wrote offsets using WriteInt */ i = ReadInt(AH); /* -1 means not set */ if (i < 0) return K_OFFSET_POS_NOT_SET; else if (i == 0) return K_OFFSET_NO_DATA; /* Cast to pgoff_t because it was written as an int. */ *o = (pgoff_t) i; return K_OFFSET_POS_SET; } /* * Read the flag indicating the state of the data pointer. Check if valid * and die if not. * * This used to be handled by a negative or zero pointer, now we use an * extra byte specifically for the state. */ offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF; switch (offsetFlg) { case K_OFFSET_POS_NOT_SET: case K_OFFSET_NO_DATA: case K_OFFSET_POS_SET: break; default: exit_horribly(modulename, "unexpected data offset flag %d\n", offsetFlg); } /* * Read the bytes */ for (off = 0; off < AH->offSize; off++) { if (off < sizeof(pgoff_t)) *o |= ((pgoff_t) ((*AH->ReadBytePtr) (AH))) << (off * 8); else { if ((*AH->ReadBytePtr) (AH) != 0) exit_horribly(modulename, "file offset in dump file is too large\n"); } } return offsetFlg; }
char* ReadStr | ( | ArchiveHandle * | AH | ) |
Definition at line 1776 of file pg_backup_archiver.c.
References buf, exit_horribly(), modulename, pg_malloc(), _archiveHandle::ReadBufPtr, and ReadInt().
Referenced by _ReadExtraToc(), ReadHead(), and ReadToc().
{ char *buf; int l; l = ReadInt(AH); if (l < 0) buf = NULL; else { buf = (char *) pg_malloc(l + 1); if ((*AH->ReadBufPtr) (AH, (void *) buf, l) != l) exit_horribly(modulename, "unexpected end of file\n"); buf[l] = '\0'; } return buf; }
void ReadToc | ( | ArchiveHandle * | AH | ) |
Definition at line 2217 of file pg_backup_archiver.c.
References ahlog(), _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, exit_horribly(), free, _tocEntry::hadDumper, i, K_VERS_1_10, K_VERS_1_11, K_VERS_1_3, K_VERS_1_5, K_VERS_1_6, K_VERS_1_8, K_VERS_1_9, _archiveHandle::maxDumpId, modulename, _tocEntry::nDeps, _tocEntry::next, CatalogId::oid, _tocEntry::owner, pg_malloc(), pg_malloc0(), pg_realloc(), _tocEntry::prev, processEncodingEntry(), processStdStringsEntry(), _archiveHandle::ReadExtraTocPtr, ReadInt(), ReadStr(), _tocEntry::section, CatalogId::tableoid, _tocEntry::tablespace, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, _archiveHandle::version, and _tocEntry::withOids.
Referenced by InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), and InitArchiveFmt_Tar().
{ int i; char *tmp; DumpId *deps; int depIdx; int depSize; TocEntry *te; AH->tocCount = ReadInt(AH); AH->maxDumpId = 0; for (i = 0; i < AH->tocCount; i++) { te = (TocEntry *) pg_malloc0(sizeof(TocEntry)); te->dumpId = ReadInt(AH); if (te->dumpId > AH->maxDumpId) AH->maxDumpId = te->dumpId; /* Sanity check */ if (te->dumpId <= 0) exit_horribly(modulename, "entry ID %d out of range -- perhaps a corrupt TOC\n", te->dumpId); te->hadDumper = ReadInt(AH); if (AH->version >= K_VERS_1_8) { tmp = ReadStr(AH); sscanf(tmp, "%u", &te->catalogId.tableoid); free(tmp); } else te->catalogId.tableoid = InvalidOid; tmp = ReadStr(AH); sscanf(tmp, "%u", &te->catalogId.oid); free(tmp); te->tag = ReadStr(AH); te->desc = ReadStr(AH); if (AH->version >= K_VERS_1_11) { te->section = ReadInt(AH); } else { /* * Rules for pre-8.4 archives wherein pg_dump hasn't classified * the entries into sections. This list need not cover entry * types added later than 8.4. */ if (strcmp(te->desc, "COMMENT") == 0 || strcmp(te->desc, "ACL") == 0 || strcmp(te->desc, "ACL LANGUAGE") == 0) te->section = SECTION_NONE; else if (strcmp(te->desc, "TABLE DATA") == 0 || strcmp(te->desc, "BLOBS") == 0 || strcmp(te->desc, "BLOB COMMENTS") == 0) te->section = SECTION_DATA; else if (strcmp(te->desc, "CONSTRAINT") == 0 || strcmp(te->desc, "CHECK CONSTRAINT") == 0 || strcmp(te->desc, "FK CONSTRAINT") == 0 || strcmp(te->desc, "INDEX") == 0 || strcmp(te->desc, "RULE") == 0 || strcmp(te->desc, "TRIGGER") == 0) te->section = SECTION_POST_DATA; else te->section = SECTION_PRE_DATA; } te->defn = ReadStr(AH); te->dropStmt = ReadStr(AH); if (AH->version >= K_VERS_1_3) te->copyStmt = ReadStr(AH); if (AH->version >= K_VERS_1_6) te->namespace = ReadStr(AH); if (AH->version >= K_VERS_1_10) te->tablespace = ReadStr(AH); te->owner = ReadStr(AH); if (AH->version >= K_VERS_1_9) { if (strcmp(ReadStr(AH), "true") == 0) te->withOids = true; else te->withOids = false; } else te->withOids = true; /* Read TOC entry dependencies */ if (AH->version >= K_VERS_1_5) { depSize = 100; deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize); depIdx = 0; for (;;) { tmp = ReadStr(AH); if (!tmp) break; /* end of list */ if (depIdx >= depSize) { depSize *= 2; deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize); } sscanf(tmp, "%d", &deps[depIdx]); free(tmp); depIdx++; } if (depIdx > 0) /* We have a non-null entry */ { deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx); te->dependencies = deps; te->nDeps = depIdx; } else { free(deps); te->dependencies = NULL; te->nDeps = 0; } } else { te->dependencies = NULL; te->nDeps = 0; } if (AH->ReadExtraTocPtr) (*AH->ReadExtraTocPtr) (AH, te); ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n", i, te->dumpId, te->desc, te->tag); /* link completed entry into TOC circular list */ te->prev = AH->toc->prev; AH->toc->prev->next = te; AH->toc->prev = te; te->next = AH->toc; /* special processing immediately upon read for some items */ if (strcmp(te->desc, "ENCODING") == 0) processEncodingEntry(AH, te); else if (strcmp(te->desc, "STDSTRINGS") == 0) processStdStringsEntry(AH, te); } }
void ReadTOC | ( | ArchiveHandle * | AH | ) |
int ReconnectToServer | ( | ArchiveHandle * | AH, | |
const char * | dbname, | |||
const char * | newUser | |||
) |
Definition at line 70 of file pg_backup_db.c.
References _connectDB(), _archiveHandle::connection, PQdb(), PQfinish(), and PQuser().
Referenced by _reconnectToDB().
{ PGconn *newConn; const char *newdbname; const char *newusername; if (!dbname) newdbname = PQdb(AH->connection); else newdbname = dbname; if (!username) newusername = PQuser(AH->connection); else newusername = username; /* Let's see if the request is already satisfied */ if (strcmp(newdbname, PQdb(AH->connection)) == 0 && strcmp(newusername, PQuser(AH->connection)) == 0) return 1; newConn = _connectDB(AH, newdbname, newusername); PQfinish(AH->connection); AH->connection = newConn; return 1; }
void StartRestoreBlob | ( | ArchiveHandle * | AH, | |
Oid | oid, | |||
bool | drop | |||
) |
Definition at line 1010 of file pg_backup_archiver.c.
References ahlog(), ahprintf(), _archiveHandle::blobCount, _archiveHandle::connection, DropBlobIfExists(), exit_horribly(), INV_WRITE, _archiveHandle::lo_buf_used, lo_create(), lo_open(), _archiveHandle::loFd, modulename, PQerrorMessage(), _archiveHandle::version, and _archiveHandle::writingBlob.
Referenced by _LoadBlobs().
{ bool old_blob_style = (AH->version < K_VERS_1_12); Oid loOid; AH->blobCount++; /* Initialize the LO Buffer */ AH->lo_buf_used = 0; ahlog(AH, 1, "restoring large object with OID %u\n", oid); /* With an old archive we must do drop and create logic here */ if (old_blob_style && drop) DropBlobIfExists(AH, oid); if (AH->connection) { if (old_blob_style) { loOid = lo_create(AH->connection, oid); if (loOid == 0 || loOid != oid) exit_horribly(modulename, "could not create large object %u: %s", oid, PQerrorMessage(AH->connection)); } AH->loFd = lo_open(AH->connection, oid, INV_WRITE); if (AH->loFd == -1) exit_horribly(modulename, "could not open large object %u: %s", oid, PQerrorMessage(AH->connection)); } else { if (old_blob_style) ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n", oid, INV_WRITE); else ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n", oid, INV_WRITE); } AH->writingBlob = 1; }
void StartRestoreBlobs | ( | ArchiveHandle * | AH | ) |
Definition at line 972 of file pg_backup_archiver.c.
References ahprintf(), _archiveHandle::blobCount, _archiveHandle::connection, _archiveHandle::ropt, _restoreOptions::single_txn, and StartTransaction().
Referenced by _LoadBlobs().
{ if (!AH->ropt->single_txn) { if (AH->connection) StartTransaction(AH); else ahprintf(AH, "BEGIN;\n\n"); } AH->blobCount = 0; }
teReqs TocIDRequired | ( | ArchiveHandle * | AH, | |
DumpId | id | |||
) |
Definition at line 1610 of file pg_backup_archiver.c.
References getTocEntryByDumpId(), and _tocEntry::reqs.
Referenced by _tarPositionTo(), and findDumpableDependencies().
{ TocEntry *te = getTocEntryByDumpId(AH, id); if (!te) return 0; return te->reqs; }
void warn_or_exit_horribly | ( | ArchiveHandle * | AH, | |
const char * | modulename, | |||
const char * | fmt, | |||
... | ||||
) |
void WriteDataChunks | ( | ArchiveHandle * | AH, | |
struct ParallelState * | pstate | |||
) |
Definition at line 2097 of file pg_backup_archiver.c.
References ACT_DUMP, Assert, _tocEntry::dataDumper, DispatchJobForTocEntry(), EnsureIdleWorker(), EnsureWorkersFinished(), GetIdleWorker(), _tocEntry::next, NO_SLOT, ParallelState::numWorkers, REQ_DATA, _tocEntry::reqs, _archiveHandle::toc, and WriteDataChunksForTocEntry().
Referenced by _CloseArchive().
{ TocEntry *te; for (te = AH->toc->next; te != AH->toc; te = te->next) { if (!te->dataDumper) continue; if ((te->reqs & REQ_DATA) == 0) continue; if (pstate && pstate->numWorkers > 1) { /* * If we are in a parallel backup, then we are always the master * process. */ EnsureIdleWorker(AH, pstate); Assert(GetIdleWorker(pstate) != NO_SLOT); DispatchJobForTocEntry(AH, pstate, te, ACT_DUMP); } else WriteDataChunksForTocEntry(AH, te); } EnsureWorkersFinished(AH, pstate); }
void WriteDataChunksForTocEntry | ( | ArchiveHandle * | AH, | |
TocEntry * | te | |||
) |
Definition at line 2126 of file pg_backup_archiver.c.
References _archiveHandle::currToc, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::desc, _archiveHandle::EndBlobsPtr, _archiveHandle::EndDataPtr, NULL, _archiveHandle::StartBlobsPtr, and _archiveHandle::StartDataPtr.
Referenced by _WorkerJobDumpDirectory(), and WriteDataChunks().
{ StartDataPtr startPtr; EndDataPtr endPtr; AH->currToc = te; if (strcmp(te->desc, "BLOBS") == 0) { startPtr = AH->StartBlobsPtr; endPtr = AH->EndBlobsPtr; } else { startPtr = AH->StartDataPtr; endPtr = AH->EndDataPtr; } if (startPtr != NULL) (*startPtr) (AH, te); /* * The user-provided DataDumper routine needs to call AH->WriteData */ (*te->dataDumper) ((Archive *) AH, te->dataDumperArg); if (endPtr != NULL) (*endPtr) (AH, te); AH->currToc = NULL; }
void WriteHead | ( | ArchiveHandle * | AH | ) |
Definition at line 3193 of file pg_backup_archiver.c.
References _archiveHandle::compression, _archiveHandle::connection, _archiveHandle::createDate, _archiveHandle::format, _archiveHandle::intSize, modulename, _archiveHandle::offSize, PQdb(), _archiveHandle::public, Archive::remoteVersionStr, tm, _archiveHandle::vmaj, _archiveHandle::vmin, _archiveHandle::vrev, write_msg(), _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, WriteInt(), and WriteStr().
Referenced by _CloseArchive().
{ struct tm crtm; (*AH->WriteBufPtr) (AH, "PGDMP", 5); /* Magic code */ (*AH->WriteBytePtr) (AH, AH->vmaj); (*AH->WriteBytePtr) (AH, AH->vmin); (*AH->WriteBytePtr) (AH, AH->vrev); (*AH->WriteBytePtr) (AH, AH->intSize); (*AH->WriteBytePtr) (AH, AH->offSize); (*AH->WriteBytePtr) (AH, AH->format); #ifndef HAVE_LIBZ if (AH->compression != 0) write_msg(modulename, "WARNING: requested compression not available in this " "installation -- archive will be uncompressed\n"); AH->compression = 0; #endif WriteInt(AH, AH->compression); crtm = *localtime(&AH->createDate); WriteInt(AH, crtm.tm_sec); WriteInt(AH, crtm.tm_min); WriteInt(AH, crtm.tm_hour); WriteInt(AH, crtm.tm_mday); WriteInt(AH, crtm.tm_mon); WriteInt(AH, crtm.tm_year); WriteInt(AH, crtm.tm_isdst); WriteStr(AH, PQdb(AH->connection)); WriteStr(AH, AH->public.remoteVersionStr); WriteStr(AH, PG_VERSION); }
size_t WriteInt | ( | ArchiveHandle * | AH, | |
int | i | |||
) |
Definition at line 1702 of file pg_backup_archiver.c.
References _archiveHandle::intSize, and _archiveHandle::WriteBytePtr.
Referenced by _CustomWriteFunc(), _EndBlob(), _EndBlobs(), _EndData(), _StartBlob(), _StartBlobs(), _StartData(), WriteHead(), WriteStr(), and WriteToc().
{ int b; /* * This is a bit yucky, but I don't want to make the binary format very * dependent on representation, and not knowing much about it, I write out * a sign byte. If you change this, don't forget to change the file * version #, and modify readInt to read the new format AS WELL AS the old * formats. */ /* SIGN byte */ if (i < 0) { (*AH->WriteBytePtr) (AH, 1); i = -i; } else (*AH->WriteBytePtr) (AH, 0); for (b = 0; b < AH->intSize; b++) { (*AH->WriteBytePtr) (AH, i & 0xFF); i >>= 8; } return AH->intSize + 1; }
size_t WriteOffset | ( | ArchiveHandle * | , | |
pgoff_t | , | |||
int | ||||
) |
Definition at line 1621 of file pg_backup_archiver.c.
References _archiveHandle::WriteBytePtr.
Referenced by _WriteExtraToc().
{ int off; /* Save the flag */ (*AH->WriteBytePtr) (AH, wasSet); /* Write out pgoff_t smallest byte first, prevents endian mismatch */ for (off = 0; off < sizeof(pgoff_t); off++) { (*AH->WriteBytePtr) (AH, o & 0xFF); o >>= 8; } return sizeof(pgoff_t) + 1; }
size_t WriteStr | ( | ArchiveHandle * | AH, | |
const char * | s | |||
) |
Definition at line 1760 of file pg_backup_archiver.c.
References _archiveHandle::WriteBufPtr, and WriteInt().
Referenced by _WriteExtraToc(), WriteHead(), and WriteToc().
void WriteToc | ( | ArchiveHandle * | AH | ) |
Definition at line 2159 of file pg_backup_archiver.c.
References _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::dataDumper, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, i, _tocEntry::nDeps, _tocEntry::next, NULL, CatalogId::oid, _tocEntry::owner, REQ_DATA, REQ_SCHEMA, REQ_SPECIAL, _tocEntry::reqs, _tocEntry::section, CatalogId::tableoid, _tocEntry::tablespace, _tocEntry::tag, _archiveHandle::toc, _tocEntry::withOids, _archiveHandle::WriteExtraTocPtr, WriteInt(), and WriteStr().
Referenced by _CloseArchive().
{ TocEntry *te; char workbuf[32]; int tocCount; int i; /* count entries that will actually be dumped */ tocCount = 0; for (te = AH->toc->next; te != AH->toc; te = te->next) { if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) != 0) tocCount++; } /* printf("%d TOC Entries to save\n", tocCount); */ WriteInt(AH, tocCount); for (te = AH->toc->next; te != AH->toc; te = te->next) { if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) == 0) continue; WriteInt(AH, te->dumpId); WriteInt(AH, te->dataDumper ? 1 : 0); /* OID is recorded as a string for historical reasons */ sprintf(workbuf, "%u", te->catalogId.tableoid); WriteStr(AH, workbuf); sprintf(workbuf, "%u", te->catalogId.oid); WriteStr(AH, workbuf); WriteStr(AH, te->tag); WriteStr(AH, te->desc); WriteInt(AH, te->section); WriteStr(AH, te->defn); WriteStr(AH, te->dropStmt); WriteStr(AH, te->copyStmt); WriteStr(AH, te->namespace); WriteStr(AH, te->tablespace); WriteStr(AH, te->owner); WriteStr(AH, te->withOids ? "true" : "false"); /* Dump list of dependencies */ for (i = 0; i < te->nDeps; i++) { sprintf(workbuf, "%d", te->dependencies[i]); WriteStr(AH, workbuf); } WriteStr(AH, NULL); /* Terminate List */ if (AH->WriteExtraTocPtr) (*AH->WriteExtraTocPtr) (AH, te); } }
void void WriteTOC | ( | ArchiveHandle * | AH | ) |