PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_backup_directory.c File Reference
#include "postgres_fe.h"
#include <dirent.h>
#include <sys/stat.h>
#include "common/file_utils.h"
#include "compress_io.h"
#include "parallel.h"
#include "pg_backup_utils.h"
Include dependency graph for pg_backup_directory.c:

Go to the source code of this file.

Data Structures

struct  lclContext
 
struct  lclTocEntry
 

Functions

static void _ArchiveEntry (ArchiveHandle *AH, TocEntry *te)
 
static void _StartData (ArchiveHandle *AH, TocEntry *te)
 
static void _EndData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteData (ArchiveHandle *AH, const void *data, size_t dLen)
 
static int _WriteByte (ArchiveHandle *AH, const int i)
 
static int _ReadByte (ArchiveHandle *AH)
 
static void _WriteBuf (ArchiveHandle *AH, const void *buf, size_t len)
 
static void _ReadBuf (ArchiveHandle *AH, void *buf, size_t len)
 
static void _CloseArchive (ArchiveHandle *AH)
 
static void _ReopenArchive (ArchiveHandle *AH)
 
static void _PrintTocData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _ReadExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _PrintExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _StartLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _PrepParallelRestore (ArchiveHandle *AH)
 
static void _Clone (ArchiveHandle *AH)
 
static void _DeClone (ArchiveHandle *AH)
 
static int _WorkerJobRestoreDirectory (ArchiveHandle *AH, TocEntry *te)
 
static int _WorkerJobDumpDirectory (ArchiveHandle *AH, TocEntry *te)
 
static void setFilePath (ArchiveHandle *AH, char *buf, const char *relativeFilename)
 
void InitArchiveFmt_Directory (ArchiveHandle *AH)
 
static void _PrintFileData (ArchiveHandle *AH, char *filename)
 

Function Documentation

◆ _ArchiveEntry()

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 230 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _Clone()

static void _Clone ( ArchiveHandle AH)
static

Definition at line 825 of file pg_backup_directory.c.

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

References _archiveHandle::formatData, and pg_malloc().

Referenced by InitArchiveFmt_Directory().

◆ _CloseArchive()

static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 581 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 845 of file pg_backup_directory.c.

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

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Directory().

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 369 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _EndLO()

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

Definition at line 693 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _EndLOs()

static void _EndLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 723 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 434 of file pg_backup_directory.c.

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

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

Referenced by _PrintTocData().

◆ _PrepParallelRestore()

static void _PrepParallelRestore ( ArchiveHandle AH)
static

Definition at line 765 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _PrintExtraToc()

static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 304 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _PrintFileData()

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

Definition at line 384 of file pg_backup_directory.c.

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

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

Referenced by _LoadLOs(), and _PrintTocData().

◆ _PrintTocData()

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 415 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _ReadBuf()

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

Definition at line 555 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 520 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _ReadExtraToc()

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 281 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _ReopenArchive()

static void _ReopenArchive ( ArchiveHandle AH)
static

Definition at line 632 of file pg_backup_directory.c.

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

Referenced by InitArchiveFmt_Directory().

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 322 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _StartLO()

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

Definition at line 675 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _StartLOs()

static void _StartLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 653 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobDumpDirectory()

static int _WorkerJobDumpDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 857 of file pg_backup_directory.c.

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

References WriteDataChunksForTocEntry().

Referenced by InitArchiveFmt_Directory().

◆ _WorkerJobRestoreDirectory()

static int _WorkerJobRestoreDirectory ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 874 of file pg_backup_directory.c.

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

References parallel_restore().

Referenced by InitArchiveFmt_Directory().

◆ _WriteBuf()

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

Definition at line 533 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _WriteByte()

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

Definition at line 494 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _WriteData()

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

Definition at line 346 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ _WriteExtraToc()

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 260 of file pg_backup_directory.c.

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

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

Referenced by InitArchiveFmt_Directory().

◆ InitArchiveFmt_Directory()

void InitArchiveFmt_Directory ( ArchiveHandle AH)

Definition at line 109 of file pg_backup_directory.c.

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

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

Referenced by _allocAH().

◆ setFilePath()

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

Definition at line 739 of file pg_backup_directory.c.

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

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

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