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 *AH)
 
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 _skipLOs (ArchiveHandle *AH)
 
static void _StartLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadLOs (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 203 of file pg_backup_custom.c.

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

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

Referenced by InitArchiveFmt_Custom().

◆ _Clone()

static void _Clone ( ArchiveHandle AH)
static

Definition at line 874 of file pg_backup_custom.c.

875 {
876  lclContext *ctx = (lclContext *) AH->formatData;
877 
878  /*
879  * Each thread must have private lclContext working state.
880  */
881  AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
882  memcpy(AH->formatData, ctx, sizeof(lclContext));
883  ctx = (lclContext *) AH->formatData;
884 
885  /* sanity check, shouldn't happen */
886  if (ctx->cs != NULL)
887  pg_fatal("compressor active");
888 
889  /*
890  * We intentionally do not clone TOC-entry-local state: it's useful to
891  * share knowledge about where the data blocks are across threads.
892  * _PrintTocData has to be careful about the order of operations on that
893  * state, though.
894  *
895  * Note: we do not make a local lo_buf because we expect at most one BLOBS
896  * entry per archive, so no parallelism is possible.
897  */
898 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
#define pg_fatal(...)
CompressorState * cs

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

Referenced by InitArchiveFmt_Custom().

◆ _CloseArchive()

static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 733 of file pg_backup_custom.c.

734 {
735  lclContext *ctx = (lclContext *) AH->formatData;
736  pgoff_t tpos;
737 
738  if (AH->mode == archModeWrite)
739  {
740  WriteHead(AH);
741  /* Remember TOC's seek position for use below */
742  tpos = ftello(AH->FH);
743  if (tpos < 0 && ctx->hasSeek)
744  pg_fatal("could not determine seek position in archive file: %m");
745  WriteToc(AH);
746  WriteDataChunks(AH, NULL);
747 
748  /*
749  * If possible, re-write the TOC in order to update the data offset
750  * information. This is not essential, as pg_restore can cope in most
751  * cases without it; but it can make pg_restore significantly faster
752  * in some situations (especially parallel restore).
753  */
754  if (ctx->hasSeek &&
755  fseeko(AH->FH, tpos, SEEK_SET) == 0)
756  WriteToc(AH);
757  }
758 
759  if (fclose(AH->FH) != 0)
760  pg_fatal("could not close archive file: %m");
761 
762  /* Sync the output file if one is defined */
763  if (AH->dosync && AH->mode == archModeWrite && AH->fSpec)
764  (void) fsync_fname(AH->fSpec, false);
765 
766  AH->FH = NULL;
767 }
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:662
@ archModeWrite
Definition: pg_backup.h:50
void WriteHead(ArchiveHandle *AH)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void WriteToc(ArchiveHandle *AH)
#define ftello(stream)
Definition: win32_port.h:221
#define fseeko(stream, offset, origin)
Definition: win32_port.h:218
#define pgoff_t
Definition: win32_port.h:211

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

Referenced by InitArchiveFmt_Custom().

◆ _CustomReadFunc()

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

Definition at line 999 of file pg_backup_custom.c.

1000 {
1001  size_t blkLen;
1002 
1003  /* Read length */
1004  blkLen = ReadInt(AH);
1005  if (blkLen == 0)
1006  return 0;
1007 
1008  /* If the caller's buffer is not large enough, allocate a bigger one */
1009  if (blkLen > *buflen)
1010  {
1011  free(*buf);
1012  *buf = (char *) pg_malloc(blkLen);
1013  *buflen = blkLen;
1014  }
1015 
1016  /* exits app on read errors */
1017  _ReadBuf(AH, *buf, blkLen);
1018 
1019  return blkLen;
1020 }
#define free(a)
Definition: header.h:65
int ReadInt(ArchiveHandle *AH)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static char * buf
Definition: pg_test_fsync.c:67

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

Referenced by _PrintData().

◆ _CustomWriteFunc()

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

Definition at line 984 of file pg_backup_custom.c.

985 {
986  /* never write 0-byte blocks (this should not happen) */
987  if (len > 0)
988  {
989  WriteInt(AH, len);
990  _WriteBuf(AH, buf, len);
991  }
992 }
size_t WriteInt(ArchiveHandle *AH, int i)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
const void size_t len

References _WriteBuf(), buf, len, and WriteInt().

Referenced by _StartData(), and _StartLO().

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 901 of file pg_backup_custom.c.

902 {
903  lclContext *ctx = (lclContext *) AH->formatData;
904 
905  free(ctx);
906 }

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Custom().

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 331 of file pg_backup_custom.c.

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

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

Referenced by InitArchiveFmt_Custom().

◆ _EndLO()

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

Definition at line 389 of file pg_backup_custom.c.

390 {
391  lclContext *ctx = (lclContext *) AH->formatData;
392 
393  EndCompressor(AH, ctx->cs);
394  /* Send the end marker */
395  WriteInt(AH, 0);
396 }

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

Referenced by InitArchiveFmt_Custom().

◆ _EndLOs()

static void _EndLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 404 of file pg_backup_custom.c.

405 {
406  /* Write out a fake zero OID to mark end-of-LOs. */
407  WriteInt(AH, 0);
408 }

References WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _getFilePos()

static pgoff_t _getFilePos ( ArchiveHandle AH,
lclContext ctx 
)
static

Definition at line 932 of file pg_backup_custom.c.

933 {
934  pgoff_t pos;
935 
936  pos = ftello(AH->FH);
937  if (pos < 0)
938  {
939  /* Not expected if we found we can seek. */
940  if (ctx->hasSeek)
941  pg_fatal("could not determine seek position in archive file: %m");
942  }
943  return pos;
944 }

References _archiveHandle::FH, ftello, lclContext::hasSeek, pg_fatal, and pgoff_t.

Referenced by _PrintTocData(), _StartData(), _StartLOs(), and InitArchiveFmt_Custom().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH,
bool  drop 
)
static

Definition at line 573 of file pg_backup_custom.c.

574 {
575  Oid oid;
576 
577  StartRestoreLOs(AH);
578 
579  oid = ReadInt(AH);
580  while (oid != 0)
581  {
582  StartRestoreLO(AH, oid, drop);
583  _PrintData(AH);
584  EndRestoreLO(AH, oid);
585  oid = ReadInt(AH);
586  }
587 
588  EndRestoreLOs(AH);
589 }
void StartRestoreLOs(ArchiveHandle *AH)
void EndRestoreLO(ArchiveHandle *AH, Oid oid)
void EndRestoreLOs(ArchiveHandle *AH)
void StartRestoreLO(ArchiveHandle *AH, Oid oid, bool drop)
static void _PrintData(ArchiveHandle *AH)
unsigned int Oid
Definition: postgres_ext.h:31

References _PrintData(), EndRestoreLO(), EndRestoreLOs(), ReadInt(), StartRestoreLO(), and StartRestoreLOs().

Referenced by _PrintTocData().

◆ _PrepParallelRestore()

static void _PrepParallelRestore ( ArchiveHandle AH)
static

Definition at line 822 of file pg_backup_custom.c.

823 {
824  lclContext *ctx = (lclContext *) AH->formatData;
825  TocEntry *prev_te = NULL;
826  lclTocEntry *prev_tctx = NULL;
827  TocEntry *te;
828 
829  /*
830  * Knowing that the data items were dumped out in TOC order, we can
831  * reconstruct the length of each item as the delta to the start offset of
832  * the next data item.
833  */
834  for (te = AH->toc->next; te != AH->toc; te = te->next)
835  {
836  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
837 
838  /*
839  * Ignore entries without a known data offset; if we were unable to
840  * seek to rewrite the TOC when creating the archive, this'll be all
841  * of them, and we'll end up with no size estimates.
842  */
843  if (tctx->dataState != K_OFFSET_POS_SET)
844  continue;
845 
846  /* Compute previous data item's length */
847  if (prev_te)
848  {
849  if (tctx->dataPos > prev_tctx->dataPos)
850  prev_te->dataLength = tctx->dataPos - prev_tctx->dataPos;
851  }
852 
853  prev_te = te;
854  prev_tctx = tctx;
855  }
856 
857  /* If OK to seek, we can determine the length of the last item */
858  if (prev_te && ctx->hasSeek)
859  {
860  pgoff_t endpos;
861 
862  if (fseeko(AH->FH, 0, SEEK_END) != 0)
863  pg_fatal("error during file seek: %m");
864  endpos = ftello(AH->FH);
865  if (endpos > prev_tctx->dataPos)
866  prev_te->dataLength = endpos - prev_tctx->dataPos;
867  }
868 }
#define K_OFFSET_POS_SET
static XLogRecPtr endpos
Definition: pg_receivewal.c:56
struct _tocEntry * toc
struct _tocEntry * next

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

Referenced by InitArchiveFmt_Custom().

◆ _PrintData()

static void _PrintData ( ArchiveHandle AH)
static

Definition at line 567 of file pg_backup_custom.c.

568 {
570 }
void ReadDataFromArchive(ArchiveHandle *AH, const pg_compress_specification compression_spec, ReadFunc readF)
Definition: compress_io.c:127
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
pg_compress_specification compression_spec

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

Referenced by _LoadLOs(), and _PrintTocData().

◆ _PrintExtraToc()

static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 269 of file pg_backup_custom.c.

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

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

Referenced by InitArchiveFmt_Custom().

◆ _PrintTocData()

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 414 of file pg_backup_custom.c.

415 {
416  lclContext *ctx = (lclContext *) AH->formatData;
417  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
418  int blkType;
419  int id;
420 
421  if (tctx->dataState == K_OFFSET_NO_DATA)
422  return;
423 
424  if (!ctx->hasSeek || tctx->dataState == K_OFFSET_POS_NOT_SET)
425  {
426  /*
427  * We cannot seek directly to the desired block. Instead, skip over
428  * block headers until we find the one we want. Remember the
429  * positions of skipped-over blocks, so that if we later decide we
430  * need to read one, we'll be able to seek to it.
431  *
432  * When our input file is seekable, we can do the search starting from
433  * the point after the last data block we scanned in previous
434  * iterations of this function.
435  */
436  if (ctx->hasSeek)
437  {
438  if (fseeko(AH->FH, ctx->lastFilePos, SEEK_SET) != 0)
439  pg_fatal("error during file seek: %m");
440  }
441 
442  for (;;)
443  {
444  pgoff_t thisBlkPos = _getFilePos(AH, ctx);
445 
446  _readBlockHeader(AH, &blkType, &id);
447 
448  if (blkType == EOF || id == te->dumpId)
449  break;
450 
451  /* Remember the block position, if we got one */
452  if (thisBlkPos >= 0)
453  {
454  TocEntry *otherte = getTocEntryByDumpId(AH, id);
455 
456  if (otherte && otherte->formatData)
457  {
458  lclTocEntry *othertctx = (lclTocEntry *) otherte->formatData;
459 
460  /*
461  * Note: on Windows, multiple threads might access/update
462  * the same lclTocEntry concurrently, but that should be
463  * safe as long as we update dataPos before dataState.
464  * Ideally, we'd use pg_write_barrier() to enforce that,
465  * but the needed infrastructure doesn't exist in frontend
466  * code. But Windows only runs on machines with strong
467  * store ordering, so it should be okay for now.
468  */
469  if (othertctx->dataState == K_OFFSET_POS_NOT_SET)
470  {
471  othertctx->dataPos = thisBlkPos;
472  othertctx->dataState = K_OFFSET_POS_SET;
473  }
474  else if (othertctx->dataPos != thisBlkPos ||
475  othertctx->dataState != K_OFFSET_POS_SET)
476  {
477  /* sanity check */
478  pg_log_warning("data block %d has wrong seek position",
479  id);
480  }
481  }
482  }
483 
484  switch (blkType)
485  {
486  case BLK_DATA:
487  _skipData(AH);
488  break;
489 
490  case BLK_BLOBS:
491  _skipLOs(AH);
492  break;
493 
494  default: /* Always have a default */
495  pg_fatal("unrecognized data block type (%d) while searching archive",
496  blkType);
497  break;
498  }
499  }
500  }
501  else
502  {
503  /* We can just seek to the place we need to be. */
504  if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
505  pg_fatal("error during file seek: %m");
506 
507  _readBlockHeader(AH, &blkType, &id);
508  }
509 
510  /*
511  * If we reached EOF without finding the block we want, then either it
512  * doesn't exist, or it does but we lack the ability to seek back to it.
513  */
514  if (blkType == EOF)
515  {
516  if (!ctx->hasSeek)
517  pg_fatal("could not find block ID %d in archive -- "
518  "possibly due to out-of-order restore request, "
519  "which cannot be handled due to non-seekable input file",
520  te->dumpId);
521  else
522  pg_fatal("could not find block ID %d in archive -- "
523  "possibly corrupt archive",
524  te->dumpId);
525  }
526 
527  /* Are we sane? */
528  if (id != te->dumpId)
529  pg_fatal("found unexpected block ID (%d) when reading data -- expected %d",
530  id, te->dumpId);
531 
532  switch (blkType)
533  {
534  case BLK_DATA:
535  _PrintData(AH);
536  break;
537 
538  case BLK_BLOBS:
539  _LoadLOs(AH, AH->public.ropt->dropSchema);
540  break;
541 
542  default: /* Always have a default */
543  pg_fatal("unrecognized data block type %d while restoring archive",
544  blkType);
545  break;
546  }
547 
548  /*
549  * If our input file is seekable but lacks data offsets, update our
550  * knowledge of where to start future searches from. (Note that we did
551  * not update the current TE's dataState/dataPos. We could have, but
552  * there is no point since it will not be visited again.)
553  */
554  if (ctx->hasSeek && tctx->dataState == K_OFFSET_POS_NOT_SET)
555  {
556  pgoff_t curPos = _getFilePos(AH, ctx);
557 
558  if (curPos > ctx->lastFilePos)
559  ctx->lastFilePos = curPos;
560  }
561 }
TocEntry * getTocEntryByDumpId(ArchiveHandle *AH, DumpId id)
#define BLK_DATA
#define BLK_BLOBS
static void _skipData(ArchiveHandle *AH)
static void _skipLOs(ArchiveHandle *AH)
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
static void _LoadLOs(ArchiveHandle *AH, bool drop)
#define pg_log_warning(...)
Definition: pgfnames.c:24
RestoreOptions * ropt
Definition: pg_backup.h:212
pgoff_t lastFilePos

References _getFilePos(), _LoadLOs(), _PrintData(), _readBlockHeader(), _skipData(), _skipLOs(), BLK_BLOBS, BLK_DATA, lclTocEntry::dataPos, lclTocEntry::dataState, _restoreOptions::dropSchema, _tocEntry::dumpId, _archiveHandle::FH, _archiveHandle::formatData, _tocEntry::formatData, fseeko, getTocEntryByDumpId(), lclContext::hasSeek, if(), K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, K_OFFSET_POS_SET, lclContext::lastFilePos, pg_fatal, pg_log_warning, pgoff_t, _archiveHandle::public, and Archive::ropt.

Referenced by InitArchiveFmt_Custom().

◆ _readBlockHeader()

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

Definition at line 952 of file pg_backup_custom.c.

953 {
954  int byt;
955 
956  /*
957  * Note: if we are at EOF with a pre-1.3 input file, we'll pg_fatal()
958  * inside ReadInt rather than returning EOF. It doesn't seem worth
959  * jumping through hoops to deal with that case better, because no such
960  * files are likely to exist in the wild: only some 7.1 development
961  * versions of pg_dump ever generated such files.
962  */
963  if (AH->version < K_VERS_1_3)
964  *type = BLK_DATA;
965  else
966  {
967  byt = getc(AH->FH);
968  *type = byt;
969  if (byt == EOF)
970  {
971  *id = 0; /* don't return an uninitialized value */
972  return;
973  }
974  }
975 
976  *id = ReadInt(AH);
977 }
#define K_VERS_1_3

References BLK_DATA, _archiveHandle::FH, K_VERS_1_3, ReadInt(), generate_unaccent_rules::type, and _archiveHandle::version.

Referenced by _PrintTocData().

◆ _ReadBuf()

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

Definition at line 711 of file pg_backup_custom.c.

712 {
713  if (fread(buf, 1, len, AH->FH) != len)
714  READ_ERROR_EXIT(AH->FH);
715 }
#define READ_ERROR_EXIT(fd)

References buf, _archiveHandle::FH, len, and READ_ERROR_EXIT.

Referenced by _CustomReadFunc(), and InitArchiveFmt_Custom().

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 679 of file pg_backup_custom.c.

680 {
681  int res;
682 
683  res = getc(AH->FH);
684  if (res == EOF)
685  READ_ERROR_EXIT(AH->FH);
686  return res;
687 }

References _archiveHandle::FH, READ_ERROR_EXIT, and res.

Referenced by InitArchiveFmt_Custom().

◆ _ReadExtraToc()

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 242 of file pg_backup_custom.c.

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

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

Referenced by InitArchiveFmt_Custom().

◆ _ReopenArchive()

static void _ReopenArchive ( ArchiveHandle AH)
static

Definition at line 777 of file pg_backup_custom.c.

778 {
779  lclContext *ctx = (lclContext *) AH->formatData;
780  pgoff_t tpos;
781 
782  if (AH->mode == archModeWrite)
783  pg_fatal("can only reopen input archives");
784 
785  /*
786  * These two cases are user-facing errors since they represent unsupported
787  * (but not invalid) use-cases. Word the error messages appropriately.
788  */
789  if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0)
790  pg_fatal("parallel restore from standard input is not supported");
791  if (!ctx->hasSeek)
792  pg_fatal("parallel restore from non-seekable file is not supported");
793 
794  tpos = ftello(AH->FH);
795  if (tpos < 0)
796  pg_fatal("could not determine seek position in archive file: %m");
797 
798 #ifndef WIN32
799  if (fclose(AH->FH) != 0)
800  pg_fatal("could not close archive file: %m");
801 #endif
802 
803  AH->FH = fopen(AH->fSpec, PG_BINARY_R);
804  if (!AH->FH)
805  pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
806 
807  if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
808  pg_fatal("could not set seek position in archive file: %m");
809 }
#define PG_BINARY_R
Definition: c.h:1211

References archModeWrite, _archiveHandle::FH, _archiveHandle::formatData, fseeko, _archiveHandle::fSpec, ftello, lclContext::hasSeek, if(), _archiveHandle::mode, PG_BINARY_R, pg_fatal, and pgoff_t.

Referenced by InitArchiveFmt_Custom().

◆ _skipData()

static void _skipData ( ArchiveHandle AH)
static

Definition at line 616 of file pg_backup_custom.c.

617 {
618  lclContext *ctx = (lclContext *) AH->formatData;
619  size_t blkLen;
620  char *buf = NULL;
621  int buflen = 0;
622 
623  blkLen = ReadInt(AH);
624  while (blkLen != 0)
625  {
626  if (ctx->hasSeek)
627  {
628  if (fseeko(AH->FH, blkLen, SEEK_CUR) != 0)
629  pg_fatal("error during file seek: %m");
630  }
631  else
632  {
633  if (blkLen > buflen)
634  {
635  free(buf);
636  buf = (char *) pg_malloc(blkLen);
637  buflen = blkLen;
638  }
639  if (fread(buf, 1, blkLen, AH->FH) != blkLen)
640  {
641  if (feof(AH->FH))
642  pg_fatal("could not read from input file: end of file");
643  else
644  pg_fatal("could not read from input file: %m");
645  }
646  }
647 
648  blkLen = ReadInt(AH);
649  }
650 
651  free(buf);
652 }

References buf, _archiveHandle::FH, _archiveHandle::formatData, free, fseeko, lclContext::hasSeek, pg_fatal, pg_malloc(), and ReadInt().

Referenced by _PrintTocData(), and _skipLOs().

◆ _skipLOs()

static void _skipLOs ( ArchiveHandle AH)
static

Definition at line 598 of file pg_backup_custom.c.

599 {
600  Oid oid;
601 
602  oid = ReadInt(AH);
603  while (oid != 0)
604  {
605  _skipData(AH);
606  oid = ReadInt(AH);
607  }
608 }

References _skipData(), and ReadInt().

Referenced by _PrintTocData().

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 289 of file pg_backup_custom.c.

290 {
291  lclContext *ctx = (lclContext *) AH->formatData;
292  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
293 
294  tctx->dataPos = _getFilePos(AH, ctx);
295  if (tctx->dataPos >= 0)
296  tctx->dataState = K_OFFSET_POS_SET;
297 
298  _WriteByte(AH, BLK_DATA); /* Block type */
299  WriteInt(AH, te->dumpId); /* For sanity check */
300 
302 }
CompressorState * AllocateCompressor(const pg_compress_specification compression_spec, WriteFunc writeF)
Definition: compress_io.c:97
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)

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

Referenced by InitArchiveFmt_Custom().

◆ _StartLO()

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

Definition at line 371 of file pg_backup_custom.c.

372 {
373  lclContext *ctx = (lclContext *) AH->formatData;
374 
375  if (oid == 0)
376  pg_fatal("invalid OID for large object");
377 
378  WriteInt(AH, oid);
379 
381 }

References _CustomWriteFunc(), AllocateCompressor(), _archiveHandle::compression_spec, lclContext::cs, _archiveHandle::formatData, if(), pg_fatal, and WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _StartLOs()

static void _StartLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 350 of file pg_backup_custom.c.

351 {
352  lclContext *ctx = (lclContext *) AH->formatData;
353  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
354 
355  tctx->dataPos = _getFilePos(AH, ctx);
356  if (tctx->dataPos >= 0)
357  tctx->dataState = K_OFFSET_POS_SET;
358 
359  _WriteByte(AH, BLK_BLOBS); /* Block type */
360  WriteInt(AH, te->dumpId); /* For sanity check */
361 }

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

Referenced by InitArchiveFmt_Custom().

◆ _WorkerJobRestoreCustom()

static int _WorkerJobRestoreCustom ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 913 of file pg_backup_custom.c.

914 {
915  return parallel_restore(AH, te);
916 }
int parallel_restore(ArchiveHandle *AH, TocEntry *te)

References parallel_restore().

Referenced by InitArchiveFmt_Custom().

◆ _WriteBuf()

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

Definition at line 697 of file pg_backup_custom.c.

698 {
699  if (fwrite(buf, 1, len, AH->FH) != len)
701 }
#define WRITE_ERROR_EXIT

References buf, _archiveHandle::FH, len, and WRITE_ERROR_EXIT.

Referenced by _CustomWriteFunc(), and InitArchiveFmt_Custom().

◆ _WriteByte()

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

Definition at line 662 of file pg_backup_custom.c.

663 {
664  if (fputc(i, AH->FH) == EOF)
666 
667  return 1;
668 }
int i
Definition: isn.c:73

References _archiveHandle::FH, i, and WRITE_ERROR_EXIT.

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

◆ _WriteData()

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

Definition at line 314 of file pg_backup_custom.c.

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

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

Referenced by InitArchiveFmt_Custom().

◆ _WriteExtraToc()

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 226 of file pg_backup_custom.c.

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

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

Referenced by InitArchiveFmt_Custom().

◆ InitArchiveFmt_Custom()

void InitArchiveFmt_Custom ( ArchiveHandle AH)

Definition at line 106 of file pg_backup_custom.c.

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 
126  AH->StartLOsPtr = _StartLOs;
127  AH->StartLOPtr = _StartLO;
128  AH->EndLOPtr = _EndLO;
129  AH->EndLOsPtr = _EndLOs;
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  /*
148  * Now open the file
149  */
150  if (AH->mode == archModeWrite)
151  {
152  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
153  {
154  AH->FH = fopen(AH->fSpec, PG_BINARY_W);
155  if (!AH->FH)
156  pg_fatal("could not open output file \"%s\": %m", AH->fSpec);
157  }
158  else
159  {
160  AH->FH = stdout;
161  if (!AH->FH)
162  pg_fatal("could not open output file: %m");
163  }
164 
165  ctx->hasSeek = checkSeek(AH->FH);
166  }
167  else
168  {
169  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
170  {
171  AH->FH = fopen(AH->fSpec, PG_BINARY_R);
172  if (!AH->FH)
173  pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
174  }
175  else
176  {
177  AH->FH = stdin;
178  if (!AH->FH)
179  pg_fatal("could not open input file: %m");
180  }
181 
182  ctx->hasSeek = checkSeek(AH->FH);
183 
184  ReadHead(AH);
185  ReadToc(AH);
186 
187  /*
188  * Remember location of first data block (i.e., the point after TOC)
189  * in case we have to search for desired data blocks.
190  */
191  ctx->lastFilePos = _getFilePos(AH, ctx);
192  }
193 }
#define PG_BINARY_W
Definition: c.h:1212
bool checkSeek(FILE *fp)
void ReadHead(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
#define LOBBUFSIZE
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
static void _StartData(ArchiveHandle *AH, TocEntry *te)
static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _CloseArchive(ArchiveHandle *AH)
static void _DeClone(ArchiveHandle *AH)
static void _ReopenArchive(ArchiveHandle *AH)
static void _StartLOs(ArchiveHandle *AH, TocEntry *te)
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _EndLOs(ArchiveHandle *AH, TocEntry *te)
static void _PrepParallelRestore(ArchiveHandle *AH)
static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
static int _ReadByte(ArchiveHandle *AH)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static int _WorkerJobRestoreCustom(ArchiveHandle *AH, TocEntry *te)
static void _Clone(ArchiveHandle *AH)
DeClonePtrType DeClonePtr
EndLOsPtrType EndLOsPtr
ReadExtraTocPtrType ReadExtraTocPtr
WorkerJobDumpPtrType WorkerJobDumpPtr
StartLOsPtrType StartLOsPtr
ArchiveEntryPtrType ArchiveEntryPtr
WriteDataPtrType WriteDataPtr
StartLOPtrType StartLOPtr
ClonePtrType ClonePtr
WriteBufPtrType WriteBufPtr
PrepParallelRestorePtrType PrepParallelRestorePtr
EndLOPtrType EndLOPtr
WriteExtraTocPtrType WriteExtraTocPtr
ReadBytePtrType ReadBytePtr
WorkerJobRestorePtrType WorkerJobRestorePtr
PrintTocDataPtrType PrintTocDataPtr
WriteBytePtrType WriteBytePtr
ReadBufPtrType ReadBufPtr
PrintExtraTocPtrType PrintExtraTocPtr
StartDataPtrType StartDataPtr
ReopenPtrType ReopenPtr
EndDataPtrType EndDataPtr
ClosePtrType ClosePtr

References _ArchiveEntry(), _Clone(), _CloseArchive(), _DeClone(), _EndData(), _EndLO(), _EndLOs(), _getFilePos(), _PrepParallelRestore(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _ReopenArchive(), _StartData(), _StartLO(), _StartLOs(), _WorkerJobRestoreCustom(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), _archiveHandle::ArchiveEntryPtr, archModeWrite, checkSeek(), _archiveHandle::ClonePtr, _archiveHandle::ClosePtr, _archiveHandle::DeClonePtr, _archiveHandle::EndDataPtr, _archiveHandle::EndLOPtr, _archiveHandle::EndLOsPtr, _archiveHandle::FH, _archiveHandle::formatData, _archiveHandle::fSpec, lclContext::hasSeek, lclContext::lastFilePos, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, _archiveHandle::mode, PG_BINARY_R, PG_BINARY_W, pg_fatal, pg_malloc(), pg_malloc0(), _archiveHandle::PrepParallelRestorePtr, _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, _archiveHandle::StartDataPtr, _archiveHandle::StartLOPtr, _archiveHandle::StartLOsPtr, generate_unaccent_rules::stdout, _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.

Referenced by _allocAH().