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

234 {
235  lclTocEntry *tctx;
236  char fn[MAXPGPATH];
237 
238  tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
239  if (strcmp(te->desc, "BLOBS") == 0)
240  tctx->filename = pg_strdup("blobs.toc");
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)

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

803 {
804  lclContext *ctx = (lclContext *) AH->formatData;
805 
806  AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
807  memcpy(AH->formatData, ctx, sizeof(lclContext));
808  ctx = (lclContext *) AH->formatData;
809 
810  /*
811  * Note: we do not make a local lo_buf because we expect at most one BLOBS
812  * entry per archive, so no parallelism is possible. Likewise,
813  * TOC-entry-local state isn't an issue because any one TOC entry is
814  * touched by just one worker child.
815  */
816 
817  /*
818  * We also don't copy the ParallelState pointer (pstate), only the leader
819  * process ever writes to it.
820  */
821 }
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 570 of file pg_backup_directory.c.

571 {
572  lclContext *ctx = (lclContext *) AH->formatData;
573 
574  if (AH->mode == archModeWrite)
575  {
576  cfp *tocFH;
577  pg_compress_specification compression_spec = {0};
578  char fname[MAXPGPATH];
579 
580  setFilePath(AH, fname, "toc.dat");
581 
582  /* this will actually fork the processes for a parallel backup */
583  ctx->pstate = ParallelBackupStart(AH);
584 
585  /* The TOC is always created uncompressed */
586  compression_spec.algorithm = PG_COMPRESSION_NONE;
587  tocFH = cfopen_write(fname, PG_BINARY_W, compression_spec);
588  if (tocFH == NULL)
589  pg_fatal("could not open output file \"%s\": %m", fname);
590  ctx->dataFH = tocFH;
591 
592  /*
593  * Write 'tar' in the format field of the toc.dat file. The directory
594  * is compatible with 'tar', so there's no point having a different
595  * format code for it.
596  */
597  AH->format = archTar;
598  WriteHead(AH);
599  AH->format = archDirectory;
600  WriteToc(AH);
601  if (cfclose(tocFH) != 0)
602  pg_fatal("could not close TOC file: %m");
603  WriteDataChunks(AH, ctx->pstate);
604 
605  ParallelBackupEnd(AH, ctx->pstate);
606 
607  /*
608  * In directory mode, there is no need to sync all the entries
609  * individually. Just recurse once through all the files generated.
610  */
611  if (AH->dosync)
612  fsync_dir_recurse(ctx->directory);
613  }
614  AH->FH = NULL;
615 }
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:1212
int cfclose(cfp *fp)
Definition: compress_io.c:631
cfp * cfopen_write(const char *path, const char *mode, const pg_compress_specification compression_spec)
Definition: compress_io.c:469
@ PG_COMPRESSION_NONE
Definition: compression.h:19
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
@ archModeWrite
Definition: pg_backup.h:50
@ archTar
Definition: pg_backup.h:42
@ archDirectory
Definition: pg_backup.h:44
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(...)
ArchiveFormat format
ParallelState * pstate
pg_compress_algorithm algorithm
Definition: compression.h:29

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

Referenced by InitArchiveFmt_Directory().

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 824 of file pg_backup_directory.c.

825 {
826  lclContext *ctx = (lclContext *) AH->formatData;
827 
828  free(ctx);
829 }
#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 */
373  if (cfclose(ctx->dataFH) != 0)
374  pg_fatal("could not close data file: %m");
375 
376  ctx->dataFH = NULL;
377 }

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

Referenced by InitArchiveFmt_Directory().

◆ _EndLO()

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

Definition at line 682 of file pg_backup_directory.c.

683 {
684  lclContext *ctx = (lclContext *) AH->formatData;
685  char buf[50];
686  int len;
687 
688  /* Close the LO data file itself */
689  if (cfclose(ctx->dataFH) != 0)
690  pg_fatal("could not close LO data file: %m");
691  ctx->dataFH = NULL;
692 
693  /* register the LO in blobs.toc */
694  len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
695  if (cfwrite(buf, len, ctx->LOsTocFH) != len)
696  pg_fatal("could not write to LOs TOC file");
697 }
int cfwrite(const void *ptr, int size, cfp *fp)
Definition: compress_io.c:581
const void size_t len
static char * buf
Definition: pg_test_fsync.c:67

References buf, cfclose(), cfwrite(), lclContext::dataFH, _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 705 of file pg_backup_directory.c.

706 {
707  lclContext *ctx = (lclContext *) AH->formatData;
708 
709  if (cfclose(ctx->LOsTocFH) != 0)
710  pg_fatal("could not close LOs TOC file: %m");
711  ctx->LOsTocFH = NULL;
712 }

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

Referenced by InitArchiveFmt_Directory().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH)
static

Definition at line 434 of file pg_backup_directory.c.

435 {
436  Oid oid;
437  lclContext *ctx = (lclContext *) AH->formatData;
438  char tocfname[MAXPGPATH];
439  char line[MAXPGPATH];
440 
441  StartRestoreLOs(AH);
442 
443  setFilePath(AH, tocfname, "blobs.toc");
444 
445  ctx->LOsTocFH = cfopen_read(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 ((cfgets(ctx->LOsTocFH, line, MAXPGPATH)) != 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 (!cfeof(ctx->LOsTocFH))
468  pg_fatal("error reading large object TOC file \"%s\"",
469  tocfname);
470 
471  if (cfclose(ctx->LOsTocFH) != 0)
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:1211
#define CppAsString2(x)
Definition: c.h:311
char * cfgets(cfp *fp, char *buf, int len)
Definition: compress_io.c:620
cfp * cfopen_read(const char *path, const char *mode)
Definition: compress_io.c:425
int cfeof(cfp *fp)
Definition: compress_io.c:658
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:212

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

748 {
749  TocEntry *te;
750 
751  for (te = AH->toc->next; te != AH->toc; te = te->next)
752  {
753  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
754  char fname[MAXPGPATH];
755  struct stat st;
756 
757  /*
758  * A dumpable object has set tctx->filename, any other object has not.
759  * (see _ArchiveEntry).
760  */
761  if (tctx->filename == NULL)
762  continue;
763 
764  /* We may ignore items not due to be restored */
765  if ((te->reqs & REQ_DATA) == 0)
766  continue;
767 
768  /*
769  * Stat the file and, if successful, put its size in dataLength. When
770  * using compression, the physical file size might not be a very good
771  * guide to the amount of work involved in restoring the file, but we
772  * only need an approximate indicator of that.
773  */
774  setFilePath(AH, fname, tctx->filename);
775 
776  if (stat(fname, &st) == 0)
777  te->dataLength = st.st_size;
778  else
779  {
780  /* It might be compressed */
781  strlcat(fname, ".gz", sizeof(fname));
782  if (stat(fname, &st) == 0)
783  te->dataLength = st.st_size;
784  }
785 
786  /*
787  * If this is the BLOBS entry, what we stat'd was blobs.toc, which
788  * most likely is a lot smaller than the actual blob data. We don't
789  * have a cheap way to estimate how much smaller, but fortunately it
790  * doesn't matter too much as long as we get the LOs processed
791  * reasonably early. Arbitrarily scale up by a factor of 1K.
792  */
793  if (strcmp(te->desc, "BLOBS") == 0)
794  te->dataLength *= 1024;
795  }
796 }
#define REQ_DATA
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
struct _tocEntry * toc
pgoff_t dataLength
struct _tocEntry * next
#define stat
Definition: win32_port.h:286

References _tocEntry::dataLength, _tocEntry::desc, lclTocEntry::filename, _tocEntry::formatData, if(), MAXPGPATH, _tocEntry::next, 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:214

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;
386  char *buf;
387  size_t buflen;
388  cfp *cfp;
389 
390  if (!filename)
391  return;
392 
394 
395  if (!cfp)
396  pg_fatal("could not open input file \"%s\": %m", filename);
397 
399  buflen = ZLIB_OUT_SIZE;
400 
401  while ((cnt = cfread(buf, buflen, cfp)))
402  {
403  ahwrite(buf, 1, cnt, AH);
404  }
405 
406  free(buf);
407  if (cfclose(cfp) != 0)
408  pg_fatal("could not close data file \"%s\": %m", filename);
409 }
int cfread(void *ptr, int size, cfp *fp)
Definition: compress_io.c:550
struct cfp cfp
Definition: compress_io.h:53
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static char * filename
Definition: pg_dumpall.c:119
#define ZLIB_OUT_SIZE
Definition: walmethods.c:33

References ahwrite(), buf, cfclose(), cfopen_read(), cfread(), filename, free, PG_BINARY_R, pg_fatal, pg_malloc(), and ZLIB_OUT_SIZE.

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);
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)

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

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

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

Referenced by InitArchiveFmt_Directory().

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 512 of file pg_backup_directory.c.

513 {
514  lclContext *ctx = (lclContext *) AH->formatData;
515 
516  return cfgetc(ctx->dataFH);
517 }
int cfgetc(cfp *fp)
Definition: compress_io.c:592

References cfgetc(), lclContext::dataFH, and _archiveHandle::formatData.

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

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

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 = cfopen_write(fname, PG_BINARY_W,
331  AH->compression_spec);
332  if (ctx->dataFH == NULL)
333  pg_fatal("could not open output file \"%s\": %m", fname);
334 }
pg_compress_specification compression_spec

References cfopen_write(), _archiveHandle::compression_spec, lclTocEntry::filename, _archiveHandle::formatData, _tocEntry::formatData, 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 663 of file pg_backup_directory.c.

664 {
665  lclContext *ctx = (lclContext *) AH->formatData;
666  char fname[MAXPGPATH];
667 
668  snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
669 
670  ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression_spec);
671 
672  if (ctx->dataFH == NULL)
673  pg_fatal("could not open output file \"%s\": %m", fname);
674 }

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

Referenced by InitArchiveFmt_Directory().

◆ _StartLOs()

static void _StartLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 642 of file pg_backup_directory.c.

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

References _archiveHandle::formatData.

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobDumpDirectory()

static int _WorkerJobDumpDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 836 of file pg_backup_directory.c.

837 {
838  /*
839  * This function returns void. We either fail and die horribly or
840  * succeed... A failure will be detected by the parent when the child dies
841  * unexpectedly.
842  */
844 
845  return 0;
846 }
void WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te)

References WriteDataChunksForTocEntry().

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobRestoreDirectory()

static int _WorkerJobRestoreDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 853 of file pg_backup_directory.c.

854 {
855  return parallel_restore(AH, te);
856 }
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 524 of file pg_backup_directory.c.

525 {
526  lclContext *ctx = (lclContext *) AH->formatData;
527 
528  errno = 0;
529  if (cfwrite(buf, len, ctx->dataFH) != len)
530  {
531  /* if write didn't set errno, assume problem is no disk space */
532  if (errno == 0)
533  errno = ENOSPC;
534  pg_fatal("could not write to output file: %s",
535  get_cfp_error(ctx->dataFH));
536  }
537 }
const char * get_cfp_error(cfp *fp)
Definition: compress_io.c:669

References buf, cfwrite(), lclContext::dataFH, _archiveHandle::formatData, get_cfp_error(), 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 
492  errno = 0;
493  if (cfwrite(&c, 1, ctx->dataFH) != 1)
494  {
495  /* if write didn't set errno, assume problem is no disk space */
496  if (errno == 0)
497  errno = ENOSPC;
498  pg_fatal("could not write to output file: %s",
499  get_cfp_error(ctx->dataFH));
500  }
501 
502  return 1;
503 }
int i
Definition: isn.c:73
char * c

References cfwrite(), lclContext::dataFH, _archiveHandle::formatData, get_cfp_error(), 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 
350  errno = 0;
351  if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
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  get_cfp_error(ctx->dataFH));
358  }
359 }
const void * data

References cfwrite(), data, lclContext::dataFH, _archiveHandle::formatData, get_cfp_error(), 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 108 of file pg_backup_directory.c.

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

722 {
723  lclContext *ctx = (lclContext *) AH->formatData;
724  char *dname;
725 
726  dname = ctx->directory;
727 
728  if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
729  pg_fatal("file name too long: \"%s\"", dname);
730 
731  strcpy(buf, dname);
732  strcat(buf, "/");
733  strcat(buf, relativeFilename);
734 }

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

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