PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_backup_custom.c File Reference
#include "postgres_fe.h"
#include "compress_io.h"
#include "parallel.h"
#include "pg_backup_utils.h"
Include dependency graph for pg_backup_custom.c:

Go to the source code of this file.

Data Structures

struct  lclContext
 
struct  lclTocEntry
 

Functions

static void _ArchiveEntry (ArchiveHandle *AH, TocEntry *te)
 
static void _StartData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteData (ArchiveHandle *AH, const void *data, size_t dLen)
 
static void _EndData (ArchiveHandle *AH, TocEntry *te)
 
static int _WriteByte (ArchiveHandle *AH, const int i)
 
static int _ReadByte (ArchiveHandle *)
 
static void _WriteBuf (ArchiveHandle *AH, const void *buf, size_t len)
 
static void _ReadBuf (ArchiveHandle *AH, void *buf, size_t len)
 
static void _CloseArchive (ArchiveHandle *AH)
 
static void _ReopenArchive (ArchiveHandle *AH)
 
static void _PrintTocData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _ReadExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _PrintExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _PrintData (ArchiveHandle *AH)
 
static void _skipData (ArchiveHandle *AH)
 
static void _skipBlobs (ArchiveHandle *AH)
 
static void _StartBlobs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndBlobs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadBlobs (ArchiveHandle *AH, bool drop)
 
static void _Clone (ArchiveHandle *AH)
 
static void _DeClone (ArchiveHandle *AH)
 
static int _WorkerJobRestoreCustom (ArchiveHandle *AH, TocEntry *te)
 
static void _readBlockHeader (ArchiveHandle *AH, int *type, int *id)
 
static pgoff_t _getFilePos (ArchiveHandle *AH, lclContext *ctx)
 
static void _CustomWriteFunc (ArchiveHandle *AH, const char *buf, size_t len)
 
static size_t _CustomReadFunc (ArchiveHandle *AH, char **buf, size_t *buflen)
 
void InitArchiveFmt_Custom (ArchiveHandle *AH)
 

Variables

static const char * modulename = gettext_noop("custom archiver")
 

Function Documentation

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 204 of file pg_backup_custom.c.

References _tocEntry::dataDumper, lclTocEntry::dataState, _tocEntry::formatData, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, and pg_malloc0().

Referenced by InitArchiveFmt_Custom().

205 {
206  lclTocEntry *ctx;
207 
208  ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
209  if (te->dataDumper)
211  else
213 
214  te->formatData = (void *) ctx;
215 }
DataDumperPtr dataDumper
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define K_OFFSET_NO_DATA
#define K_OFFSET_POS_NOT_SET
static void _Clone ( ArchiveHandle AH)
static

Definition at line 777 of file pg_backup_custom.c.

References lclContext::cs, exit_horribly(), _archiveHandle::formatData, modulename, NULL, and pg_malloc().

Referenced by InitArchiveFmt_Custom().

778 {
779  lclContext *ctx = (lclContext *) AH->formatData;
780 
781  AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
782  memcpy(AH->formatData, ctx, sizeof(lclContext));
783  ctx = (lclContext *) AH->formatData;
784 
785  /* sanity check, shouldn't happen */
786  if (ctx->cs != NULL)
787  exit_horribly(modulename, "compressor active\n");
788 
789  /*
790  * Note: we do not make a local lo_buf because we expect at most one BLOBS
791  * entry per archive, so no parallelism is possible. Likewise,
792  * TOC-entry-local state isn't an issue because any one TOC entry is
793  * touched by just one worker child.
794  */
795 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CompressorState * cs
static const char * modulename
#define NULL
Definition: c.h:226
void exit_horribly(const char *modulename, const char *fmt,...)
static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 693 of file pg_backup_custom.c.

References _getFilePos(), archModeWrite, lclContext::dataStart, exit_horribly(), _archiveHandle::FH, _archiveHandle::formatData, fseeko, ftello, lclContext::hasSeek, _archiveHandle::mode, modulename, NULL, pgoff_t, strerror(), WriteDataChunks(), WriteHead(), and WriteToc().

Referenced by InitArchiveFmt_Custom().

694 {
695  lclContext *ctx = (lclContext *) AH->formatData;
696  pgoff_t tpos;
697 
698  if (AH->mode == archModeWrite)
699  {
700  WriteHead(AH);
701  /* Remember TOC's seek position for use below */
702  tpos = ftello(AH->FH);
703  if (tpos < 0 && ctx->hasSeek)
704  exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
705  strerror(errno));
706  WriteToc(AH);
707  ctx->dataStart = _getFilePos(AH, ctx);
708  WriteDataChunks(AH, NULL);
709 
710  /*
711  * If possible, re-write the TOC in order to update the data offset
712  * information. This is not essential, as pg_restore can cope in most
713  * cases without it; but it can make pg_restore significantly faster
714  * in some situations (especially parallel restore).
715  */
716  if (ctx->hasSeek &&
717  fseeko(AH->FH, tpos, SEEK_SET) == 0)
718  WriteToc(AH);
719  }
720 
721  if (fclose(AH->FH) != 0)
722  exit_horribly(modulename, "could not close archive file: %s\n", strerror(errno));
723 
724  AH->FH = NULL;
725 }
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void WriteToc(ArchiveHandle *AH)
#define fseeko(stream, offset, origin)
Definition: win32.h:247
#define pgoff_t
Definition: win32.h:241
static const char * modulename
#define NULL
Definition: c.h:226
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
#define ftello(stream)
Definition: win32.h:250
void WriteHead(ArchiveHandle *AH)
void exit_horribly(const char *modulename, const char *fmt,...)
pgoff_t dataStart
const char * strerror(int errnum)
Definition: strerror.c:19
static size_t _CustomReadFunc ( ArchiveHandle AH,
char **  buf,
size_t *  buflen 
)
static

Definition at line 906 of file pg_backup_custom.c.

References _ReadBuf(), free, pg_malloc(), and ReadInt().

Referenced by _PrintData().

907 {
908  size_t blkLen;
909 
910  /* Read length */
911  blkLen = ReadInt(AH);
912  if (blkLen == 0)
913  return 0;
914 
915  /* If the caller's buffer is not large enough, allocate a bigger one */
916  if (blkLen > *buflen)
917  {
918  free(*buf);
919  *buf = (char *) pg_malloc(blkLen);
920  *buflen = blkLen;
921  }
922 
923  /* exits app on read errors */
924  _ReadBuf(AH, *buf, blkLen);
925 
926  return blkLen;
927 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:65
#define free(a)
Definition: header.h:60
static void _CustomWriteFunc ( ArchiveHandle AH,
const char *  buf,
size_t  len 
)
static

Definition at line 890 of file pg_backup_custom.c.

References _WriteBuf(), and WriteInt().

Referenced by _StartBlob(), and _StartData().

891 {
892  /* never write 0-byte blocks (this should not happen) */
893  if (len > 0)
894  {
895  WriteInt(AH, len);
896  _WriteBuf(AH, buf, len);
897  }
898  return;
899 }
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
static char * buf
Definition: pg_test_fsync.c:65
size_t WriteInt(ArchiveHandle *AH, int i)
static void _DeClone ( ArchiveHandle AH)
static

Definition at line 798 of file pg_backup_custom.c.

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Custom().

799 {
800  lclContext *ctx = (lclContext *) AH->formatData;
801 
802  free(ctx);
803 }
#define free(a)
Definition: header.h:60
static void _EndBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 392 of file pg_backup_custom.c.

References lclContext::cs, EndCompressor(), _archiveHandle::formatData, and WriteInt().

Referenced by InitArchiveFmt_Custom().

393 {
394  lclContext *ctx = (lclContext *) AH->formatData;
395 
396  EndCompressor(AH, ctx->cs);
397  /* Send the end marker */
398  WriteInt(AH, 0);
399 }
CompressorState * cs
size_t WriteInt(ArchiveHandle *AH, int i)
void EndCompressor(ArchiveHandle *AH, CompressorState *cs)
Definition: compress_io.c:206
static void _EndBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 407 of file pg_backup_custom.c.

References WriteInt().

Referenced by InitArchiveFmt_Custom().

408 {
409  /* Write out a fake zero OID to mark end-of-blobs. */
410  WriteInt(AH, 0);
411 }
size_t WriteInt(ArchiveHandle *AH, int i)
static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 335 of file pg_backup_custom.c.

References lclContext::cs, EndCompressor(), _archiveHandle::formatData, and WriteInt().

Referenced by InitArchiveFmt_Custom().

336 {
337  lclContext *ctx = (lclContext *) AH->formatData;
338 
339  EndCompressor(AH, ctx->cs);
340  /* Send the end marker */
341  WriteInt(AH, 0);
342 }
CompressorState * cs
size_t WriteInt(ArchiveHandle *AH, int i)
void EndCompressor(ArchiveHandle *AH, CompressorState *cs)
Definition: compress_io.c:206
static pgoff_t _getFilePos ( ArchiveHandle AH,
lclContext ctx 
)
static

Definition at line 824 of file pg_backup_custom.c.

References exit_horribly(), _archiveHandle::FH, lclContext::filePos, ftello, lclContext::hasSeek, modulename, pgoff_t, strerror(), and write_msg().

Referenced by _CloseArchive(), _StartBlobs(), _StartData(), and InitArchiveFmt_Custom().

825 {
826  pgoff_t pos;
827 
828  if (ctx->hasSeek)
829  {
830  /*
831  * Prior to 1.7 (pg7.3) we relied on the internally maintained
832  * pointer. Now we rely on ftello() always, unless the file has been
833  * found to not support it. For debugging purposes, print a warning
834  * if the internal pointer disagrees, so that we're more likely to
835  * notice if something's broken about the internal position tracking.
836  */
837  pos = ftello(AH->FH);
838  if (pos < 0)
839  exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
840  strerror(errno));
841 
842  if (pos != ctx->filePos)
843  write_msg(modulename, "WARNING: ftell mismatch with expected position -- ftell used\n");
844  }
845  else
846  pos = ctx->filePos;
847  return pos;
848 }
#define pgoff_t
Definition: win32.h:241
static const char * modulename
void write_msg(const char *modulename, const char *fmt,...)
#define ftello(stream)
Definition: win32.h:250
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
pgoff_t filePos
static void _LoadBlobs ( ArchiveHandle AH,
bool  drop 
)
static

Definition at line 518 of file pg_backup_custom.c.

References _PrintData(), EndRestoreBlob(), EndRestoreBlobs(), ReadInt(), StartRestoreBlob(), and StartRestoreBlobs().

Referenced by _PrintTocData().

519 {
520  Oid oid;
521 
522  StartRestoreBlobs(AH);
523 
524  oid = ReadInt(AH);
525  while (oid != 0)
526  {
527  StartRestoreBlob(AH, oid, drop);
528  _PrintData(AH);
529  EndRestoreBlob(AH, oid);
530  oid = ReadInt(AH);
531  }
532 
533  EndRestoreBlobs(AH);
534 }
int ReadInt(ArchiveHandle *AH)
unsigned int Oid
Definition: postgres_ext.h:31
void StartRestoreBlobs(ArchiveHandle *AH)
static void _PrintData(ArchiveHandle *AH)
void StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
void EndRestoreBlobs(ArchiveHandle *AH)
void EndRestoreBlob(ArchiveHandle *AH, Oid oid)
static void _PrintData ( ArchiveHandle AH)
static

Definition at line 512 of file pg_backup_custom.c.

References _CustomReadFunc(), _archiveHandle::compression, and ReadDataFromArchive().

Referenced by _LoadBlobs(), and _PrintTocData().

513 {
515 }
void ReadDataFromArchive(ArchiveHandle *AH, int compression, ReadFunc readF)
Definition: compress_io.c:161
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 271 of file pg_backup_custom.c.

References ahprintf(), lclTocEntry::dataPos, _tocEntry::formatData, INT64_FORMAT, _archiveHandle::public, and Archive::verbose.

Referenced by InitArchiveFmt_Custom().

272 {
273  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
274 
275  if (AH->public.verbose)
276  ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
277  (int64) ctx->dataPos);
278 }
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
int verbose
Definition: pg_backup.h:181
#define INT64_FORMAT
Definition: c.h:312
static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 417 of file pg_backup_custom.c.

References _LoadBlobs(), _PrintData(), _readBlockHeader(), _skipBlobs(), _skipData(), BLK_BLOBS, BLK_DATA, _restoreOptions::dropSchema, _tocEntry::dumpId, exit_horribly(), _archiveHandle::FH, _archiveHandle::formatData, _tocEntry::formatData, fseeko, lclContext::hasSeek, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, modulename, _archiveHandle::public, Archive::ropt, and strerror().

Referenced by InitArchiveFmt_Custom().

418 {
419  lclContext *ctx = (lclContext *) AH->formatData;
420  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
421  int blkType;
422  int id;
423 
424  if (tctx->dataState == K_OFFSET_NO_DATA)
425  return;
426 
427  if (!ctx->hasSeek || tctx->dataState == K_OFFSET_POS_NOT_SET)
428  {
429  /*
430  * We cannot seek directly to the desired block. Instead, skip over
431  * block headers until we find the one we want. This could fail if we
432  * are asked to restore items out-of-order.
433  */
434  _readBlockHeader(AH, &blkType, &id);
435 
436  while (blkType != EOF && id != te->dumpId)
437  {
438  switch (blkType)
439  {
440  case BLK_DATA:
441  _skipData(AH);
442  break;
443 
444  case BLK_BLOBS:
445  _skipBlobs(AH);
446  break;
447 
448  default: /* Always have a default */
450  "unrecognized data block type (%d) while searching archive\n",
451  blkType);
452  break;
453  }
454  _readBlockHeader(AH, &blkType, &id);
455  }
456  }
457  else
458  {
459  /* We can just seek to the place we need to be. */
460  if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
461  exit_horribly(modulename, "error during file seek: %s\n",
462  strerror(errno));
463 
464  _readBlockHeader(AH, &blkType, &id);
465  }
466 
467  /* Produce suitable failure message if we fell off end of file */
468  if (blkType == EOF)
469  {
470  if (tctx->dataState == K_OFFSET_POS_NOT_SET)
471  exit_horribly(modulename, "could not find block ID %d in archive -- "
472  "possibly due to out-of-order restore request, "
473  "which cannot be handled due to lack of data offsets in archive\n",
474  te->dumpId);
475  else if (!ctx->hasSeek)
476  exit_horribly(modulename, "could not find block ID %d in archive -- "
477  "possibly due to out-of-order restore request, "
478  "which cannot be handled due to non-seekable input file\n",
479  te->dumpId);
480  else /* huh, the dataPos led us to EOF? */
481  exit_horribly(modulename, "could not find block ID %d in archive -- "
482  "possibly corrupt archive\n",
483  te->dumpId);
484  }
485 
486  /* Are we sane? */
487  if (id != te->dumpId)
488  exit_horribly(modulename, "found unexpected block ID (%d) when reading data -- expected %d\n",
489  id, te->dumpId);
490 
491  switch (blkType)
492  {
493  case BLK_DATA:
494  _PrintData(AH);
495  break;
496 
497  case BLK_BLOBS:
498  _LoadBlobs(AH, AH->public.ropt->dropSchema);
499  break;
500 
501  default: /* Always have a default */
502  exit_horribly(modulename, "unrecognized data block type %d while restoring archive\n",
503  blkType);
504  break;
505  }
506 }
static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
#define BLK_DATA
RestoreOptions * ropt
Definition: pg_backup.h:179
#define BLK_BLOBS
static void _skipBlobs(ArchiveHandle *AH)
#define fseeko(stream, offset, origin)
Definition: win32.h:247
static void _PrintData(ArchiveHandle *AH)
static void _LoadBlobs(ArchiveHandle *AH, bool drop)
#define K_OFFSET_NO_DATA
static void _skipData(ArchiveHandle *AH)
static const char * modulename
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
#define K_OFFSET_POS_NOT_SET
static void _readBlockHeader ( ArchiveHandle AH,
int *  type,
int *  id 
)
static

Definition at line 856 of file pg_backup_custom.c.

References BLK_DATA, _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, K_VERS_1_3, ReadInt(), and _archiveHandle::version.

Referenced by _PrintTocData().

857 {
858  lclContext *ctx = (lclContext *) AH->formatData;
859  int byt;
860 
861  /*
862  * Note: if we are at EOF with a pre-1.3 input file, we'll exit_horribly
863  * inside ReadInt rather than returning EOF. It doesn't seem worth
864  * jumping through hoops to deal with that case better, because no such
865  * files are likely to exist in the wild: only some 7.1 development
866  * versions of pg_dump ever generated such files.
867  */
868  if (AH->version < K_VERS_1_3)
869  *type = BLK_DATA;
870  else
871  {
872  byt = getc(AH->FH);
873  *type = byt;
874  if (byt == EOF)
875  {
876  *id = 0; /* don't return an uninitialized value */
877  return;
878  }
879  ctx->filePos += 1;
880  }
881 
882  *id = ReadInt(AH);
883 }
#define BLK_DATA
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_3
pgoff_t filePos
static void _ReadBuf ( ArchiveHandle AH,
void *  buf,
size_t  len 
)
static

Definition at line 666 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, and READ_ERROR_EXIT.

Referenced by _CustomReadFunc(), and InitArchiveFmt_Custom().

667 {
668  lclContext *ctx = (lclContext *) AH->formatData;
669 
670  if (fread(buf, 1, len, AH->FH) != len)
671  READ_ERROR_EXIT(AH->FH);
672  ctx->filePos += len;
673 
674  return;
675 }
static char * buf
Definition: pg_test_fsync.c:65
#define READ_ERROR_EXIT(fd)
pgoff_t filePos
static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 627 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, and READ_ERROR_EXIT.

Referenced by InitArchiveFmt_Custom().

628 {
629  lclContext *ctx = (lclContext *) AH->formatData;
630  int res;
631 
632  res = getc(AH->FH);
633  if (res == EOF)
634  READ_ERROR_EXIT(AH->FH);
635  ctx->filePos += 1;
636  return res;
637 }
#define READ_ERROR_EXIT(fd)
pgoff_t filePos
static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 243 of file pg_backup_custom.c.

References lclTocEntry::dataPos, lclTocEntry::dataState, _tocEntry::formatData, K_VERS_1_7, NULL, pg_malloc0(), ReadInt(), ReadOffset(), and _archiveHandle::version.

Referenced by InitArchiveFmt_Custom().

244 {
245  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
246 
247  if (ctx == NULL)
248  {
249  ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
250  te->formatData = (void *) ctx;
251  }
252 
253  ctx->dataState = ReadOffset(AH, &(ctx->dataPos));
254 
255  /*
256  * Prior to V1.7 (pg7.3), we dumped the data size as an int now we don't
257  * dump it at all.
258  */
259  if (AH->version < K_VERS_1_7)
260  ReadInt(AH);
261 }
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_7
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
int ReadOffset(ArchiveHandle *AH, pgoff_t *o)
#define NULL
Definition: c.h:226
static void _ReopenArchive ( ArchiveHandle AH)
static

Definition at line 735 of file pg_backup_custom.c.

References archModeWrite, exit_horribly(), _archiveHandle::FH, _archiveHandle::formatData, fseeko, _archiveHandle::fSpec, ftello, lclContext::hasSeek, _archiveHandle::mode, modulename, NULL, PG_BINARY_R, pgoff_t, and strerror().

Referenced by InitArchiveFmt_Custom().

736 {
737  lclContext *ctx = (lclContext *) AH->formatData;
738  pgoff_t tpos;
739 
740  if (AH->mode == archModeWrite)
741  exit_horribly(modulename, "can only reopen input archives\n");
742 
743  /*
744  * These two cases are user-facing errors since they represent unsupported
745  * (but not invalid) use-cases. Word the error messages appropriately.
746  */
747  if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0)
748  exit_horribly(modulename, "parallel restore from standard input is not supported\n");
749  if (!ctx->hasSeek)
750  exit_horribly(modulename, "parallel restore from non-seekable file is not supported\n");
751 
752  tpos = ftello(AH->FH);
753  if (tpos < 0)
754  exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
755  strerror(errno));
756 
757 #ifndef WIN32
758  if (fclose(AH->FH) != 0)
759  exit_horribly(modulename, "could not close archive file: %s\n",
760  strerror(errno));
761 #endif
762 
763  AH->FH = fopen(AH->fSpec, PG_BINARY_R);
764  if (!AH->FH)
765  exit_horribly(modulename, "could not open input file \"%s\": %s\n",
766  AH->fSpec, strerror(errno));
767 
768  if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
769  exit_horribly(modulename, "could not set seek position in archive file: %s\n",
770  strerror(errno));
771 }
#define fseeko(stream, offset, origin)
Definition: win32.h:247
#define PG_BINARY_R
Definition: c.h:1040
#define pgoff_t
Definition: win32.h:241
static const char * modulename
#define NULL
Definition: c.h:226
#define ftello(stream)
Definition: win32.h:250
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
static void _skipBlobs ( ArchiveHandle AH)
static

Definition at line 543 of file pg_backup_custom.c.

References _skipData(), and ReadInt().

Referenced by _PrintTocData().

544 {
545  Oid oid;
546 
547  oid = ReadInt(AH);
548  while (oid != 0)
549  {
550  _skipData(AH);
551  oid = ReadInt(AH);
552  }
553 }
int ReadInt(ArchiveHandle *AH)
unsigned int Oid
Definition: postgres_ext.h:31
static void _skipData(ArchiveHandle *AH)
static void _skipData ( ArchiveHandle AH)
static

Definition at line 561 of file pg_backup_custom.c.

References buf, exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, free, modulename, NULL, pg_malloc(), ReadInt(), and strerror().

Referenced by _PrintTocData(), and _skipBlobs().

562 {
563  lclContext *ctx = (lclContext *) AH->formatData;
564  size_t blkLen;
565  char *buf = NULL;
566  int buflen = 0;
567  size_t cnt;
568 
569  blkLen = ReadInt(AH);
570  while (blkLen != 0)
571  {
572  if (blkLen > buflen)
573  {
574  if (buf)
575  free(buf);
576  buf = (char *) pg_malloc(blkLen);
577  buflen = blkLen;
578  }
579  if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen)
580  {
581  if (feof(AH->FH))
583  "could not read from input file: end of file\n");
584  else
586  "could not read from input file: %s\n", strerror(errno));
587  }
588 
589  ctx->filePos += blkLen;
590 
591  blkLen = ReadInt(AH);
592  }
593 
594  if (buf)
595  free(buf);
596 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:65
static const char * modulename
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
pgoff_t filePos
static void _StartBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 374 of file pg_backup_custom.c.

References _CustomWriteFunc(), AllocateCompressor(), _archiveHandle::compression, lclContext::cs, exit_horribly(), _archiveHandle::formatData, modulename, and WriteInt().

Referenced by InitArchiveFmt_Custom().

375 {
376  lclContext *ctx = (lclContext *) AH->formatData;
377 
378  if (oid == 0)
379  exit_horribly(modulename, "invalid OID for large object\n");
380 
381  WriteInt(AH, oid);
382 
384 }
CompressorState * AllocateCompressor(int compression, WriteFunc writeF)
Definition: compress_io.c:128
CompressorState * cs
static const char * modulename
size_t WriteInt(ArchiveHandle *AH, int i)
void exit_horribly(const char *modulename, const char *fmt,...)
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)
static void _StartBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 354 of file pg_backup_custom.c.

References _getFilePos(), _WriteByte(), BLK_BLOBS, _tocEntry::dumpId, _archiveHandle::formatData, _tocEntry::formatData, K_OFFSET_POS_SET, and WriteInt().

Referenced by InitArchiveFmt_Custom().

355 {
356  lclContext *ctx = (lclContext *) AH->formatData;
357  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
358 
359  tctx->dataPos = _getFilePos(AH, ctx);
360  tctx->dataState = K_OFFSET_POS_SET;
361 
362  _WriteByte(AH, BLK_BLOBS); /* Block type */
363  WriteInt(AH, te->dumpId); /* For sanity check */
364 }
#define BLK_BLOBS
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
size_t WriteInt(ArchiveHandle *AH, int i)
#define K_OFFSET_POS_SET
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 291 of file pg_backup_custom.c.

References _CustomWriteFunc(), _getFilePos(), _WriteByte(), AllocateCompressor(), BLK_DATA, _archiveHandle::compression, lclContext::cs, _tocEntry::dumpId, _archiveHandle::formatData, _tocEntry::formatData, K_OFFSET_POS_SET, and WriteInt().

Referenced by InitArchiveFmt_Custom().

292 {
293  lclContext *ctx = (lclContext *) AH->formatData;
294  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
295 
296  tctx->dataPos = _getFilePos(AH, ctx);
297  tctx->dataState = K_OFFSET_POS_SET;
298 
299  _WriteByte(AH, BLK_DATA); /* Block type */
300  WriteInt(AH, te->dumpId); /* For sanity check */
301 
303 }
#define BLK_DATA
CompressorState * AllocateCompressor(int compression, WriteFunc writeF)
Definition: compress_io.c:128
CompressorState * cs
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
size_t WriteInt(ArchiveHandle *AH, int i)
#define K_OFFSET_POS_SET
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)
static int _WriteByte(ArchiveHandle *AH, const int i)
static int _WorkerJobRestoreCustom ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 810 of file pg_backup_custom.c.

References parallel_restore().

Referenced by InitArchiveFmt_Custom().

811 {
812  return parallel_restore(AH, te);
813 }
int parallel_restore(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 647 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, and WRITE_ERROR_EXIT.

Referenced by _CustomWriteFunc(), and InitArchiveFmt_Custom().

648 {
649  lclContext *ctx = (lclContext *) AH->formatData;
650 
651  if (fwrite(buf, 1, len, AH->FH) != len)
653  ctx->filePos += len;
654 
655  return;
656 }
static char * buf
Definition: pg_test_fsync.c:65
#define WRITE_ERROR_EXIT
pgoff_t filePos
static int _WriteByte ( ArchiveHandle AH,
const int  i 
)
static

Definition at line 606 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, and WRITE_ERROR_EXIT.

Referenced by _StartBlobs(), _StartData(), and InitArchiveFmt_Custom().

607 {
608  lclContext *ctx = (lclContext *) AH->formatData;
609  int res;
610 
611  if ((res = fputc(i, AH->FH)) == EOF)
613  ctx->filePos += 1;
614 
615  return 1;
616 }
#define WRITE_ERROR_EXIT
int i
pgoff_t filePos
static void _WriteData ( ArchiveHandle AH,
const void *  data,
size_t  dLen 
)
static

Definition at line 315 of file pg_backup_custom.c.

References lclContext::cs, _archiveHandle::formatData, and WriteDataToArchive().

Referenced by InitArchiveFmt_Custom().

316 {
317  lclContext *ctx = (lclContext *) AH->formatData;
318  CompressorState *cs = ctx->cs;
319 
320  if (dLen > 0)
321  /* WriteDataToArchive() internally throws write errors */
322  WriteDataToArchive(AH, cs, data, dLen);
323 
324  return;
325 }
void WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs, const void *data, size_t dLen)
Definition: compress_io.c:183
CompressorState * cs
static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 227 of file pg_backup_custom.c.

References lclTocEntry::dataPos, lclTocEntry::dataState, _tocEntry::formatData, and WriteOffset().

Referenced by InitArchiveFmt_Custom().

228 {
229  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
230 
231  WriteOffset(AH, ctx->dataPos, ctx->dataState);
232 }
size_t WriteOffset(ArchiveHandle *AH, pgoff_t o, int wasSet)
void InitArchiveFmt_Custom ( ArchiveHandle AH)

Definition at line 107 of file pg_backup_custom.c.

References _ArchiveEntry(), _Clone(), _CloseArchive(), _DeClone(), _EndBlob(), _EndBlobs(), _EndData(), _getFilePos(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _ReopenArchive(), _StartBlob(), _StartBlobs(), _StartData(), _WorkerJobRestoreCustom(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), _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::mode, modulename, NULL, 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().

108 {
109  lclContext *ctx;
110 
111  /* Assuming static functions, this can be copied for each format. */
113  AH->StartDataPtr = _StartData;
114  AH->WriteDataPtr = _WriteData;
115  AH->EndDataPtr = _EndData;
116  AH->WriteBytePtr = _WriteByte;
117  AH->ReadBytePtr = _ReadByte;
118  AH->WriteBufPtr = _WriteBuf;
119  AH->ReadBufPtr = _ReadBuf;
120  AH->ClosePtr = _CloseArchive;
126 
128  AH->StartBlobPtr = _StartBlob;
129  AH->EndBlobPtr = _EndBlob;
130  AH->EndBlobsPtr = _EndBlobs;
131  AH->ClonePtr = _Clone;
132  AH->DeClonePtr = _DeClone;
133 
134  /* no parallel dump in the custom archive, only parallel restore */
135  AH->WorkerJobDumpPtr = NULL;
137 
138  /* Set up a private area. */
139  ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
140  AH->formatData = (void *) ctx;
141 
142  /* Initialize LO buffering */
143  AH->lo_buf_size = LOBBUFSIZE;
144  AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
145 
146  ctx->filePos = 0;
147 
148  /*
149  * Now open the file
150  */
151  if (AH->mode == archModeWrite)
152  {
153  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
154  {
155  AH->FH = fopen(AH->fSpec, PG_BINARY_W);
156  if (!AH->FH)
157  exit_horribly(modulename, "could not open output file \"%s\": %s\n",
158  AH->fSpec, strerror(errno));
159  }
160  else
161  {
162  AH->FH = stdout;
163  if (!AH->FH)
164  exit_horribly(modulename, "could not open output file: %s\n",
165  strerror(errno));
166  }
167 
168  ctx->hasSeek = checkSeek(AH->FH);
169  }
170  else
171  {
172  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
173  {
174  AH->FH = fopen(AH->fSpec, PG_BINARY_R);
175  if (!AH->FH)
176  exit_horribly(modulename, "could not open input file \"%s\": %s\n",
177  AH->fSpec, strerror(errno));
178  }
179  else
180  {
181  AH->FH = stdin;
182  if (!AH->FH)
183  exit_horribly(modulename, "could not open input file: %s\n",
184  strerror(errno));
185  }
186 
187  ctx->hasSeek = checkSeek(AH->FH);
188 
189  ReadHead(AH);
190  ReadToc(AH);
191  ctx->dataStart = _getFilePos(AH, ctx);
192  }
193 
194 }
static void _ReopenArchive(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
StartBlobsPtr StartBlobsPtr
void ReadHead(ArchiveHandle *AH)
static void _Clone(ArchiveHandle *AH)
static void _StartData(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
PrintTocDataPtr PrintTocDataPtr
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
WorkerJobDumpPtr WorkerJobDumpPtr
static int _WorkerJobRestoreCustom(ArchiveHandle *AH, TocEntry *te)
WriteBufPtr WriteBufPtr
WriteExtraTocPtr WriteExtraTocPtr
#define PG_BINARY_W
Definition: c.h:1041
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
static void _CloseArchive(ArchiveHandle *AH)
#define PG_BINARY_R
Definition: c.h:1040
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
static void _StartBlobs(ArchiveHandle *AH, TocEntry *te)
PrintExtraTocPtr PrintExtraTocPtr
WriteBytePtr WriteBytePtr
WorkerJobRestorePtr WorkerJobRestorePtr
ArchiveEntryPtr ArchiveEntryPtr
ReadBytePtr ReadBytePtr
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
static int _ReadByte(ArchiveHandle *)
static const char * modulename
#define NULL
Definition: c.h:226
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _EndBlobs(ArchiveHandle *AH, TocEntry *te)
WriteDataPtr WriteDataPtr
void exit_horribly(const char *modulename, const char *fmt,...)
pgoff_t dataStart
StartDataPtr StartDataPtr
EndBlobsPtr EndBlobsPtr
const char * strerror(int errnum)
Definition: strerror.c:19
static void _DeClone(ArchiveHandle *AH)
bool checkSeek(FILE *fp)
pgoff_t filePos
static int _WriteByte(ArchiveHandle *AH, const int i)
ReadExtraTocPtr ReadExtraTocPtr
#define LOBBUFSIZE
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
StartBlobPtr StartBlobPtr

Variable Documentation

const char* modulename = gettext_noop("custom archiver")
static