PostgreSQL Source Code  git master
pg_backup_custom.c File Reference
#include "postgres_fe.h"
#include "common/file_utils.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 _PrepParallelRestore (ArchiveHandle *AH)
 
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)
 

Function Documentation

◆ _ArchiveEntry()

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

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

202 {
203  lclTocEntry *ctx;
204 
205  ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
206  if (te->dataDumper)
208  else
210 
211  te->formatData = (void *) ctx;
212 }
DataDumperPtr dataDumper
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define K_OFFSET_NO_DATA
#define K_OFFSET_POS_NOT_SET

◆ _Clone()

static void _Clone ( ArchiveHandle AH)
static

Definition at line 822 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

823 {
824  lclContext *ctx = (lclContext *) AH->formatData;
825 
826  AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
827  memcpy(AH->formatData, ctx, sizeof(lclContext));
828  ctx = (lclContext *) AH->formatData;
829 
830  /* sanity check, shouldn't happen */
831  if (ctx->cs != NULL)
832  fatal("compressor active");
833 
834  /*
835  * Note: we do not make a local lo_buf because we expect at most one BLOBS
836  * entry per archive, so no parallelism is possible. Likewise,
837  * TOC-entry-local state isn't an issue because any one TOC entry is
838  * touched by just one worker child.
839  */
840 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CompressorState * cs
#define fatal(...)

◆ _CloseArchive()

static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 680 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

681 {
682  lclContext *ctx = (lclContext *) AH->formatData;
683  pgoff_t tpos;
684 
685  if (AH->mode == archModeWrite)
686  {
687  WriteHead(AH);
688  /* Remember TOC's seek position for use below */
689  tpos = ftello(AH->FH);
690  if (tpos < 0 && ctx->hasSeek)
691  fatal("could not determine seek position in archive file: %m");
692  WriteToc(AH);
693  ctx->dataStart = _getFilePos(AH, ctx);
694  WriteDataChunks(AH, NULL);
695 
696  /*
697  * If possible, re-write the TOC in order to update the data offset
698  * information. This is not essential, as pg_restore can cope in most
699  * cases without it; but it can make pg_restore significantly faster
700  * in some situations (especially parallel restore).
701  */
702  if (ctx->hasSeek &&
703  fseeko(AH->FH, tpos, SEEK_SET) == 0)
704  WriteToc(AH);
705  }
706 
707  if (fclose(AH->FH) != 0)
708  fatal("could not close archive file: %m");
709 
710  /* Sync the output file if one is defined */
711  if (AH->dosync && AH->mode == archModeWrite && AH->fSpec)
712  (void) fsync_fname(AH->fSpec, false);
713 
714  AH->FH = NULL;
715 }
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:616
void WriteToc(ArchiveHandle *AH)
#define pgoff_t
Definition: win32_port.h:195
#define ftello(stream)
Definition: win32_port.h:204
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
#define fatal(...)
void WriteHead(ArchiveHandle *AH)
pgoff_t dataStart

◆ _CustomReadFunc()

static size_t _CustomReadFunc ( ArchiveHandle AH,
char **  buf,
size_t *  buflen 
)
static

Definition at line 949 of file pg_backup_custom.c.

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

Referenced by _PrintData().

950 {
951  size_t blkLen;
952 
953  /* Read length */
954  blkLen = ReadInt(AH);
955  if (blkLen == 0)
956  return 0;
957 
958  /* If the caller's buffer is not large enough, allocate a bigger one */
959  if (blkLen > *buflen)
960  {
961  free(*buf);
962  *buf = (char *) pg_malloc(blkLen);
963  *buflen = blkLen;
964  }
965 
966  /* exits app on read errors */
967  _ReadBuf(AH, *buf, blkLen);
968 
969  return blkLen;
970 }
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

◆ _CustomWriteFunc()

static void _CustomWriteFunc ( ArchiveHandle AH,
const char *  buf,
size_t  len 
)
static

Definition at line 934 of file pg_backup_custom.c.

References _WriteBuf(), and WriteInt().

Referenced by _StartBlob(), and _StartData().

935 {
936  /* never write 0-byte blocks (this should not happen) */
937  if (len > 0)
938  {
939  WriteInt(AH, len);
940  _WriteBuf(AH, buf, len);
941  }
942 }
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)

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 843 of file pg_backup_custom.c.

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Custom().

844 {
845  lclContext *ctx = (lclContext *) AH->formatData;
846 
847  free(ctx);
848 }
#define free(a)
Definition: header.h:65

◆ _EndBlob()

static void _EndBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 387 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

388 {
389  lclContext *ctx = (lclContext *) AH->formatData;
390 
391  EndCompressor(AH, ctx->cs);
392  /* Send the end marker */
393  WriteInt(AH, 0);
394 }
CompressorState * cs
size_t WriteInt(ArchiveHandle *AH, int i)
void EndCompressor(ArchiveHandle *AH, CompressorState *cs)
Definition: compress_io.c:201

◆ _EndBlobs()

static void _EndBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 402 of file pg_backup_custom.c.

References WriteInt().

Referenced by InitArchiveFmt_Custom().

403 {
404  /* Write out a fake zero OID to mark end-of-blobs. */
405  WriteInt(AH, 0);
406 }
size_t WriteInt(ArchiveHandle *AH, int i)

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 330 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

331 {
332  lclContext *ctx = (lclContext *) AH->formatData;
333 
334  EndCompressor(AH, ctx->cs);
335  /* Send the end marker */
336  WriteInt(AH, 0);
337 }
CompressorState * cs
size_t WriteInt(ArchiveHandle *AH, int i)
void EndCompressor(ArchiveHandle *AH, CompressorState *cs)
Definition: compress_io.c:201

◆ _getFilePos()

static pgoff_t _getFilePos ( ArchiveHandle AH,
lclContext ctx 
)
static

Definition at line 869 of file pg_backup_custom.c.

References fatal, _archiveHandle::FH, lclContext::filePos, ftello, lclContext::hasSeek, pg_log_warning, and pgoff_t.

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

870 {
871  pgoff_t pos;
872 
873  if (ctx->hasSeek)
874  {
875  /*
876  * Prior to 1.7 (pg7.3) we relied on the internally maintained
877  * pointer. Now we rely on ftello() always, unless the file has been
878  * found to not support it. For debugging purposes, print a warning
879  * if the internal pointer disagrees, so that we're more likely to
880  * notice if something's broken about the internal position tracking.
881  */
882  pos = ftello(AH->FH);
883  if (pos < 0)
884  fatal("could not determine seek position in archive file: %m");
885 
886  if (pos != ctx->filePos)
887  pg_log_warning("ftell mismatch with expected position -- ftell used");
888  }
889  else
890  pos = ctx->filePos;
891  return pos;
892 }
#define pgoff_t
Definition: win32_port.h:195
#define ftello(stream)
Definition: win32_port.h:204
#define fatal(...)
#define pg_log_warning(...)
Definition: pgfnames.c:24
pgoff_t filePos

◆ _LoadBlobs()

static void _LoadBlobs ( ArchiveHandle AH,
bool  drop 
)
static

Definition at line 511 of file pg_backup_custom.c.

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

Referenced by _PrintTocData().

512 {
513  Oid oid;
514 
515  StartRestoreBlobs(AH);
516 
517  oid = ReadInt(AH);
518  while (oid != 0)
519  {
520  StartRestoreBlob(AH, oid, drop);
521  _PrintData(AH);
522  EndRestoreBlob(AH, oid);
523  oid = ReadInt(AH);
524  }
525 
526  EndRestoreBlobs(AH);
527 }
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)

◆ _PrepParallelRestore()

static void _PrepParallelRestore ( ArchiveHandle AH)
static

Definition at line 770 of file pg_backup_custom.c.

References lclTocEntry::dataPos, lclTocEntry::dataState, endpos, fatal, _archiveHandle::FH, _archiveHandle::formatData, fseeko, ftello, lclContext::hasSeek, K_OFFSET_POS_SET, _tocEntry::next, pgoff_t, and _archiveHandle::toc.

Referenced by InitArchiveFmt_Custom().

771 {
772  lclContext *ctx = (lclContext *) AH->formatData;
773  TocEntry *prev_te = NULL;
774  lclTocEntry *prev_tctx = NULL;
775  TocEntry *te;
776 
777  /*
778  * Knowing that the data items were dumped out in TOC order, we can
779  * reconstruct the length of each item as the delta to the start offset of
780  * the next data item.
781  */
782  for (te = AH->toc->next; te != AH->toc; te = te->next)
783  {
784  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
785 
786  /*
787  * Ignore entries without a known data offset; if we were unable to
788  * seek to rewrite the TOC when creating the archive, this'll be all
789  * of them, and we'll end up with no size estimates.
790  */
791  if (tctx->dataState != K_OFFSET_POS_SET)
792  continue;
793 
794  /* Compute previous data item's length */
795  if (prev_te)
796  {
797  if (tctx->dataPos > prev_tctx->dataPos)
798  prev_te->dataLength = tctx->dataPos - prev_tctx->dataPos;
799  }
800 
801  prev_te = te;
802  prev_tctx = tctx;
803  }
804 
805  /* If OK to seek, we can determine the length of the last item */
806  if (prev_te && ctx->hasSeek)
807  {
808  pgoff_t endpos;
809 
810  if (fseeko(AH->FH, 0, SEEK_END) != 0)
811  fatal("error during file seek: %m");
812  endpos = ftello(AH->FH);
813  if (endpos > prev_tctx->dataPos)
814  prev_te->dataLength = endpos - prev_tctx->dataPos;
815  }
816 }
struct _tocEntry * next
#define pgoff_t
Definition: win32_port.h:195
#define ftello(stream)
Definition: win32_port.h:204
static XLogRecPtr endpos
Definition: pg_receivewal.c:46
struct _tocEntry * toc
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201
#define fatal(...)
#define K_OFFSET_POS_SET

◆ _PrintData()

static void _PrintData ( ArchiveHandle AH)
static

Definition at line 505 of file pg_backup_custom.c.

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

Referenced by _LoadBlobs(), and _PrintTocData().

506 {
508 }
void ReadDataFromArchive(ArchiveHandle *AH, int compression, ReadFunc readF)
Definition: compress_io.c:157
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)

◆ _PrintExtraToc()

static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 268 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

269 {
270  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
271 
272  if (AH->public.verbose)
273  ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
274  (int64) ctx->dataPos);
275 }
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
int verbose
Definition: pg_backup.h:185
#define INT64_FORMAT
Definition: c.h:401

◆ _PrintTocData()

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 412 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

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

◆ _readBlockHeader()

static void _readBlockHeader ( ArchiveHandle AH,
int *  type,
int *  id 
)
static

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

901 {
902  lclContext *ctx = (lclContext *) AH->formatData;
903  int byt;
904 
905  /*
906  * Note: if we are at EOF with a pre-1.3 input file, we'll fatal() inside
907  * ReadInt rather than returning EOF. It doesn't seem worth jumping
908  * through hoops to deal with that case better, because no such files are
909  * likely to exist in the wild: only some 7.1 development versions of
910  * pg_dump ever generated such files.
911  */
912  if (AH->version < K_VERS_1_3)
913  *type = BLK_DATA;
914  else
915  {
916  byt = getc(AH->FH);
917  *type = byt;
918  if (byt == EOF)
919  {
920  *id = 0; /* don't return an uninitialized value */
921  return;
922  }
923  ctx->filePos += 1;
924  }
925 
926  *id = ReadInt(AH);
927 }
#define BLK_DATA
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_3
pgoff_t filePos

◆ _ReadBuf()

static void _ReadBuf ( ArchiveHandle AH,
void *  buf,
size_t  len 
)
static

Definition at line 655 of file pg_backup_custom.c.

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

Referenced by _CustomReadFunc(), and InitArchiveFmt_Custom().

656 {
657  lclContext *ctx = (lclContext *) AH->formatData;
658 
659  if (fread(buf, 1, len, AH->FH) != len)
660  READ_ERROR_EXIT(AH->FH);
661  ctx->filePos += len;
662 }
static char * buf
Definition: pg_test_fsync.c:67
#define READ_ERROR_EXIT(fd)
pgoff_t filePos

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 618 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

619 {
620  lclContext *ctx = (lclContext *) AH->formatData;
621  int res;
622 
623  res = getc(AH->FH);
624  if (res == EOF)
625  READ_ERROR_EXIT(AH->FH);
626  ctx->filePos += 1;
627  return res;
628 }
#define READ_ERROR_EXIT(fd)
pgoff_t filePos

◆ _ReadExtraToc()

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

◆ _ReopenArchive()

static void _ReopenArchive ( ArchiveHandle AH)
static

Definition at line 725 of file pg_backup_custom.c.

References archModeWrite, fatal, _archiveHandle::FH, _archiveHandle::formatData, fseeko, _archiveHandle::fSpec, ftello, lclContext::hasSeek, _archiveHandle::mode, PG_BINARY_R, and pgoff_t.

Referenced by InitArchiveFmt_Custom().

726 {
727  lclContext *ctx = (lclContext *) AH->formatData;
728  pgoff_t tpos;
729 
730  if (AH->mode == archModeWrite)
731  fatal("can only reopen input archives");
732 
733  /*
734  * These two cases are user-facing errors since they represent unsupported
735  * (but not invalid) use-cases. Word the error messages appropriately.
736  */
737  if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0)
738  fatal("parallel restore from standard input is not supported");
739  if (!ctx->hasSeek)
740  fatal("parallel restore from non-seekable file is not supported");
741 
742  tpos = ftello(AH->FH);
743  if (tpos < 0)
744  fatal("could not determine seek position in archive file: %m");
745 
746 #ifndef WIN32
747  if (fclose(AH->FH) != 0)
748  fatal("could not close archive file: %m");
749 #endif
750 
751  AH->FH = fopen(AH->fSpec, PG_BINARY_R);
752  if (!AH->FH)
753  fatal("could not open input file \"%s\": %m", AH->fSpec);
754 
755  if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
756  fatal("could not set seek position in archive file: %m");
757 }
#define PG_BINARY_R
Definition: c.h:1223
#define pgoff_t
Definition: win32_port.h:195
#define ftello(stream)
Definition: win32_port.h:204
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201
#define fatal(...)

◆ _skipBlobs()

static void _skipBlobs ( ArchiveHandle AH)
static

Definition at line 536 of file pg_backup_custom.c.

References _skipData(), and ReadInt().

Referenced by _PrintTocData().

537 {
538  Oid oid;
539 
540  oid = ReadInt(AH);
541  while (oid != 0)
542  {
543  _skipData(AH);
544  oid = ReadInt(AH);
545  }
546 }
int ReadInt(ArchiveHandle *AH)
unsigned int Oid
Definition: postgres_ext.h:31
static void _skipData(ArchiveHandle *AH)

◆ _skipData()

static void _skipData ( ArchiveHandle AH)
static

Definition at line 554 of file pg_backup_custom.c.

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

Referenced by _PrintTocData(), and _skipBlobs().

555 {
556  lclContext *ctx = (lclContext *) AH->formatData;
557  size_t blkLen;
558  char *buf = NULL;
559  int buflen = 0;
560  size_t cnt;
561 
562  blkLen = ReadInt(AH);
563  while (blkLen != 0)
564  {
565  if (blkLen > buflen)
566  {
567  if (buf)
568  free(buf);
569  buf = (char *) pg_malloc(blkLen);
570  buflen = blkLen;
571  }
572  if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen)
573  {
574  if (feof(AH->FH))
575  fatal("could not read from input file: end of file");
576  else
577  fatal("could not read from input file: %m");
578  }
579 
580  ctx->filePos += blkLen;
581 
582  blkLen = ReadInt(AH);
583  }
584 
585  if (buf)
586  free(buf);
587 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:67
#define free(a)
Definition: header.h:65
#define fatal(...)
pgoff_t filePos

◆ _StartBlob()

static void _StartBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 369 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

370 {
371  lclContext *ctx = (lclContext *) AH->formatData;
372 
373  if (oid == 0)
374  fatal("invalid OID for large object");
375 
376  WriteInt(AH, oid);
377 
379 }
CompressorState * AllocateCompressor(int compression, WriteFunc writeF)
Definition: compress_io.c:124
CompressorState * cs
size_t WriteInt(ArchiveHandle *AH, int i)
#define fatal(...)
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)

◆ _StartBlobs()

static void _StartBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

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

350 {
351  lclContext *ctx = (lclContext *) AH->formatData;
352  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
353 
354  tctx->dataPos = _getFilePos(AH, ctx);
355  tctx->dataState = K_OFFSET_POS_SET;
356 
357  _WriteByte(AH, BLK_BLOBS); /* Block type */
358  WriteInt(AH, te->dumpId); /* For sanity check */
359 }
#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)

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

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

289 {
290  lclContext *ctx = (lclContext *) AH->formatData;
291  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
292 
293  tctx->dataPos = _getFilePos(AH, ctx);
294  tctx->dataState = K_OFFSET_POS_SET;
295 
296  _WriteByte(AH, BLK_DATA); /* Block type */
297  WriteInt(AH, te->dumpId); /* For sanity check */
298 
300 }
#define BLK_DATA
CompressorState * AllocateCompressor(int compression, WriteFunc writeF)
Definition: compress_io.c:124
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)

◆ _WorkerJobRestoreCustom()

static int _WorkerJobRestoreCustom ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 855 of file pg_backup_custom.c.

References parallel_restore(), and pgoff_t.

Referenced by InitArchiveFmt_Custom().

856 {
857  return parallel_restore(AH, te);
858 }
int parallel_restore(ArchiveHandle *AH, TocEntry *te)

◆ _WriteBuf()

static void _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 638 of file pg_backup_custom.c.

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

Referenced by _CustomWriteFunc(), and InitArchiveFmt_Custom().

639 {
640  lclContext *ctx = (lclContext *) AH->formatData;
641 
642  if (fwrite(buf, 1, len, AH->FH) != len)
644  ctx->filePos += len;
645 }
static char * buf
Definition: pg_test_fsync.c:67
#define WRITE_ERROR_EXIT
pgoff_t filePos

◆ _WriteByte()

static int _WriteByte ( ArchiveHandle AH,
const int  i 
)
static

Definition at line 597 of file pg_backup_custom.c.

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

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

598 {
599  lclContext *ctx = (lclContext *) AH->formatData;
600  int res;
601 
602  if ((res = fputc(i, AH->FH)) == EOF)
604  ctx->filePos += 1;
605 
606  return 1;
607 }
#define WRITE_ERROR_EXIT
int i
pgoff_t filePos

◆ _WriteData()

static void _WriteData ( ArchiveHandle AH,
const void *  data,
size_t  dLen 
)
static

Definition at line 312 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

313 {
314  lclContext *ctx = (lclContext *) AH->formatData;
315  CompressorState *cs = ctx->cs;
316 
317  if (dLen > 0)
318  /* WriteDataToArchive() internally throws write errors */
319  WriteDataToArchive(AH, cs, data, dLen);
320 }
void WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs, const void *data, size_t dLen)
Definition: compress_io.c:179
CompressorState * cs

◆ _WriteExtraToc()

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 224 of file pg_backup_custom.c.

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

Referenced by InitArchiveFmt_Custom().

225 {
226  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
227 
228  WriteOffset(AH, ctx->dataPos, ctx->dataState);
229 }
size_t WriteOffset(ArchiveHandle *AH, pgoff_t o, int wasSet)

◆ InitArchiveFmt_Custom()

void InitArchiveFmt_Custom ( ArchiveHandle AH)

Definition at line 106 of file pg_backup_custom.c.

References _ArchiveEntry(), _Clone(), _CloseArchive(), _DeClone(), _EndBlob(), _EndBlobs(), _EndData(), _getFilePos(), _PrepParallelRestore(), _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, fatal, _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, _archiveHandle::fSpec, lclContext::hasSeek, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, _archiveHandle::mode, PG_BINARY_R, PG_BINARY_W, pg_malloc(), pg_malloc0(), _archiveHandle::PrepParallelRestorePtr, _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, _archiveHandle::StartBlobPtr, _archiveHandle::StartBlobsPtr, _archiveHandle::StartDataPtr, generate_unaccent_rules::stdout, _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.

Referenced by _allocAH().

107 {
108  lclContext *ctx;
109 
110  /* Assuming static functions, this can be copied for each format. */
112  AH->StartDataPtr = _StartData;
113  AH->WriteDataPtr = _WriteData;
114  AH->EndDataPtr = _EndData;
115  AH->WriteBytePtr = _WriteByte;
116  AH->ReadBytePtr = _ReadByte;
117  AH->WriteBufPtr = _WriteBuf;
118  AH->ReadBufPtr = _ReadBuf;
119  AH->ClosePtr = _CloseArchive;
125 
127  AH->StartBlobPtr = _StartBlob;
128  AH->EndBlobPtr = _EndBlob;
129  AH->EndBlobsPtr = _EndBlobs;
130 
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  fatal("could not open output file \"%s\": %m", AH->fSpec);
159  }
160  else
161  {
162  AH->FH = stdout;
163  if (!AH->FH)
164  fatal("could not open output file: %m");
165  }
166 
167  ctx->hasSeek = checkSeek(AH->FH);
168  }
169  else
170  {
171  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
172  {
173  AH->FH = fopen(AH->fSpec, PG_BINARY_R);
174  if (!AH->FH)
175  fatal("could not open input file \"%s\": %m", AH->fSpec);
176  }
177  else
178  {
179  AH->FH = stdin;
180  if (!AH->FH)
181  fatal("could not open input file: %m");
182  }
183 
184  ctx->hasSeek = checkSeek(AH->FH);
185 
186  ReadHead(AH);
187  ReadToc(AH);
188  ctx->dataStart = _getFilePos(AH, ctx);
189  }
190 
191 }
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:1224
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
static void _CloseArchive(ArchiveHandle *AH)
StartBlobsPtrType StartBlobsPtr
#define PG_BINARY_R
Definition: c.h:1223
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 void _PrepParallelRestore(ArchiveHandle *AH)
static int _ReadByte(ArchiveHandle *)
PrintTocDataPtrType PrintTocDataPtr
WriteDataPtrType WriteDataPtr
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _EndBlobs(ArchiveHandle *AH, TocEntry *te)
PrepParallelRestorePtrType PrepParallelRestorePtr
EndBlobsPtrType EndBlobsPtr
ArchiveEntryPtrType ArchiveEntryPtr
#define fatal(...)
pgoff_t dataStart
ClonePtrType ClonePtr
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