PostgreSQL Source Code  git master
pg_backup_directory.c File Reference
#include "postgres_fe.h"
#include <dirent.h>
#include <sys/stat.h>
#include "common/file_utils.h"
#include "compress_io.h"
#include "parallel.h"
#include "pg_backup_utils.h"
Include dependency graph for pg_backup_directory.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 _EndData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteData (ArchiveHandle *AH, const void *data, size_t dLen)
 
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 _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, TocEntry *te)
 
static void _PrepParallelRestore (ArchiveHandle *AH)
 
static void _Clone (ArchiveHandle *AH)
 
static void _DeClone (ArchiveHandle *AH)
 
static int _WorkerJobRestoreDirectory (ArchiveHandle *AH, TocEntry *te)
 
static int _WorkerJobDumpDirectory (ArchiveHandle *AH, TocEntry *te)
 
static void setFilePath (ArchiveHandle *AH, char *buf, const char *relativeFilename)
 
void InitArchiveFmt_Directory (ArchiveHandle *AH)
 
static void _PrintFileData (ArchiveHandle *AH, char *filename)
 

Function Documentation

◆ _ArchiveEntry()

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 230 of file pg_backup_directory.c.

231 {
232  lclTocEntry *tctx;
233  char fn[MAXPGPATH];
234 
235  tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
236  if (strcmp(te->desc, "BLOBS") == 0)
237  {
238  snprintf(fn, MAXPGPATH, "blobs_%d.toc", te->dumpId);
239  tctx->filename = pg_strdup(fn);
240  }
241  else if (te->dataDumper)
242  {
243  snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId);
244  tctx->filename = pg_strdup(fn);
245  }
246  else
247  tctx->filename = NULL;
248 
249  te->formatData = (void *) tctx;
250 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define MAXPGPATH
#define snprintf
Definition: port.h:238
DataDumperPtr dataDumper
static void * fn(void *arg)
Definition: thread-alloc.c:119

References _tocEntry::dataDumper, _tocEntry::desc, _tocEntry::dumpId, lclTocEntry::filename, fn(), _tocEntry::formatData, MAXPGPATH, pg_malloc0(), pg_strdup(), and snprintf.

Referenced by InitArchiveFmt_Directory().

◆ _Clone()

static void _Clone ( ArchiveHandle AH)
static

Definition at line 825 of file pg_backup_directory.c.

826 {
827  lclContext *ctx = (lclContext *) AH->formatData;
828 
829  AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
830  memcpy(AH->formatData, ctx, sizeof(lclContext));
831  ctx = (lclContext *) AH->formatData;
832 
833  /*
834  * TOC-entry-local state isn't an issue because any one TOC entry is
835  * touched by just one worker child.
836  */
837 
838  /*
839  * We also don't copy the ParallelState pointer (pstate), only the leader
840  * process ever writes to it.
841  */
842 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47

References _archiveHandle::formatData, and pg_malloc().

Referenced by InitArchiveFmt_Directory().

◆ _CloseArchive()

static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 581 of file pg_backup_directory.c.

582 {
583  lclContext *ctx = (lclContext *) AH->formatData;
584 
585  if (AH->mode == archModeWrite)
586  {
587  CompressFileHandle *tocFH;
588  pg_compress_specification compression_spec = {0};
589  char fname[MAXPGPATH];
590 
591  setFilePath(AH, fname, "toc.dat");
592 
593  /* this will actually fork the processes for a parallel backup */
594  ctx->pstate = ParallelBackupStart(AH);
595 
596  /* The TOC is always created uncompressed */
597  compression_spec.algorithm = PG_COMPRESSION_NONE;
598  tocFH = InitCompressFileHandle(compression_spec);
599  if (!tocFH->open_write_func(fname, PG_BINARY_W, tocFH))
600  pg_fatal("could not open output file \"%s\": %m", fname);
601  ctx->dataFH = tocFH;
602 
603  /*
604  * Write 'tar' in the format field of the toc.dat file. The directory
605  * is compatible with 'tar', so there's no point having a different
606  * format code for it.
607  */
608  AH->format = archTar;
609  WriteHead(AH);
610  AH->format = archDirectory;
611  WriteToc(AH);
612  if (!EndCompressFileHandle(tocFH))
613  pg_fatal("could not close TOC file: %m");
614  WriteDataChunks(AH, ctx->pstate);
615 
616  ParallelBackupEnd(AH, ctx->pstate);
617 
618  /*
619  * In directory mode, there is no need to sync all the entries
620  * individually. Just recurse once through all the files generated.
621  */
622  if (AH->dosync)
623  sync_dir_recurse(ctx->directory, AH->sync_method);
624  }
625  AH->FH = NULL;
626 }
void ParallelBackupEnd(ArchiveHandle *AH, ParallelState *pstate)
Definition: parallel.c:1059
ParallelState * ParallelBackupStart(ArchiveHandle *AH)
Definition: parallel.c:897
#define PG_BINARY_W
Definition: c.h:1276
bool EndCompressFileHandle(CompressFileHandle *CFH)
Definition: compress_io.c:289
CompressFileHandle * InitCompressFileHandle(const pg_compress_specification compression_spec)
Definition: compress_io.c:195
@ PG_COMPRESSION_NONE
Definition: compression.h:23
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
@ archModeWrite
Definition: pg_backup.h:51
@ archTar
Definition: pg_backup.h:43
@ archDirectory
Definition: pg_backup.h:45
void WriteHead(ArchiveHandle *AH)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void WriteToc(ArchiveHandle *AH)
static void setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename)
#define pg_fatal(...)
bool(* open_write_func)(const char *path, const char *mode, CompressFileHandle *CFH)
Definition: compress_io.h:122
ArchiveFormat format
DataDirSyncMethod sync_method
ParallelState * pstate
CompressFileHandle * dataFH
pg_compress_algorithm algorithm
Definition: compression.h:34

References pg_compress_specification::algorithm, archDirectory, archModeWrite, archTar, lclContext::dataFH, lclContext::directory, _archiveHandle::dosync, EndCompressFileHandle(), _archiveHandle::FH, _archiveHandle::format, _archiveHandle::formatData, if(), InitCompressFileHandle(), MAXPGPATH, _archiveHandle::mode, CompressFileHandle::open_write_func, ParallelBackupEnd(), ParallelBackupStart(), PG_BINARY_W, PG_COMPRESSION_NONE, pg_fatal, lclContext::pstate, setFilePath(), _archiveHandle::sync_method, WriteDataChunks(), WriteHead(), and WriteToc().

Referenced by InitArchiveFmt_Directory().

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 845 of file pg_backup_directory.c.

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

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Directory().

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 369 of file pg_backup_directory.c.

370 {
371  lclContext *ctx = (lclContext *) AH->formatData;
372 
373  /* Close the file */
375  pg_fatal("could not close data file: %m");
376 
377  ctx->dataFH = NULL;
378 }

References lclContext::dataFH, EndCompressFileHandle(), _archiveHandle::formatData, if(), and pg_fatal.

Referenced by InitArchiveFmt_Directory().

◆ _EndLO()

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

Definition at line 693 of file pg_backup_directory.c.

694 {
695  lclContext *ctx = (lclContext *) AH->formatData;
696  CompressFileHandle *CFH = ctx->LOsTocFH;
697  char buf[50];
698  int len;
699 
700  /* Close the BLOB data file itself */
702  pg_fatal("could not close LO data file: %m");
703  ctx->dataFH = NULL;
704 
705  /* register the LO in blobs_NNN.toc */
706  len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
707  if (!CFH->write_func(buf, len, CFH))
708  {
709  /* if write didn't set errno, assume problem is no disk space */
710  if (errno == 0)
711  errno = ENOSPC;
712  pg_fatal("could not write to LOs TOC file: %s",
713  CFH->get_error_func(CFH));
714  }
715 }
const void size_t len
static char * buf
Definition: pg_test_fsync.c:73
CompressFileHandle * LOsTocFH

References buf, lclContext::dataFH, EndCompressFileHandle(), _archiveHandle::formatData, if(), len, lclContext::LOsTocFH, pg_fatal, and snprintf.

Referenced by InitArchiveFmt_Directory().

◆ _EndLOs()

static void _EndLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 723 of file pg_backup_directory.c.

724 {
725  lclContext *ctx = (lclContext *) AH->formatData;
726 
728  pg_fatal("could not close LOs TOC file: %m");
729  ctx->LOsTocFH = NULL;
730 }

References EndCompressFileHandle(), _archiveHandle::formatData, if(), lclContext::LOsTocFH, and pg_fatal.

Referenced by InitArchiveFmt_Directory().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 434 of file pg_backup_directory.c.

435 {
436  Oid oid;
437  lclContext *ctx = (lclContext *) AH->formatData;
438  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
439  CompressFileHandle *CFH;
440  char tocfname[MAXPGPATH];
441  char line[MAXPGPATH];
442 
443  StartRestoreLOs(AH);
444 
445  /*
446  * Note: before archive v16, there was always only one BLOBS TOC entry,
447  * now there can be multiple. We don't need to worry what version we are
448  * reading though, because tctx->filename should be correct either way.
449  */
450  setFilePath(AH, tocfname, tctx->filename);
451 
452  CFH = ctx->LOsTocFH = InitDiscoverCompressFileHandle(tocfname, PG_BINARY_R);
453 
454  if (ctx->LOsTocFH == NULL)
455  pg_fatal("could not open large object TOC file \"%s\" for input: %m",
456  tocfname);
457 
458  /* Read the LOs TOC file line-by-line, and process each LO */
459  while ((CFH->gets_func(line, MAXPGPATH, CFH)) != NULL)
460  {
461  char lofname[MAXPGPATH + 1];
462  char path[MAXPGPATH];
463 
464  /* Can't overflow because line and lofname are the same length */
465  if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, lofname) != 2)
466  pg_fatal("invalid line in large object TOC file \"%s\": \"%s\"",
467  tocfname, line);
468 
469  StartRestoreLO(AH, oid, AH->public.ropt->dropSchema);
470  snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, lofname);
471  _PrintFileData(AH, path);
472  EndRestoreLO(AH, oid);
473  }
474  if (!CFH->eof_func(CFH))
475  pg_fatal("error reading large object TOC file \"%s\"",
476  tocfname);
477 
478  if (!EndCompressFileHandle(ctx->LOsTocFH))
479  pg_fatal("could not close large object TOC file \"%s\": %m",
480  tocfname);
481 
482  ctx->LOsTocFH = NULL;
483 
484  EndRestoreLOs(AH);
485 }
#define PG_BINARY_R
Definition: c.h:1275
#define CppAsString2(x)
Definition: c.h:327
CompressFileHandle * InitDiscoverCompressFileHandle(const char *path, const char *mode)
Definition: compress_io.c:241
void StartRestoreLOs(ArchiveHandle *AH)
void EndRestoreLO(ArchiveHandle *AH, Oid oid)
void EndRestoreLOs(ArchiveHandle *AH)
void StartRestoreLO(ArchiveHandle *AH, Oid oid, bool drop)
static void _PrintFileData(ArchiveHandle *AH, char *filename)
unsigned int Oid
Definition: postgres_ext.h:31
RestoreOptions * ropt
Definition: pg_backup.h:215
char *(* gets_func)(char *s, int size, CompressFileHandle *CFH)
Definition: compress_io.h:152
bool(* eof_func)(CompressFileHandle *CFH)
Definition: compress_io.h:168

References _PrintFileData(), CppAsString2, lclContext::directory, _restoreOptions::dropSchema, EndCompressFileHandle(), EndRestoreLO(), EndRestoreLOs(), CompressFileHandle::eof_func, _archiveHandle::formatData, _tocEntry::formatData, CompressFileHandle::gets_func, InitDiscoverCompressFileHandle(), lclContext::LOsTocFH, MAXPGPATH, PG_BINARY_R, pg_fatal, _archiveHandle::public, Archive::ropt, setFilePath(), snprintf, StartRestoreLO(), and StartRestoreLOs().

Referenced by _PrintTocData().

◆ _PrepParallelRestore()

static void _PrepParallelRestore ( ArchiveHandle AH)
static

Definition at line 765 of file pg_backup_directory.c.

766 {
767  TocEntry *te;
768 
769  for (te = AH->toc->next; te != AH->toc; te = te->next)
770  {
771  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
772  char fname[MAXPGPATH];
773  struct stat st;
774 
775  /*
776  * A dumpable object has set tctx->filename, any other object has not.
777  * (see _ArchiveEntry).
778  */
779  if (tctx->filename == NULL)
780  continue;
781 
782  /* We may ignore items not due to be restored */
783  if ((te->reqs & REQ_DATA) == 0)
784  continue;
785 
786  /*
787  * Stat the file and, if successful, put its size in dataLength. When
788  * using compression, the physical file size might not be a very good
789  * guide to the amount of work involved in restoring the file, but we
790  * only need an approximate indicator of that.
791  */
792  setFilePath(AH, fname, tctx->filename);
793 
794  if (stat(fname, &st) == 0)
795  te->dataLength = st.st_size;
797  {
799  strlcat(fname, ".gz", sizeof(fname));
801  strlcat(fname, ".lz4", sizeof(fname));
803  strlcat(fname, ".zst", sizeof(fname));
804 
805  if (stat(fname, &st) == 0)
806  te->dataLength = st.st_size;
807  }
808 
809  /*
810  * If this is a BLOBS entry, what we stat'd was blobs_NNN.toc, which
811  * most likely is a lot smaller than the actual blob data. We don't
812  * have a cheap way to estimate how much smaller, but fortunately it
813  * doesn't matter too much as long as we get the LOs processed
814  * reasonably early. Arbitrarily scale up by a factor of 1K.
815  */
816  if (strcmp(te->desc, "BLOBS") == 0)
817  te->dataLength *= 1024;
818  }
819 }
@ PG_COMPRESSION_GZIP
Definition: compression.h:24
@ PG_COMPRESSION_LZ4
Definition: compression.h:25
@ PG_COMPRESSION_ZSTD
Definition: compression.h:26
#define REQ_DATA
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
struct _tocEntry * toc
pg_compress_specification compression_spec
pgoff_t dataLength
struct _tocEntry * next
#define stat
Definition: win32_port.h:284

References pg_compress_specification::algorithm, _archiveHandle::compression_spec, _tocEntry::dataLength, _tocEntry::desc, lclTocEntry::filename, _tocEntry::formatData, if(), MAXPGPATH, _tocEntry::next, PG_COMPRESSION_GZIP, PG_COMPRESSION_LZ4, PG_COMPRESSION_NONE, PG_COMPRESSION_ZSTD, REQ_DATA, _tocEntry::reqs, setFilePath(), stat, strlcat(), and _archiveHandle::toc.

Referenced by InitArchiveFmt_Directory().

◆ _PrintExtraToc()

static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 304 of file pg_backup_directory.c.

305 {
306  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
307 
308  if (AH->public.verbose && tctx->filename)
309  ahprintf(AH, "-- File: %s\n", tctx->filename);
310 }
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
int verbose
Definition: pg_backup.h:217

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

Referenced by InitArchiveFmt_Directory().

◆ _PrintFileData()

static void _PrintFileData ( ArchiveHandle AH,
char *  filename 
)
static

Definition at line 384 of file pg_backup_directory.c.

385 {
386  size_t cnt = 0;
387  char *buf;
388  size_t buflen;
389  CompressFileHandle *CFH;
390 
391  if (!filename)
392  return;
393 
395  if (!CFH)
396  pg_fatal("could not open input file \"%s\": %m", filename);
397 
398  buflen = DEFAULT_IO_BUFFER_SIZE;
399  buf = pg_malloc(buflen);
400 
401  while (CFH->read_func(buf, buflen, &cnt, CFH) && cnt > 0)
402  {
403  ahwrite(buf, 1, cnt, AH);
404  }
405 
406  free(buf);
407  if (!EndCompressFileHandle(CFH))
408  pg_fatal("could not close data file \"%s\": %m", filename);
409 }
#define DEFAULT_IO_BUFFER_SIZE
Definition: compress_io.h:27
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static char * filename
Definition: pg_dumpall.c:119
bool(* read_func)(void *ptr, size_t size, size_t *rsize, CompressFileHandle *CFH)
Definition: compress_io.h:131

References ahwrite(), buf, DEFAULT_IO_BUFFER_SIZE, EndCompressFileHandle(), filename, free, InitDiscoverCompressFileHandle(), PG_BINARY_R, pg_fatal, pg_malloc(), and CompressFileHandle::read_func.

Referenced by _LoadLOs(), and _PrintTocData().

◆ _PrintTocData()

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 415 of file pg_backup_directory.c.

416 {
417  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
418 
419  if (!tctx->filename)
420  return;
421 
422  if (strcmp(te->desc, "BLOBS") == 0)
423  _LoadLOs(AH, te);
424  else
425  {
426  char fname[MAXPGPATH];
427 
428  setFilePath(AH, fname, tctx->filename);
429  _PrintFileData(AH, fname);
430  }
431 }
static void _LoadLOs(ArchiveHandle *AH, TocEntry *te)

References _LoadLOs(), _PrintFileData(), _tocEntry::desc, lclTocEntry::filename, _tocEntry::formatData, if(), MAXPGPATH, and setFilePath().

Referenced by InitArchiveFmt_Directory().

◆ _ReadBuf()

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

Definition at line 555 of file pg_backup_directory.c.

556 {
557  lclContext *ctx = (lclContext *) AH->formatData;
558  CompressFileHandle *CFH = ctx->dataFH;
559 
560  /*
561  * If there was an I/O error, we already exited in readF(), so here we
562  * exit on short reads.
563  */
564  if (!CFH->read_func(buf, len, NULL, CFH))
565  pg_fatal("could not read from input file: end of file");
566 }

References buf, lclContext::dataFH, _archiveHandle::formatData, if(), len, and pg_fatal.

Referenced by InitArchiveFmt_Directory().

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 520 of file pg_backup_directory.c.

521 {
522  lclContext *ctx = (lclContext *) AH->formatData;
523  CompressFileHandle *CFH = ctx->dataFH;
524 
525  return CFH->getc_func(CFH);
526 }
int(* getc_func)(CompressFileHandle *CFH)
Definition: compress_io.h:161

References lclContext::dataFH, _archiveHandle::formatData, and CompressFileHandle::getc_func.

Referenced by InitArchiveFmt_Directory().

◆ _ReadExtraToc()

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 281 of file pg_backup_directory.c.

282 {
283  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
284 
285  if (tctx == NULL)
286  {
287  tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
288  te->formatData = (void *) tctx;
289  }
290 
291  tctx->filename = ReadStr(AH);
292  if (strlen(tctx->filename) == 0)
293  {
294  free(tctx->filename);
295  tctx->filename = NULL;
296  }
297 }
char * ReadStr(ArchiveHandle *AH)

References lclTocEntry::filename, _tocEntry::formatData, free, if(), pg_malloc0(), and ReadStr().

Referenced by InitArchiveFmt_Directory().

◆ _ReopenArchive()

static void _ReopenArchive ( ArchiveHandle AH)
static

Definition at line 632 of file pg_backup_directory.c.

633 {
634  /*
635  * Our TOC is in memory, our data files are opened by each child anyway as
636  * they are separate. We support reopening the archive by just doing
637  * nothing.
638  */
639 }

Referenced by InitArchiveFmt_Directory().

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 322 of file pg_backup_directory.c.

323 {
324  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
325  lclContext *ctx = (lclContext *) AH->formatData;
326  char fname[MAXPGPATH];
327 
328  setFilePath(AH, fname, tctx->filename);
329 
330  ctx->dataFH = InitCompressFileHandle(AH->compression_spec);
331 
332  if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
333  pg_fatal("could not open output file \"%s\": %m", fname);
334 }

References _archiveHandle::compression_spec, lclTocEntry::filename, _archiveHandle::formatData, _tocEntry::formatData, InitCompressFileHandle(), MAXPGPATH, PG_BINARY_W, pg_fatal, and setFilePath().

Referenced by InitArchiveFmt_Directory().

◆ _StartLO()

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

Definition at line 675 of file pg_backup_directory.c.

676 {
677  lclContext *ctx = (lclContext *) AH->formatData;
678  char fname[MAXPGPATH];
679 
680  snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
681 
683  if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
684  pg_fatal("could not open output file \"%s\": %m", fname);
685 }

References _archiveHandle::compression_spec, lclContext::dataFH, lclContext::directory, _archiveHandle::formatData, InitCompressFileHandle(), MAXPGPATH, CompressFileHandle::open_write_func, PG_BINARY_W, pg_fatal, and snprintf.

Referenced by InitArchiveFmt_Directory().

◆ _StartLOs()

static void _StartLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 653 of file pg_backup_directory.c.

654 {
655  lclContext *ctx = (lclContext *) AH->formatData;
656  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
657  pg_compress_specification compression_spec = {0};
658  char fname[MAXPGPATH];
659 
660  setFilePath(AH, fname, tctx->filename);
661 
662  /* The LO TOC file is never compressed */
663  compression_spec.algorithm = PG_COMPRESSION_NONE;
664  ctx->LOsTocFH = InitCompressFileHandle(compression_spec);
665  if (!ctx->LOsTocFH->open_write_func(fname, "ab", ctx->LOsTocFH))
666  pg_fatal("could not open output file \"%s\": %m", fname);
667 }

References pg_compress_specification::algorithm, _archiveHandle::formatData, _tocEntry::formatData, InitCompressFileHandle(), lclContext::LOsTocFH, MAXPGPATH, CompressFileHandle::open_write_func, PG_COMPRESSION_NONE, pg_fatal, and setFilePath().

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobDumpDirectory()

static int _WorkerJobDumpDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 857 of file pg_backup_directory.c.

858 {
859  /*
860  * This function returns void. We either fail and die horribly or
861  * succeed... A failure will be detected by the parent when the child dies
862  * unexpectedly.
863  */
865 
866  return 0;
867 }
void WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te)

References WriteDataChunksForTocEntry().

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobRestoreDirectory()

static int _WorkerJobRestoreDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 874 of file pg_backup_directory.c.

875 {
876  return parallel_restore(AH, te);
877 }
int parallel_restore(ArchiveHandle *AH, TocEntry *te)

References parallel_restore().

Referenced by InitArchiveFmt_Directory().

◆ _WriteBuf()

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

Definition at line 533 of file pg_backup_directory.c.

534 {
535  lclContext *ctx = (lclContext *) AH->formatData;
536  CompressFileHandle *CFH = ctx->dataFH;
537 
538  errno = 0;
539  if (!CFH->write_func(buf, len, CFH))
540  {
541  /* if write didn't set errno, assume problem is no disk space */
542  if (errno == 0)
543  errno = ENOSPC;
544  pg_fatal("could not write to output file: %s",
545  CFH->get_error_func(CFH));
546  }
547 }

References buf, lclContext::dataFH, _archiveHandle::formatData, if(), len, and pg_fatal.

Referenced by InitArchiveFmt_Directory().

◆ _WriteByte()

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

Definition at line 494 of file pg_backup_directory.c.

495 {
496  unsigned char c = (unsigned char) i;
497  lclContext *ctx = (lclContext *) AH->formatData;
498  CompressFileHandle *CFH = ctx->dataFH;
499 
500  errno = 0;
501  if (!CFH->write_func(&c, 1, CFH))
502  {
503  /* if write didn't set errno, assume problem is no disk space */
504  if (errno == 0)
505  errno = ENOSPC;
506  pg_fatal("could not write to output file: %s",
507  CFH->get_error_func(CFH));
508  }
509 
510  return 1;
511 }
int i
Definition: isn.c:73
char * c

References lclContext::dataFH, _archiveHandle::formatData, i, if(), and pg_fatal.

Referenced by InitArchiveFmt_Directory().

◆ _WriteData()

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

Definition at line 346 of file pg_backup_directory.c.

347 {
348  lclContext *ctx = (lclContext *) AH->formatData;
349  CompressFileHandle *CFH = ctx->dataFH;
350 
351  errno = 0;
352  if (dLen > 0 && !CFH->write_func(data, dLen, CFH))
353  {
354  /* if write didn't set errno, assume problem is no disk space */
355  if (errno == 0)
356  errno = ENOSPC;
357  pg_fatal("could not write to output file: %s",
358  CFH->get_error_func(CFH));
359  }
360 }
const void * data

References data, lclContext::dataFH, _archiveHandle::formatData, if(), and pg_fatal.

Referenced by InitArchiveFmt_Directory().

◆ _WriteExtraToc()

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 260 of file pg_backup_directory.c.

261 {
262  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
263 
264  /*
265  * A dumpable object has set tctx->filename, any other object has not.
266  * (see _ArchiveEntry).
267  */
268  if (tctx->filename)
269  WriteStr(AH, tctx->filename);
270  else
271  WriteStr(AH, "");
272 }
size_t WriteStr(ArchiveHandle *AH, const char *c)

References lclTocEntry::filename, _tocEntry::formatData, if(), and WriteStr().

Referenced by InitArchiveFmt_Directory().

◆ InitArchiveFmt_Directory()

void InitArchiveFmt_Directory ( ArchiveHandle AH)

Definition at line 109 of file pg_backup_directory.c.

110 {
111  lclContext *ctx;
112 
113  /* Assuming static functions, this can be copied for each format. */
115  AH->StartDataPtr = _StartData;
116  AH->WriteDataPtr = _WriteData;
117  AH->EndDataPtr = _EndData;
118  AH->WriteBytePtr = _WriteByte;
119  AH->ReadBytePtr = _ReadByte;
120  AH->WriteBufPtr = _WriteBuf;
121  AH->ReadBufPtr = _ReadBuf;
122  AH->ClosePtr = _CloseArchive;
128 
129  AH->StartLOsPtr = _StartLOs;
130  AH->StartLOPtr = _StartLO;
131  AH->EndLOPtr = _EndLO;
132  AH->EndLOsPtr = _EndLOs;
133 
135  AH->ClonePtr = _Clone;
136  AH->DeClonePtr = _DeClone;
137 
140 
141  /* Set up our private context */
142  ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
143  AH->formatData = (void *) ctx;
144 
145  ctx->dataFH = NULL;
146  ctx->LOsTocFH = NULL;
147 
148  /*
149  * Now open the TOC file
150  */
151 
152  if (!AH->fSpec || strcmp(AH->fSpec, "") == 0)
153  pg_fatal("no output directory specified");
154 
155  ctx->directory = AH->fSpec;
156 
157  if (AH->mode == archModeWrite)
158  {
159  struct stat st;
160  bool is_empty = false;
161 
162  /* we accept an empty existing directory */
163  if (stat(ctx->directory, &st) == 0 && S_ISDIR(st.st_mode))
164  {
165  DIR *dir = opendir(ctx->directory);
166 
167  if (dir)
168  {
169  struct dirent *d;
170 
171  is_empty = true;
172  while (errno = 0, (d = readdir(dir)))
173  {
174  if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0)
175  {
176  is_empty = false;
177  break;
178  }
179  }
180 
181  if (errno)
182  pg_fatal("could not read directory \"%s\": %m",
183  ctx->directory);
184 
185  if (closedir(dir))
186  pg_fatal("could not close directory \"%s\": %m",
187  ctx->directory);
188  }
189  }
190 
191  if (!is_empty && mkdir(ctx->directory, 0700) < 0)
192  pg_fatal("could not create directory \"%s\": %m",
193  ctx->directory);
194  }
195  else
196  { /* Read Mode */
197  char fname[MAXPGPATH];
198  CompressFileHandle *tocFH;
199 
200  setFilePath(AH, fname, "toc.dat");
201 
203  if (tocFH == NULL)
204  pg_fatal("could not open input file \"%s\": %m", fname);
205 
206  ctx->dataFH = tocFH;
207 
208  /*
209  * The TOC of a directory format dump shares the format code of the
210  * tar format.
211  */
212  AH->format = archTar;
213  ReadHead(AH);
214  AH->format = archDirectory;
215  ReadToc(AH);
216 
217  /* Nothing else in the file, so close it again... */
218  if (!EndCompressFileHandle(tocFH))
219  pg_fatal("could not close TOC file: %m");
220  ctx->dataFH = NULL;
221  }
222 }
int closedir(DIR *)
Definition: dirent.c:127
struct dirent * readdir(DIR *)
Definition: dirent.c:78
DIR * opendir(const char *)
Definition: dirent.c:33
void ReadHead(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
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 int _WriteByte(ArchiveHandle *AH, const int i)
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 _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _Clone(ArchiveHandle *AH)
static int _WorkerJobRestoreDirectory(ArchiveHandle *AH, TocEntry *te)
static int _WorkerJobDumpDirectory(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
Definition: dirent.c:26
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
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
#define S_ISDIR(m)
Definition: win32_port.h:325
#define mkdir(a, b)
Definition: win32_port.h:80

References _ArchiveEntry(), _Clone(), _CloseArchive(), _DeClone(), _EndData(), _EndLO(), _EndLOs(), _PrepParallelRestore(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _ReopenArchive(), _StartData(), _StartLO(), _StartLOs(), _WorkerJobDumpDirectory(), _WorkerJobRestoreDirectory(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), archDirectory, _archiveHandle::ArchiveEntryPtr, archModeWrite, archTar, _archiveHandle::ClonePtr, closedir(), _archiveHandle::ClosePtr, dirent::d_name, lclContext::dataFH, _archiveHandle::DeClonePtr, lclContext::directory, EndCompressFileHandle(), _archiveHandle::EndDataPtr, _archiveHandle::EndLOPtr, _archiveHandle::EndLOsPtr, _archiveHandle::format, _archiveHandle::formatData, _archiveHandle::fSpec, InitDiscoverCompressFileHandle(), lclContext::LOsTocFH, MAXPGPATH, mkdir, _archiveHandle::mode, opendir(), PG_BINARY_R, pg_fatal, pg_malloc0(), _archiveHandle::PrepParallelRestorePtr, _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, readdir(), _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, S_ISDIR, setFilePath(), stat::st_mode, _archiveHandle::StartDataPtr, _archiveHandle::StartLOPtr, _archiveHandle::StartLOsPtr, stat, _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.

Referenced by _allocAH().

◆ setFilePath()

static void setFilePath ( ArchiveHandle AH,
char *  buf,
const char *  relativeFilename 
)
static

Definition at line 739 of file pg_backup_directory.c.

740 {
741  lclContext *ctx = (lclContext *) AH->formatData;
742  char *dname;
743 
744  dname = ctx->directory;
745 
746  if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
747  pg_fatal("file name too long: \"%s\"", dname);
748 
749  strcpy(buf, dname);
750  strcat(buf, "/");
751  strcat(buf, relativeFilename);
752 }

References buf, lclContext::directory, _archiveHandle::formatData, if(), MAXPGPATH, and pg_fatal.

Referenced by _CloseArchive(), _LoadLOs(), _PrepParallelRestore(), _PrintTocData(), _StartData(), _StartLOs(), and InitArchiveFmt_Directory().