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 "common/file_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 205 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().

206 {
207  lclTocEntry *ctx;
208 
209  ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
210  if (te->dataDumper)
212  else
214 
215  te->formatData = (void *) ctx;
216 }
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 782 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

Definition at line 694 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

695 {
696  lclContext *ctx = (lclContext *) AH->formatData;
697  pgoff_t tpos;
698 
699  if (AH->mode == archModeWrite)
700  {
701  WriteHead(AH);
702  /* Remember TOC's seek position for use below */
703  tpos = ftello(AH->FH);
704  if (tpos < 0 && ctx->hasSeek)
705  exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
706  strerror(errno));
707  WriteToc(AH);
708  ctx->dataStart = _getFilePos(AH, ctx);
709  WriteDataChunks(AH, NULL);
710 
711  /*
712  * If possible, re-write the TOC in order to update the data offset
713  * information. This is not essential, as pg_restore can cope in most
714  * cases without it; but it can make pg_restore significantly faster
715  * in some situations (especially parallel restore).
716  */
717  if (ctx->hasSeek &&
718  fseeko(AH->FH, tpos, SEEK_SET) == 0)
719  WriteToc(AH);
720  }
721 
722  if (fclose(AH->FH) != 0)
723  exit_horribly(modulename, "could not close archive file: %s\n", strerror(errno));
724 
725  /* Sync the output file if one is defined */
726  if (AH->dosync && AH->mode == archModeWrite && AH->fSpec)
727  (void) fsync_fname(AH->fSpec, false, progname);
728 
729  AH->FH = NULL;
730 }
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:567
void WriteToc(ArchiveHandle *AH)
#define fseeko(stream, offset, origin)
Definition: win32.h:237
const char * progname
Definition: pg_standby.c:37
#define pgoff_t
Definition: win32.h:231
static const char * modulename
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
#define ftello(stream)
Definition: win32.h:240
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 911 of file pg_backup_custom.c.

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

Referenced by _PrintData().

912 {
913  size_t blkLen;
914 
915  /* Read length */
916  blkLen = ReadInt(AH);
917  if (blkLen == 0)
918  return 0;
919 
920  /* If the caller's buffer is not large enough, allocate a bigger one */
921  if (blkLen > *buflen)
922  {
923  free(*buf);
924  *buf = (char *) pg_malloc(blkLen);
925  *buflen = blkLen;
926  }
927 
928  /* exits app on read errors */
929  _ReadBuf(AH, *buf, blkLen);
930 
931  return blkLen;
932 }
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:67
#define free(a)
Definition: header.h:65
static void _CustomWriteFunc ( ArchiveHandle AH,
const char *  buf,
size_t  len 
)
static

Definition at line 895 of file pg_backup_custom.c.

References _WriteBuf(), and WriteInt().

Referenced by _StartBlob(), and _StartData().

896 {
897  /* never write 0-byte blocks (this should not happen) */
898  if (len > 0)
899  {
900  WriteInt(AH, len);
901  _WriteBuf(AH, buf, len);
902  }
903  return;
904 }
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
static char * buf
Definition: pg_test_fsync.c:67
size_t WriteInt(ArchiveHandle *AH, int i)
static void _DeClone ( ArchiveHandle AH)
static

Definition at line 803 of file pg_backup_custom.c.

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Custom().

804 {
805  lclContext *ctx = (lclContext *) AH->formatData;
806 
807  free(ctx);
808 }
#define free(a)
Definition: header.h:65
static void _EndBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 393 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

394 {
395  lclContext *ctx = (lclContext *) AH->formatData;
396 
397  EndCompressor(AH, ctx->cs);
398  /* Send the end marker */
399  WriteInt(AH, 0);
400 }
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 408 of file pg_backup_custom.c.

References WriteInt().

Referenced by InitArchiveFmt_Custom().

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

Definition at line 336 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

337 {
338  lclContext *ctx = (lclContext *) AH->formatData;
339 
340  EndCompressor(AH, ctx->cs);
341  /* Send the end marker */
342  WriteInt(AH, 0);
343 }
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 829 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().

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

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

Referenced by _PrintTocData().

520 {
521  Oid oid;
522 
523  StartRestoreBlobs(AH);
524 
525  oid = ReadInt(AH);
526  while (oid != 0)
527  {
528  StartRestoreBlob(AH, oid, drop);
529  _PrintData(AH);
530  EndRestoreBlob(AH, oid);
531  oid = ReadInt(AH);
532  }
533 
534  EndRestoreBlobs(AH);
535 }
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 513 of file pg_backup_custom.c.

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

Referenced by _LoadBlobs(), and _PrintTocData().

514 {
516 }
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 272 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

Definition at line 418 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().

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

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

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

Referenced by _CustomReadFunc(), and InitArchiveFmt_Custom().

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

Definition at line 628 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

Definition at line 244 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

Definition at line 740 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

References _skipData(), and ReadInt().

Referenced by _PrintTocData().

545 {
546  Oid oid;
547 
548  oid = ReadInt(AH);
549  while (oid != 0)
550  {
551  _skipData(AH);
552  oid = ReadInt(AH);
553  }
554 }
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 562 of file pg_backup_custom.c.

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

Referenced by _PrintTocData(), and _skipBlobs().

563 {
564  lclContext *ctx = (lclContext *) AH->formatData;
565  size_t blkLen;
566  char *buf = NULL;
567  int buflen = 0;
568  size_t cnt;
569 
570  blkLen = ReadInt(AH);
571  while (blkLen != 0)
572  {
573  if (blkLen > buflen)
574  {
575  if (buf)
576  free(buf);
577  buf = (char *) pg_malloc(blkLen);
578  buflen = blkLen;
579  }
580  if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen)
581  {
582  if (feof(AH->FH))
584  "could not read from input file: end of file\n");
585  else
587  "could not read from input file: %s\n", strerror(errno));
588  }
589 
590  ctx->filePos += blkLen;
591 
592  blkLen = ReadInt(AH);
593  }
594 
595  if (buf)
596  free(buf);
597 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:67
static const char * modulename
#define free(a)
Definition: header.h:65
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 375 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

376 {
377  lclContext *ctx = (lclContext *) AH->formatData;
378 
379  if (oid == 0)
380  exit_horribly(modulename, "invalid OID for large object\n");
381 
382  WriteInt(AH, oid);
383 
385 }
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 355 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().

356 {
357  lclContext *ctx = (lclContext *) AH->formatData;
358  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
359 
360  tctx->dataPos = _getFilePos(AH, ctx);
361  tctx->dataState = K_OFFSET_POS_SET;
362 
363  _WriteByte(AH, BLK_BLOBS); /* Block type */
364  WriteInt(AH, te->dumpId); /* For sanity check */
365 }
#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 292 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().

293 {
294  lclContext *ctx = (lclContext *) AH->formatData;
295  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
296 
297  tctx->dataPos = _getFilePos(AH, ctx);
298  tctx->dataState = K_OFFSET_POS_SET;
299 
300  _WriteByte(AH, BLK_DATA); /* Block type */
301  WriteInt(AH, te->dumpId); /* For sanity check */
302 
304 }
#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 815 of file pg_backup_custom.c.

References parallel_restore().

Referenced by InitArchiveFmt_Custom().

816 {
817  return parallel_restore(AH, te);
818 }
int parallel_restore(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 648 of file pg_backup_custom.c.

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

Referenced by _CustomWriteFunc(), and InitArchiveFmt_Custom().

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

Definition at line 607 of file pg_backup_custom.c.

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

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

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

Definition at line 316 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

317 {
318  lclContext *ctx = (lclContext *) AH->formatData;
319  CompressorState *cs = ctx->cs;
320 
321  if (dLen > 0)
322  /* WriteDataToArchive() internally throws write errors */
323  WriteDataToArchive(AH, cs, data, dLen);
324 
325  return;
326 }
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 228 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

Definition at line 108 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, 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().

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

Variable Documentation

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