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)
 
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 232 of file pg_backup_directory.c.

233 {
234  lclTocEntry *tctx;
235  char fn[MAXPGPATH];
236 
237  tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
238  if (strcmp(te->desc, "BLOBS") == 0)
239  tctx->filename = pg_strdup("blobs.toc");
240  else if (te->dataDumper)
241  {
242  snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId);
243  tctx->filename = pg_strdup(fn);
244  }
245  else
246  tctx->filename = NULL;
247 
248  te->formatData = (void *) tctx;
249 }
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 817 of file pg_backup_directory.c.

818 {
819  lclContext *ctx = (lclContext *) AH->formatData;
820 
821  AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
822  memcpy(AH->formatData, ctx, sizeof(lclContext));
823  ctx = (lclContext *) AH->formatData;
824 
825  /*
826  * Note: we do not make a local lo_buf because we expect at most one BLOBS
827  * entry per archive, so no parallelism is possible. Likewise,
828  * TOC-entry-local state isn't an issue because any one TOC entry is
829  * touched by just one worker child.
830  */
831 
832  /*
833  * We also don't copy the ParallelState pointer (pstate), only the leader
834  * process ever writes to it.
835  */
836 }
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 574 of file pg_backup_directory.c.

575 {
576  lclContext *ctx = (lclContext *) AH->formatData;
577 
578  if (AH->mode == archModeWrite)
579  {
580  CompressFileHandle *tocFH;
581  pg_compress_specification compression_spec = {0};
582  char fname[MAXPGPATH];
583 
584  setFilePath(AH, fname, "toc.dat");
585 
586  /* this will actually fork the processes for a parallel backup */
587  ctx->pstate = ParallelBackupStart(AH);
588 
589  /* The TOC is always created uncompressed */
590  compression_spec.algorithm = PG_COMPRESSION_NONE;
591  tocFH = InitCompressFileHandle(compression_spec);
592  if (!tocFH->open_write_func(fname, PG_BINARY_W, tocFH))
593  pg_fatal("could not open output file \"%s\": %m", fname);
594  ctx->dataFH = tocFH;
595 
596  /*
597  * Write 'tar' in the format field of the toc.dat file. The directory
598  * is compatible with 'tar', so there's no point having a different
599  * format code for it.
600  */
601  AH->format = archTar;
602  WriteHead(AH);
603  AH->format = archDirectory;
604  WriteToc(AH);
605  if (!EndCompressFileHandle(tocFH))
606  pg_fatal("could not close TOC file: %m");
607  WriteDataChunks(AH, ctx->pstate);
608 
609  ParallelBackupEnd(AH, ctx->pstate);
610 
611  /*
612  * In directory mode, there is no need to sync all the entries
613  * individually. Just recurse once through all the files generated.
614  */
615  if (AH->dosync)
616  sync_dir_recurse(ctx->directory, AH->sync_method);
617  }
618  AH->FH = NULL;
619 }
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:1265
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 839 of file pg_backup_directory.c.

840 {
841  lclContext *ctx = (lclContext *) AH->formatData;
842 
843  free(ctx);
844 }
#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 368 of file pg_backup_directory.c.

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

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 685 of file pg_backup_directory.c.

686 {
687  lclContext *ctx = (lclContext *) AH->formatData;
688  CompressFileHandle *CFH = ctx->LOsTocFH;
689  char buf[50];
690  int len;
691 
692  /* Close the BLOB data file itself */
694  pg_fatal("could not close LO data file: %m");
695  ctx->dataFH = NULL;
696 
697  /* register the LO in blobs.toc */
698  len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
699  if (!CFH->write_func(buf, len, CFH))
700  {
701  /* if write didn't set errno, assume problem is no disk space */
702  if (errno == 0)
703  errno = ENOSPC;
704  pg_fatal("could not write to LOs TOC file: %s",
705  CFH->get_error_func(CFH));
706  }
707 }
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 715 of file pg_backup_directory.c.

716 {
717  lclContext *ctx = (lclContext *) AH->formatData;
718 
720  pg_fatal("could not close LOs TOC file: %m");
721  ctx->LOsTocFH = NULL;
722 }

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

Referenced by InitArchiveFmt_Directory().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH)
static

Definition at line 433 of file pg_backup_directory.c.

434 {
435  Oid oid;
436  lclContext *ctx = (lclContext *) AH->formatData;
437  CompressFileHandle *CFH;
438  char tocfname[MAXPGPATH];
439  char line[MAXPGPATH];
440 
441  StartRestoreLOs(AH);
442 
443  setFilePath(AH, tocfname, "blobs.toc");
444 
445  CFH = ctx->LOsTocFH = InitDiscoverCompressFileHandle(tocfname, PG_BINARY_R);
446 
447  if (ctx->LOsTocFH == NULL)
448  pg_fatal("could not open large object TOC file \"%s\" for input: %m",
449  tocfname);
450 
451  /* Read the LOs TOC file line-by-line, and process each LO */
452  while ((CFH->gets_func(line, MAXPGPATH, CFH)) != NULL)
453  {
454  char lofname[MAXPGPATH + 1];
455  char path[MAXPGPATH];
456 
457  /* Can't overflow because line and lofname are the same length */
458  if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, lofname) != 2)
459  pg_fatal("invalid line in large object TOC file \"%s\": \"%s\"",
460  tocfname, line);
461 
462  StartRestoreLO(AH, oid, AH->public.ropt->dropSchema);
463  snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, lofname);
464  _PrintFileData(AH, path);
465  EndRestoreLO(AH, oid);
466  }
467  if (!CFH->eof_func(CFH))
468  pg_fatal("error reading large object TOC file \"%s\"",
469  tocfname);
470 
471  if (!EndCompressFileHandle(ctx->LOsTocFH))
472  pg_fatal("could not close large object TOC file \"%s\": %m",
473  tocfname);
474 
475  ctx->LOsTocFH = NULL;
476 
477  EndRestoreLOs(AH);
478 }
#define PG_BINARY_R
Definition: c.h:1264
#define CppAsString2(x)
Definition: c.h:316
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:213

References _PrintFileData(), CppAsString2, lclContext::directory, _restoreOptions::dropSchema, EndCompressFileHandle(), EndRestoreLO(), EndRestoreLOs(), _archiveHandle::formatData, 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 757 of file pg_backup_directory.c.

758 {
759  TocEntry *te;
760 
761  for (te = AH->toc->next; te != AH->toc; te = te->next)
762  {
763  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
764  char fname[MAXPGPATH];
765  struct stat st;
766 
767  /*
768  * A dumpable object has set tctx->filename, any other object has not.
769  * (see _ArchiveEntry).
770  */
771  if (tctx->filename == NULL)
772  continue;
773 
774  /* We may ignore items not due to be restored */
775  if ((te->reqs & REQ_DATA) == 0)
776  continue;
777 
778  /*
779  * Stat the file and, if successful, put its size in dataLength. When
780  * using compression, the physical file size might not be a very good
781  * guide to the amount of work involved in restoring the file, but we
782  * only need an approximate indicator of that.
783  */
784  setFilePath(AH, fname, tctx->filename);
785 
786  if (stat(fname, &st) == 0)
787  te->dataLength = st.st_size;
789  {
791  strlcat(fname, ".gz", sizeof(fname));
793  strlcat(fname, ".lz4", sizeof(fname));
795  strlcat(fname, ".zst", sizeof(fname));
796 
797  if (stat(fname, &st) == 0)
798  te->dataLength = st.st_size;
799  }
800 
801  /*
802  * If this is the BLOBS entry, what we stat'd was blobs.toc, which
803  * most likely is a lot smaller than the actual blob data. We don't
804  * have a cheap way to estimate how much smaller, but fortunately it
805  * doesn't matter too much as long as we get the LOs processed
806  * reasonably early. Arbitrarily scale up by a factor of 1K.
807  */
808  if (strcmp(te->desc, "BLOBS") == 0)
809  te->dataLength *= 1024;
810  }
811 }
@ 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 303 of file pg_backup_directory.c.

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

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 383 of file pg_backup_directory.c.

384 {
385  size_t cnt = 0;
386  char *buf;
387  size_t buflen;
388  CompressFileHandle *CFH;
389 
390  if (!filename)
391  return;
392 
394  if (!CFH)
395  pg_fatal("could not open input file \"%s\": %m", filename);
396 
397  buflen = DEFAULT_IO_BUFFER_SIZE;
398  buf = pg_malloc(buflen);
399 
400  while (CFH->read_func(buf, buflen, &cnt, CFH) && cnt > 0)
401  {
402  ahwrite(buf, 1, cnt, AH);
403  }
404 
405  free(buf);
406  if (!EndCompressFileHandle(CFH))
407  pg_fatal("could not close data file \"%s\": %m", filename);
408 }
#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:121
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 414 of file pg_backup_directory.c.

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

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 548 of file pg_backup_directory.c.

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

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 513 of file pg_backup_directory.c.

514 {
515  lclContext *ctx = (lclContext *) AH->formatData;
516  CompressFileHandle *CFH = ctx->dataFH;
517 
518  return CFH->getc_func(CFH);
519 }
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 280 of file pg_backup_directory.c.

281 {
282  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
283 
284  if (tctx == NULL)
285  {
286  tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
287  te->formatData = (void *) tctx;
288  }
289 
290  tctx->filename = ReadStr(AH);
291  if (strlen(tctx->filename) == 0)
292  {
293  free(tctx->filename);
294  tctx->filename = NULL;
295  }
296 }
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 625 of file pg_backup_directory.c.

626 {
627  /*
628  * Our TOC is in memory, our data files are opened by each child anyway as
629  * they are separate. We support reopening the archive by just doing
630  * nothing.
631  */
632 }

Referenced by InitArchiveFmt_Directory().

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 321 of file pg_backup_directory.c.

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

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 667 of file pg_backup_directory.c.

668 {
669  lclContext *ctx = (lclContext *) AH->formatData;
670  char fname[MAXPGPATH];
671 
672  snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
673 
675  if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
676  pg_fatal("could not open output file \"%s\": %m", fname);
677 }

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 646 of file pg_backup_directory.c.

647 {
648  lclContext *ctx = (lclContext *) AH->formatData;
649  pg_compress_specification compression_spec = {0};
650  char fname[MAXPGPATH];
651 
652  setFilePath(AH, fname, "blobs.toc");
653 
654  /* The LO TOC file is never compressed */
655  compression_spec.algorithm = PG_COMPRESSION_NONE;
656  ctx->LOsTocFH = InitCompressFileHandle(compression_spec);
657  if (!ctx->LOsTocFH->open_write_func(fname, "ab", ctx->LOsTocFH))
658  pg_fatal("could not open output file \"%s\": %m", fname);
659 }

References _archiveHandle::formatData.

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobDumpDirectory()

static int _WorkerJobDumpDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 851 of file pg_backup_directory.c.

852 {
853  /*
854  * This function returns void. We either fail and die horribly or
855  * succeed... A failure will be detected by the parent when the child dies
856  * unexpectedly.
857  */
859 
860  return 0;
861 }
void WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te)

References WriteDataChunksForTocEntry().

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobRestoreDirectory()

static int _WorkerJobRestoreDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 868 of file pg_backup_directory.c.

869 {
870  return parallel_restore(AH, te);
871 }
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 526 of file pg_backup_directory.c.

527 {
528  lclContext *ctx = (lclContext *) AH->formatData;
529  CompressFileHandle *CFH = ctx->dataFH;
530 
531  errno = 0;
532  if (!CFH->write_func(buf, len, CFH))
533  {
534  /* if write didn't set errno, assume problem is no disk space */
535  if (errno == 0)
536  errno = ENOSPC;
537  pg_fatal("could not write to output file: %s",
538  CFH->get_error_func(CFH));
539  }
540 }

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 487 of file pg_backup_directory.c.

488 {
489  unsigned char c = (unsigned char) i;
490  lclContext *ctx = (lclContext *) AH->formatData;
491  CompressFileHandle *CFH = ctx->dataFH;
492 
493  errno = 0;
494  if (!CFH->write_func(&c, 1, CFH))
495  {
496  /* if write didn't set errno, assume problem is no disk space */
497  if (errno == 0)
498  errno = ENOSPC;
499  pg_fatal("could not write to output file: %s",
500  CFH->get_error_func(CFH));
501  }
502 
503  return 1;
504 }
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 345 of file pg_backup_directory.c.

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

260 {
261  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
262 
263  /*
264  * A dumpable object has set tctx->filename, any other object has not.
265  * (see _ArchiveEntry).
266  */
267  if (tctx->filename)
268  WriteStr(AH, tctx->filename);
269  else
270  WriteStr(AH, "");
271 }
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 107 of file pg_backup_directory.c.

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

732 {
733  lclContext *ctx = (lclContext *) AH->formatData;
734  char *dname;
735 
736  dname = ctx->directory;
737 
738  if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
739  pg_fatal("file name too long: \"%s\"", dname);
740 
741  strcpy(buf, dname);
742  strcat(buf, "/");
743  strcat(buf, relativeFilename);
744 }

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

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