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 *)
 
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 _StartBlobs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndBlobs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadBlobs (ArchiveHandle *AH)
 
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:225
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 797 of file pg_backup_directory.c.

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

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

References 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_fatal, lclContext::pstate, setFilePath(), WriteDataChunks(), WriteHead(), and WriteToc().

Referenced by InitArchiveFmt_Directory().

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 819 of file pg_backup_directory.c.

820 {
821  lclContext *ctx = (lclContext *) AH->formatData;
822 
823  free(ctx);
824 }
#define free(a)
Definition: header.h:65

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Directory().

◆ _EndBlob()

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

Definition at line 677 of file pg_backup_directory.c.

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

References lclContext::blobsTocFH, buf, cfclose(), cfwrite(), lclContext::dataFH, _archiveHandle::formatData, if(), len, pg_fatal, and snprintf.

Referenced by InitArchiveFmt_Directory().

◆ _EndBlobs()

static void _EndBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 700 of file pg_backup_directory.c.

701 {
702  lclContext *ctx = (lclContext *) AH->formatData;
703 
704  if (cfclose(ctx->blobsTocFH) != 0)
705  pg_fatal("could not close blobs TOC file: %m");
706  ctx->blobsTocFH = NULL;
707 }

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

Referenced by InitArchiveFmt_Directory().

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 367 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _LoadBlobs()

static void _LoadBlobs ( ArchiveHandle AH)
static

Definition at line 433 of file pg_backup_directory.c.

434 {
435  Oid oid;
436  lclContext *ctx = (lclContext *) AH->formatData;
437  char tocfname[MAXPGPATH];
438  char line[MAXPGPATH];
439 
440  StartRestoreBlobs(AH);
441 
442  setFilePath(AH, tocfname, "blobs.toc");
443 
444  ctx->blobsTocFH = cfopen_read(tocfname, PG_BINARY_R);
445 
446  if (ctx->blobsTocFH == NULL)
447  pg_fatal("could not open large object TOC file \"%s\" for input: %m",
448  tocfname);
449 
450  /* Read the blobs TOC file line-by-line, and process each blob */
451  while ((cfgets(ctx->blobsTocFH, line, MAXPGPATH)) != NULL)
452  {
453  char blobfname[MAXPGPATH + 1];
454  char path[MAXPGPATH];
455 
456  /* Can't overflow because line and blobfname are the same length */
457  if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, blobfname) != 2)
458  pg_fatal("invalid line in large object TOC file \"%s\": \"%s\"",
459  tocfname, line);
460 
461  StartRestoreBlob(AH, oid, AH->public.ropt->dropSchema);
462  snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, blobfname);
463  _PrintFileData(AH, path);
464  EndRestoreBlob(AH, oid);
465  }
466  if (!cfeof(ctx->blobsTocFH))
467  pg_fatal("error reading large object TOC file \"%s\"",
468  tocfname);
469 
470  if (cfclose(ctx->blobsTocFH) != 0)
471  pg_fatal("could not close large object TOC file \"%s\": %m",
472  tocfname);
473 
474  ctx->blobsTocFH = NULL;
475 
476  EndRestoreBlobs(AH);
477 }
#define PG_BINARY_R
Definition: c.h:1270
#define CppAsString2(x)
Definition: c.h:289
char * cfgets(cfp *fp, char *buf, int len)
Definition: compress_io.c:638
cfp * cfopen_read(const char *path, const char *mode)
Definition: compress_io.c:452
int cfeof(cfp *fp)
Definition: compress_io.c:676
void StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
void StartRestoreBlobs(ArchiveHandle *AH)
void EndRestoreBlob(ArchiveHandle *AH, Oid oid)
void EndRestoreBlobs(ArchiveHandle *AH)
static void _PrintFileData(ArchiveHandle *AH, char *filename)
unsigned int Oid
Definition: postgres_ext.h:31
RestoreOptions * ropt
Definition: pg_backup.h:210

References _PrintFileData(), lclContext::blobsTocFH, cfclose(), cfeof(), cfgets(), cfopen_read(), CppAsString2, lclContext::directory, _restoreOptions::dropSchema, EndRestoreBlob(), EndRestoreBlobs(), _archiveHandle::formatData, MAXPGPATH, PG_BINARY_R, pg_fatal, _archiveHandle::public, Archive::ropt, setFilePath(), snprintf, StartRestoreBlob(), and StartRestoreBlobs().

Referenced by _PrintTocData().

◆ _PrepParallelRestore()

static void _PrepParallelRestore ( ArchiveHandle AH)
static

Definition at line 742 of file pg_backup_directory.c.

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

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:212

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

383 {
384  size_t cnt;
385  char *buf;
386  size_t buflen;
387  cfp *cfp;
388 
389  if (!filename)
390  return;
391 
393 
394  if (!cfp)
395  pg_fatal("could not open input file \"%s\": %m", filename);
396 
398  buflen = ZLIB_OUT_SIZE;
399 
400  while ((cnt = cfread(buf, buflen, cfp)))
401  {
402  ahwrite(buf, 1, cnt, AH);
403  }
404 
405  free(buf);
406  if (cfclose(cfp) != 0)
407  pg_fatal("could not close data file \"%s\": %m", filename);
408 }
int cfread(void *ptr, int size, cfp *fp)
Definition: compress_io.c:568
struct cfp cfp
Definition: compress_io.h:57
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static char * filename
Definition: pg_dumpall.c:94
#define ZLIB_OUT_SIZE
Definition: walmethods.c:36

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

Referenced by _LoadBlobs(), 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  _LoadBlobs(AH);
423  else
424  {
425  char fname[MAXPGPATH];
426 
427  setFilePath(AH, fname, tctx->filename);
428  _PrintFileData(AH, fname);
429  }
430 }
static void _LoadBlobs(ArchiveHandle *AH)

References _LoadBlobs(), _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 544 of file pg_backup_directory.c.

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

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

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

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

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

Referenced by InitArchiveFmt_Directory().

◆ _StartBlob()

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

Definition at line 658 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _StartBlobs()

static void _StartBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 639 of file pg_backup_directory.c.

640 {
641  lclContext *ctx = (lclContext *) AH->formatData;
642  char fname[MAXPGPATH];
643 
644  setFilePath(AH, fname, "blobs.toc");
645 
646  /* The blob TOC file is never compressed */
647  ctx->blobsTocFH = cfopen_write(fname, "ab", 0);
648  if (ctx->blobsTocFH == NULL)
649  pg_fatal("could not open output file \"%s\": %m", fname);
650 }

References lclContext::blobsTocFH, cfopen_write(), _archiveHandle::formatData, MAXPGPATH, pg_fatal, and setFilePath().

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

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

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobDumpDirectory()

static int _WorkerJobDumpDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 831 of file pg_backup_directory.c.

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

References WriteDataChunksForTocEntry().

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobRestoreDirectory()

static int _WorkerJobRestoreDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 848 of file pg_backup_directory.c.

849 {
850  return parallel_restore(AH, te);
851 }
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 523 of file pg_backup_directory.c.

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

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

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

346 {
347  lclContext *ctx = (lclContext *) AH->formatData;
348 
349  errno = 0;
350  if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
351  {
352  /* if write didn't set errno, assume problem is no disk space */
353  if (errno == 0)
354  errno = ENOSPC;
355  pg_fatal("could not write to output file: %s",
356  get_cfp_error(ctx->dataFH));
357  }
358 }
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 
129  AH->StartBlobPtr = _StartBlob;
130  AH->EndBlobPtr = _EndBlob;
131  AH->EndBlobsPtr = _EndBlobs;
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->blobsTocFH = 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:123
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 _StartBlobs(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 _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _PrepParallelRestore(ArchiveHandle *AH)
static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _EndBlobs(ArchiveHandle *AH, TocEntry *te)
static int _ReadByte(ArchiveHandle *)
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
ReadExtraTocPtrType ReadExtraTocPtr
WorkerJobDumpPtrType WorkerJobDumpPtr
EndBlobPtrType EndBlobPtr
ArchiveEntryPtrType ArchiveEntryPtr
WriteDataPtrType WriteDataPtr
ClonePtrType ClonePtr
StartBlobsPtrType StartBlobsPtr
WriteBufPtrType WriteBufPtr
PrepParallelRestorePtrType PrepParallelRestorePtr
StartBlobPtrType StartBlobPtr
WriteExtraTocPtrType WriteExtraTocPtr
ReadBytePtrType ReadBytePtr
WorkerJobRestorePtrType WorkerJobRestorePtr
PrintTocDataPtrType PrintTocDataPtr
WriteBytePtrType WriteBytePtr
ReadBufPtrType ReadBufPtr
PrintExtraTocPtrType PrintExtraTocPtr
EndBlobsPtrType EndBlobsPtr
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:324
#define mkdir(a, b)
Definition: win32_port.h:71

References _ArchiveEntry(), _Clone(), _CloseArchive(), _DeClone(), _EndBlob(), _EndBlobs(), _EndData(), _PrepParallelRestore(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _ReopenArchive(), _StartBlob(), _StartBlobs(), _StartData(), _WorkerJobDumpDirectory(), _WorkerJobRestoreDirectory(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), archDirectory, _archiveHandle::ArchiveEntryPtr, archModeWrite, archTar, lclContext::blobsTocFH, cfclose(), cfopen_read(), _archiveHandle::ClonePtr, closedir(), _archiveHandle::ClosePtr, dirent::d_name, lclContext::dataFH, _archiveHandle::DeClonePtr, lclContext::directory, _archiveHandle::EndBlobPtr, _archiveHandle::EndBlobsPtr, _archiveHandle::EndDataPtr, _archiveHandle::format, _archiveHandle::formatData, _archiveHandle::fSpec, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, 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::StartBlobPtr, _archiveHandle::StartBlobsPtr, _archiveHandle::StartDataPtr, 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 716 of file pg_backup_directory.c.

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

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

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