LCOV - differential code coverage report
Current view: top level - src/backend/backup - basebackup.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 83.1 % 586 487 30 56 13 29 290 23 145 56 291 1 21
Current Date: 2023-04-08 17:13:01 Functions: 92.3 % 13 12 1 12 1 12
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 66.7 % 3 2 1 1 1 1 1
Legend: Lines: hit not hit (180,240] days: 100.0 % 20 20 1 19 1
(240..) days: 82.6 % 563 465 30 55 13 29 288 4 144 55 289
Function coverage date bins:
(240..) days: 46.2 % 26 12 1 12 1 12

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * basebackup.c
                                  4                 :  *    code for taking a base backup and streaming it to a standby
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 2010-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  * IDENTIFICATION
                                  9                 :  *    src/backend/backup/basebackup.c
                                 10                 :  *
                                 11                 :  *-------------------------------------------------------------------------
                                 12                 :  */
                                 13                 : #include "postgres.h"
                                 14                 : 
                                 15                 : #include <sys/stat.h>
                                 16                 : #include <unistd.h>
                                 17                 : #include <time.h>
                                 18                 : 
                                 19                 : #include "access/xlog_internal.h"
                                 20                 : #include "access/xlogbackup.h"
                                 21                 : #include "backup/backup_manifest.h"
                                 22                 : #include "backup/basebackup.h"
                                 23                 : #include "backup/basebackup_sink.h"
                                 24                 : #include "backup/basebackup_target.h"
                                 25                 : #include "commands/defrem.h"
                                 26                 : #include "common/compression.h"
                                 27                 : #include "common/file_perm.h"
                                 28                 : #include "lib/stringinfo.h"
                                 29                 : #include "miscadmin.h"
                                 30                 : #include "nodes/pg_list.h"
                                 31                 : #include "pgstat.h"
                                 32                 : #include "pgtar.h"
                                 33                 : #include "port.h"
                                 34                 : #include "postmaster/syslogger.h"
                                 35                 : #include "replication/walsender.h"
                                 36                 : #include "replication/walsender_private.h"
                                 37                 : #include "storage/bufpage.h"
                                 38                 : #include "storage/checksum.h"
                                 39                 : #include "storage/dsm_impl.h"
                                 40                 : #include "storage/fd.h"
                                 41                 : #include "storage/ipc.h"
                                 42                 : #include "storage/reinit.h"
                                 43                 : #include "utils/builtins.h"
                                 44                 : #include "utils/guc.h"
                                 45                 : #include "utils/ps_status.h"
                                 46                 : #include "utils/relcache.h"
                                 47                 : #include "utils/resowner.h"
                                 48                 : #include "utils/timestamp.h"
                                 49                 : 
                                 50                 : /*
                                 51                 :  * How much data do we want to send in one CopyData message? Note that
                                 52                 :  * this may also result in reading the underlying files in chunks of this
                                 53                 :  * size.
                                 54                 :  *
                                 55                 :  * NB: The buffer size is required to be a multiple of the system block
                                 56                 :  * size, so use that value instead if it's bigger than our preference.
                                 57                 :  */
                                 58                 : #define SINK_BUFFER_LENGTH          Max(32768, BLCKSZ)
                                 59                 : 
                                 60                 : typedef struct
                                 61                 : {
                                 62                 :     const char *label;
                                 63                 :     bool        progress;
                                 64                 :     bool        fastcheckpoint;
                                 65                 :     bool        nowait;
                                 66                 :     bool        includewal;
                                 67                 :     uint32      maxrate;
                                 68                 :     bool        sendtblspcmapfile;
                                 69                 :     bool        send_to_client;
                                 70                 :     bool        use_copytblspc;
                                 71                 :     BaseBackupTargetHandle *target_handle;
                                 72                 :     backup_manifest_option manifest;
                                 73                 :     pg_compress_algorithm compression;
                                 74                 :     pg_compress_specification compression_specification;
                                 75                 :     pg_checksum_type manifest_checksum_type;
                                 76                 : } basebackup_options;
                                 77                 : 
                                 78                 : static int64 sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
                                 79                 :                             struct backup_manifest_info *manifest);
                                 80                 : static int64 sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
                                 81                 :                      List *tablespaces, bool sendtblspclinks,
                                 82                 :                      backup_manifest_info *manifest, const char *spcoid);
                                 83                 : static bool sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
                                 84                 :                      struct stat *statbuf, bool missing_ok, Oid dboid,
                                 85                 :                      backup_manifest_info *manifest, const char *spcoid);
                                 86                 : static void sendFileWithContent(bbsink *sink, const char *filename,
                                 87                 :                                 const char *content,
                                 88                 :                                 backup_manifest_info *manifest);
                                 89                 : static int64 _tarWriteHeader(bbsink *sink, const char *filename,
                                 90                 :                              const char *linktarget, struct stat *statbuf,
                                 91                 :                              bool sizeonly);
                                 92                 : static void _tarWritePadding(bbsink *sink, int len);
                                 93                 : static void convert_link_to_directory(const char *pathbuf, struct stat *statbuf);
                                 94                 : static void perform_base_backup(basebackup_options *opt, bbsink *sink);
                                 95                 : static void parse_basebackup_options(List *options, basebackup_options *opt);
                                 96                 : static int  compareWalFileNames(const ListCell *a, const ListCell *b);
                                 97                 : static bool is_checksummed_file(const char *fullpath, const char *filename);
                                 98                 : static int  basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
                                 99                 :                                  const char *filename, bool partial_read_ok);
                                100                 : 
                                101                 : /* Was the backup currently in-progress initiated in recovery mode? */
                                102                 : static bool backup_started_in_recovery = false;
                                103                 : 
                                104                 : /* Total number of checksum failures during base backup. */
                                105                 : static long long int total_checksum_failures;
                                106                 : 
                                107                 : /* Do not verify checksums. */
                                108                 : static bool noverify_checksums = false;
                                109                 : 
                                110                 : /*
                                111                 :  * Definition of one element part of an exclusion list, used for paths part
                                112                 :  * of checksum validation or base backups.  "name" is the name of the file
                                113                 :  * or path to check for exclusion.  If "match_prefix" is true, any items
                                114                 :  * matching the name as prefix are excluded.
                                115                 :  */
                                116                 : struct exclude_list_item
                                117                 : {
                                118                 :     const char *name;
                                119                 :     bool        match_prefix;
                                120                 : };
                                121                 : 
                                122                 : /*
                                123                 :  * The contents of these directories are removed or recreated during server
                                124                 :  * start so they are not included in backups.  The directories themselves are
                                125                 :  * kept and included as empty to preserve access permissions.
                                126                 :  *
                                127                 :  * Note: this list should be kept in sync with the filter lists in pg_rewind's
                                128                 :  * filemap.c.
                                129                 :  */
                                130                 : static const char *const excludeDirContents[] =
                                131                 : {
                                132                 :     /*
                                133                 :      * Skip temporary statistics files. PG_STAT_TMP_DIR must be skipped
                                134                 :      * because extensions like pg_stat_statements store data there.
                                135                 :      */
                                136                 :     PG_STAT_TMP_DIR,
                                137                 : 
                                138                 :     /*
                                139                 :      * It is generally not useful to backup the contents of this directory
                                140                 :      * even if the intention is to restore to another primary. See backup.sgml
                                141                 :      * for a more detailed description.
                                142                 :      */
                                143                 :     "pg_replslot",
                                144                 : 
                                145                 :     /* Contents removed on startup, see dsm_cleanup_for_mmap(). */
                                146                 :     PG_DYNSHMEM_DIR,
                                147                 : 
                                148                 :     /* Contents removed on startup, see AsyncShmemInit(). */
                                149                 :     "pg_notify",
                                150                 : 
                                151                 :     /*
                                152                 :      * Old contents are loaded for possible debugging but are not required for
                                153                 :      * normal operation, see SerialInit().
                                154                 :      */
                                155                 :     "pg_serial",
                                156                 : 
                                157                 :     /* Contents removed on startup, see DeleteAllExportedSnapshotFiles(). */
                                158                 :     "pg_snapshots",
                                159                 : 
                                160                 :     /* Contents zeroed on startup, see StartupSUBTRANS(). */
                                161                 :     "pg_subtrans",
                                162                 : 
                                163                 :     /* end of list */
                                164                 :     NULL
                                165                 : };
                                166                 : 
                                167                 : /*
                                168                 :  * List of files excluded from backups.
                                169                 :  */
                                170                 : static const struct exclude_list_item excludeFiles[] =
                                171                 : {
                                172                 :     /* Skip auto conf temporary file. */
                                173                 :     {PG_AUTOCONF_FILENAME ".tmp", false},
                                174                 : 
                                175                 :     /* Skip current log file temporary file */
                                176                 :     {LOG_METAINFO_DATAFILE_TMP, false},
                                177                 : 
                                178                 :     /*
                                179                 :      * Skip relation cache because it is rebuilt on startup.  This includes
                                180                 :      * temporary files.
                                181                 :      */
                                182                 :     {RELCACHE_INIT_FILENAME, true},
                                183                 : 
                                184                 :     /*
                                185                 :      * backup_label and tablespace_map should not exist in a running cluster
                                186                 :      * capable of doing an online backup, but exclude them just in case.
                                187                 :      */
                                188                 :     {BACKUP_LABEL_FILE, false},
                                189                 :     {TABLESPACE_MAP, false},
                                190                 : 
                                191                 :     /*
                                192                 :      * If there's a backup_manifest, it belongs to a backup that was used to
                                193                 :      * start this server. It is *not* correct for this backup. Our
                                194                 :      * backup_manifest is injected into the backup separately if users want
                                195                 :      * it.
                                196                 :      */
                                197                 :     {"backup_manifest", false},
                                198                 : 
                                199                 :     {"postmaster.pid", false},
                                200                 :     {"postmaster.opts", false},
                                201                 : 
                                202                 :     /* end of list */
                                203                 :     {NULL, false}
                                204                 : };
                                205                 : 
                                206                 : /*
                                207                 :  * List of files excluded from checksum validation.
                                208                 :  *
                                209                 :  * Note: this list should be kept in sync with what pg_checksums.c
                                210                 :  * includes.
                                211                 :  */
                                212                 : static const struct exclude_list_item noChecksumFiles[] = {
                                213                 :     {"pg_control", false},
                                214                 :     {"pg_filenode.map", false},
                                215                 :     {"pg_internal.init", true},
                                216                 :     {"PG_VERSION", false},
                                217                 : #ifdef EXEC_BACKEND
                                218                 :     {"config_exec_params", true},
                                219                 : #endif
                                220                 :     {NULL, false}
                                221                 : };
                                222                 : 
                                223                 : /*
                                224                 :  * Actually do a base backup for the specified tablespaces.
                                225                 :  *
                                226                 :  * This is split out mainly to avoid complaints about "variable might be
                                227                 :  * clobbered by longjmp" from stupider versions of gcc.
                                228                 :  */
                                229                 : static void
  520 rhaas                     230 GIC         126 : perform_base_backup(basebackup_options *opt, bbsink *sink)
                                231                 : {
  520 rhaas                     232 ECB             :     bbsink_state state;
                                233                 :     XLogRecPtr  endptr;
                                234                 :     TimeLineID  endtli;
                                235                 :     backup_manifest_info manifest;
                                236                 :     BackupState *backup_state;
                                237                 :     StringInfo  tablespace_map;
                                238                 : 
                                239                 :     /* Initial backup state, insofar as we know it now. */
  520 rhaas                     240 GIC         126 :     state.tablespaces = NIL;
                                241             126 :     state.tablespace_num = 0;
  520 rhaas                     242 CBC         126 :     state.bytes_done = 0;
                                243             126 :     state.bytes_total = 0;
                                244             126 :     state.bytes_total_is_valid = false;
 1111 fujii                     245 ECB             : 
 1101 rhaas                     246                 :     /* we're going to use a BufFile, so we need a ResourceOwner */
 1101 rhaas                     247 GIC         126 :     Assert(CurrentResourceOwner == NULL);
                                248             126 :     CurrentResourceOwner = ResourceOwnerCreate(NULL, "base backup");
 1101 rhaas                     249 ECB             : 
 3769 heikki.linnakangas        250 CBC         126 :     backup_started_in_recovery = RecoveryInProgress();
                                251                 : 
 1081 rhaas                     252             126 :     InitializeBackupManifest(&manifest, opt->manifest,
                                253                 :                              opt->manifest_checksum_type);
                                254                 : 
 1832 magnus                    255             126 :     total_checksum_failures = 0;
                                256                 : 
                                257                 :     /* Allocate backup related varilables. */
  195 michael                   258 GNC         126 :     backup_state = (BackupState *) palloc0(sizeof(BackupState));
                                259             126 :     tablespace_map = makeStringInfo();
                                260                 : 
  520 rhaas                     261 GIC         126 :     basebackup_progress_wait_checkpoint();
  195 michael                   262 GNC         126 :     do_pg_backup_start(opt->label, opt->fastcheckpoint, &state.tablespaces,
                                263                 :                        backup_state, tablespace_map);
                                264                 : 
                                265             126 :     state.startptr = backup_state->startpoint;
                                266             126 :     state.starttli = backup_state->starttli;
 2878 bruce                     267 ECB             : 
                                268                 :     /*
                                269                 :      * Once do_pg_backup_start has been called, ensure that any failure causes
                                270                 :      * us to abort the backup so we don't "leak" a backup counter. For this
  368 sfrost                    271                 :      * reason, *all* functionality between do_pg_backup_start() and the end of
                                272                 :      * do_pg_backup_stop() should be inside the error cleanup block!
                                273                 :      */
                                274                 : 
 1207 rhaas                     275 GIC         126 :     PG_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
                                276                 :     {
                                277                 :         ListCell   *lc;
                                278                 :         tablespaceinfo *newti;
                                279                 : 
 4452 magnus                    280 ECB             :         /* Add a node for the base directory at the end */
  186 drowley                   281 GNC         126 :         newti = palloc0(sizeof(tablespaceinfo));
                                282             126 :         newti->size = -1;
                                283             126 :         state.tablespaces = lappend(state.tablespaces, newti);
                                284                 : 
                                285                 :         /*
 1132 fujii                     286 ECB             :          * Calculate the total backup size by summing up the size of each
                                287                 :          * tablespace
                                288                 :          */
 1132 fujii                     289 GIC         126 :         if (opt->progress)
                                290                 :         {
  520 rhaas                     291             126 :             basebackup_progress_estimate_backup_size();
                                292                 : 
                                293             268 :             foreach(lc, state.tablespaces)
 1132 fujii                     294 ECB             :             {
 1132 fujii                     295 GIC         142 :                 tablespaceinfo *tmp = (tablespaceinfo *) lfirst(lc);
 1132 fujii                     296 ECB             : 
 1026 rhaas                     297 GIC         142 :                 if (tmp->path == NULL)
  520 rhaas                     298 CBC         126 :                     tmp->size = sendDir(sink, ".", 1, true, state.tablespaces,
                                299                 :                                         true, NULL, NULL);
 1026 rhaas                     300 ECB             :                 else
  520 rhaas                     301 GIC          16 :                     tmp->size = sendTablespace(sink, tmp->path, tmp->oid, true,
 1026 rhaas                     302 ECB             :                                                NULL);
  520 rhaas                     303 CBC         142 :                 state.bytes_total += tmp->size;
                                304                 :             }
  520 rhaas                     305 GIC         126 :             state.bytes_total_is_valid = true;
 1132 fujii                     306 ECB             :         }
                                307                 : 
  520 rhaas                     308                 :         /* notify basebackup sink about start of backup */
  520 rhaas                     309 GIC         126 :         bbsink_begin_backup(sink, &state, SINK_BUFFER_LENGTH);
 3328 alvherre                  310 ECB             : 
                                311                 :         /* Send off our tablespaces one by one */
  520 rhaas                     312 GIC         262 :         foreach(lc, state.tablespaces)
                                313                 :         {
 4471 tgl                       314 CBC         142 :             tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc);
                                315                 : 
 4092 simon                     316 GIC         142 :             if (ti->path == NULL)
 4092 simon                     317 ECB             :             {
                                318                 :                 struct stat statbuf;
  697 tgl                       319 CBC         126 :                 bool        sendtblspclinks = true;
                                320                 :                 char       *backup_label;
                                321                 : 
  520 rhaas                     322             126 :                 bbsink_begin_archive(sink, "base.tar");
                                323                 : 
                                324                 :                 /* In the main tar, include the backup_label first... */
  195 michael                   325 GNC         126 :                 backup_label = build_backup_content(backup_state, false);
                                326             126 :                 sendFileWithContent(sink, BACKUP_LABEL_FILE,
                                327                 :                                     backup_label, &manifest);
                                328             126 :                 pfree(backup_label);
                                329                 : 
 1026 rhaas                     330 ECB             :                 /* Then the tablespace_map file, if required... */
 1026 rhaas                     331 GIC         126 :                 if (opt->sendtblspcmapfile)
                                332                 :                 {
  195 michael                   333 GNC          24 :                     sendFileWithContent(sink, TABLESPACE_MAP,
                                334              24 :                                         tablespace_map->data, &manifest);
 1026 rhaas                     335 GIC          24 :                     sendtblspclinks = false;
 2889 andrew                    336 ECB             :                 }
                                337                 : 
                                338                 :                 /* Then the bulk of the files... */
  520 rhaas                     339 CBC         126 :                 sendDir(sink, ".", 1, false, state.tablespaces,
                                340                 :                         sendtblspclinks, &manifest, NULL);
 3667 heikki.linnakangas        341 ECB             : 
                                342                 :                 /* ... and pg_control after everything else. */
 4092 simon                     343 CBC         120 :                 if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0)
 4092 simon                     344 UIC           0 :                     ereport(ERROR,
                                345                 :                             (errcode_for_file_access(),
                                346                 :                              errmsg("could not stat file \"%s\": %m",
 4092 simon                     347 ECB             :                                     XLOG_CONTROL_FILE)));
  520 rhaas                     348 GIC         120 :                 sendFile(sink, XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf,
                                349                 :                          false, InvalidOid, &manifest, NULL);
                                350                 :             }
 3667 heikki.linnakangas        351 ECB             :             else
  520 rhaas                     352 EUB             :             {
  520 rhaas                     353 GIC          16 :                 char       *archive_name = psprintf("%s.tar", ti->oid);
                                354                 : 
                                355              16 :                 bbsink_begin_archive(sink, archive_name);
  520 rhaas                     356 ECB             : 
  520 rhaas                     357 GIC          16 :                 sendTablespace(sink, ti->path, ti->oid, false, &manifest);
                                358                 :             }
                                359                 : 
                                360                 :             /*
 4452 magnus                    361 ECB             :              * If we're including WAL, and this is the main data directory we
                                362                 :              * don't treat this as the end of the tablespace. Instead, we will
  520 rhaas                     363                 :              * include the xlog files below and stop afterwards. This is safe
                                364                 :              * since the main data directory is always sent *last*.
 4452 magnus                    365                 :              */
 4452 magnus                    366 GIC         136 :             if (opt->includewal && ti->path == NULL)
                                367                 :             {
  520 rhaas                     368              20 :                 Assert(lnext(state.tablespaces, lc) == NULL);
                                369                 :             }
                                370                 :             else
                                371                 :             {
                                372                 :                 /* Properly terminate the tarfile. */
                                373                 :                 StaticAssertDecl(2 * TAR_BLOCK_SIZE <= BLCKSZ,
  516 rhaas                     374 ECB             :                                  "BLCKSZ too small for 2 tar blocks");
  516 rhaas                     375 GIC         116 :                 memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
  516 rhaas                     376 CBC         116 :                 bbsink_archive_contents(sink, 2 * TAR_BLOCK_SIZE);
                                377                 : 
                                378                 :                 /* OK, that's the end of the archive. */
  520 rhaas                     379 GIC         116 :                 bbsink_end_archive(sink);
                                380                 :             }
                                381                 :         }
                                382                 : 
  520 rhaas                     383 CBC         120 :         basebackup_progress_wait_wal_archive(&state);
  195 michael                   384 GNC         120 :         do_pg_backup_stop(backup_state, !opt->nowait);
                                385                 : 
                                386             120 :         endptr = backup_state->stoppoint;
                                387             120 :         endtli = backup_state->stoptli;
                                388                 : 
                                389                 :         /* Deallocate backup-related variables. */
                                390             120 :         pfree(tablespace_map->data);
                                391             120 :         pfree(tablespace_map);
                                392             120 :         pfree(backup_state);
                                393                 :     }
 1207 rhaas                     394 GIC         121 :     PG_END_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
 4471 tgl                       395 ECB             : 
                                396                 : 
 4452 magnus                    397 GIC         120 :     if (opt->includewal)
                                398                 :     {
 4452 magnus                    399 ECB             :         /*
                                400                 :          * We've left the last tar file "open", so we can now append the
                                401                 :          * required WAL files to it.
                                402                 :          */
 3748 heikki.linnakangas        403                 :         char        pathbuf[MAXPGPATH];
                                404                 :         XLogSegNo   segno;
                                405                 :         XLogSegNo   startsegno;
                                406                 :         XLogSegNo   endsegno;
 4452 magnus                    407                 :         struct stat statbuf;
 3748 heikki.linnakangas        408 CBC          20 :         List       *historyFileList = NIL;
 3748 heikki.linnakangas        409 GIC          20 :         List       *walFileList = NIL;
 3748 heikki.linnakangas        410 ECB             :         char        firstoff[MAXFNAMELEN];
                                411                 :         char        lastoff[MAXFNAMELEN];
                                412                 :         DIR        *dir;
                                413                 :         struct dirent *de;
                                414                 :         ListCell   *lc;
                                415                 :         TimeLineID  tli;
                                416                 : 
  520 rhaas                     417 GIC          20 :         basebackup_progress_transfer_wal();
                                418                 : 
                                419                 :         /*
                                420                 :          * I'd rather not worry about timelines here, so scan pg_wal and
                                421                 :          * include all WAL files in the range between 'startptr' and 'endptr',
                                422                 :          * regardless of the timeline the file is stamped with. If there are
                                423                 :          * some spurious WAL files belonging to timelines that don't belong in
 3602 bruce                     424 ECB             :          * this server's history, they will be included too. Normally there
 3748 heikki.linnakangas        425                 :          * shouldn't be such files, but if there are, there's little harm in
                                426                 :          * including them.
                                427                 :          */
  520 rhaas                     428 GIC          20 :         XLByteToSeg(state.startptr, startsegno, wal_segment_size);
                                429              20 :         XLogFileName(firstoff, state.starttli, startsegno, wal_segment_size);
 2028 andres                    430              20 :         XLByteToPrevSeg(endptr, endsegno, wal_segment_size);
  527 rhaas                     431              20 :         XLogFileName(lastoff, endtli, endsegno, wal_segment_size);
                                432                 : 
 2362 rhaas                     433 CBC          20 :         dir = AllocateDir("pg_wal");
 2362 rhaas                     434 GIC         123 :         while ((de = ReadDir(dir, "pg_wal")) != NULL)
                                435                 :         {
                                436                 :             /* Does it look like a WAL segment, and is it in the range? */
 2893 heikki.linnakangas        437             103 :             if (IsXLogFileName(de->d_name) &&
 3748                           438              43 :                 strcmp(de->d_name + 8, firstoff + 8) >= 0 &&
                                439              43 :                 strcmp(de->d_name + 8, lastoff + 8) <= 0)
                                440                 :             {
                                441              20 :                 walFileList = lappend(walFileList, pstrdup(de->d_name));
                                442                 :             }
                                443                 :             /* Does it look like a timeline history file? */
 2893 heikki.linnakangas        444 CBC          83 :             else if (IsTLHistoryFileName(de->d_name))
 3748 heikki.linnakangas        445 ECB             :             {
 3748 heikki.linnakangas        446 LBC           0 :                 historyFileList = lappend(historyFileList, pstrdup(de->d_name));
 3748 heikki.linnakangas        447 ECB             :             }
                                448                 :         }
 3748 heikki.linnakangas        449 CBC          20 :         FreeDir(dir);
 4452 magnus                    450 ECB             : 
                                451                 :         /*
                                452                 :          * Before we go any further, check that none of the WAL segments we
 3748 heikki.linnakangas        453                 :          * need were removed.
                                454                 :          */
  520 rhaas                     455 CBC          20 :         CheckXLogRemoved(startsegno, state.starttli);
                                456                 : 
 3748 heikki.linnakangas        457 ECB             :         /*
                                458                 :          * Sort the WAL filenames.  We want to send the files in order from
                                459                 :          * oldest to newest, to reduce the chance that a file is recycled
 1363 tgl                       460                 :          * before we get a chance to send it over.
                                461                 :          */
 1363 tgl                       462 GBC          20 :         list_sort(walFileList, compareWalFileNames);
                                463                 : 
                                464                 :         /*
 2153 bruce                     465 ECB             :          * There must be at least one xlog file in the pg_wal directory, since
                                466                 :          * we are doing backup-including-xlog.
                                467                 :          */
 1363 tgl                       468 GIC          20 :         if (walFileList == NIL)
 3515 magnus                    469 UIC           0 :             ereport(ERROR,
                                470                 :                     (errmsg("could not find any WAL files")));
 3515 magnus                    471 ECB             : 
                                472                 :         /*
                                473                 :          * Sanity check: the first and last segment should cover startptr and
                                474                 :          * endptr, with no gaps in between.
                                475                 :          */
 1363 tgl                       476 GIC          20 :         XLogFromFileName((char *) linitial(walFileList),
                                477                 :                          &tli, &segno, wal_segment_size);
 3748 heikki.linnakangas        478 CBC          20 :         if (segno != startsegno)
                                479                 :         {
                                480                 :             char        startfname[MAXFNAMELEN];
                                481                 : 
  520 rhaas                     482 UIC           0 :             XLogFileName(startfname, state.starttli, startsegno,
                                483                 :                          wal_segment_size);
 3748 heikki.linnakangas        484 LBC           0 :             ereport(ERROR,
 3698 peter_e                   485 EUB             :                     (errmsg("could not find WAL file \"%s\"", startfname)));
                                486                 :         }
 1363 tgl                       487 GIC          40 :         foreach(lc, walFileList)
                                488                 :         {
                                489              20 :             char       *walFileName = (char *) lfirst(lc);
 3602 bruce                     490              20 :             XLogSegNo   currsegno = segno;
                                491              20 :             XLogSegNo   nextsegno = segno + 1;
 4452 magnus                    492 ECB             : 
 1363 tgl                       493 GIC          20 :             XLogFromFileName(walFileName, &tli, &segno, wal_segment_size);
 3748 heikki.linnakangas        494 CBC          20 :             if (!(nextsegno == segno || currsegno == segno))
                                495                 :             {
                                496                 :                 char        nextfname[MAXFNAMELEN];
                                497                 : 
  527 rhaas                     498 UBC           0 :                 XLogFileName(nextfname, tli, nextsegno, wal_segment_size);
 3748 heikki.linnakangas        499 UIC           0 :                 ereport(ERROR,
 2118 tgl                       500 EUB             :                         (errmsg("could not find WAL file \"%s\"", nextfname)));
                                501                 :             }
                                502                 :         }
 3748 heikki.linnakangas        503 CBC          20 :         if (segno != endsegno)
                                504                 :         {
 3602 bruce                     505 ECB             :             char        endfname[MAXFNAMELEN];
                                506                 : 
  527 rhaas                     507 LBC           0 :             XLogFileName(endfname, endtli, endsegno, wal_segment_size);
 3748 heikki.linnakangas        508 UIC           0 :             ereport(ERROR,
 3698 peter_e                   509 ECB             :                     (errmsg("could not find WAL file \"%s\"", endfname)));
 3748 heikki.linnakangas        510                 :         }
                                511                 : 
                                512                 :         /* Ok, we have everything we need. Send the WAL files. */
 1363 tgl                       513 GIC          40 :         foreach(lc, walFileList)
 3748 heikki.linnakangas        514 EUB             :         {
 1363 tgl                       515 GBC          20 :             char       *walFileName = (char *) lfirst(lc);
                                516                 :             int         fd;
                                517                 :             size_t      cnt;
 3748 heikki.linnakangas        518 GIC          20 :             pgoff_t     len = 0;
 3748 heikki.linnakangas        519 ECB             : 
 1363 tgl                       520 GIC          20 :             snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFileName);
                                521              20 :             XLogFromFileName(walFileName, &tli, &segno, wal_segment_size);
                                522                 : 
 1026 rhaas                     523 GBC          20 :             fd = OpenTransientFile(pathbuf, O_RDONLY | PG_BINARY);
                                524              20 :             if (fd < 0)
                                525                 :             {
 1749 michael                   526 UIC           0 :                 int         save_errno = errno;
                                527                 : 
                                528                 :                 /*
 3748 heikki.linnakangas        529 ECB             :                  * Most likely reason for this is that the file was already
                                530                 :                  * removed by a checkpoint, so check for that to get a better
                                531                 :                  * error message.
                                532                 :                  */
 3748 heikki.linnakangas        533 UIC           0 :                 CheckXLogRemoved(segno, tli);
 3748 heikki.linnakangas        534 ECB             : 
 1749 michael                   535 UIC           0 :                 errno = save_errno;
 3748 heikki.linnakangas        536 LBC           0 :                 ereport(ERROR,
 3748 heikki.linnakangas        537 ECB             :                         (errcode_for_file_access(),
                                538                 :                          errmsg("could not open file \"%s\": %m", pathbuf)));
                                539                 :             }
                                540                 : 
 1026 rhaas                     541 GIC          20 :             if (fstat(fd, &statbuf) != 0)
 3748 heikki.linnakangas        542 UBC           0 :                 ereport(ERROR,
                                543                 :                         (errcode_for_file_access(),
                                544                 :                          errmsg("could not stat file \"%s\": %m",
                                545                 :                                 pathbuf)));
 2028 andres                    546 GIC          20 :             if (statbuf.st_size != wal_segment_size)
                                547                 :             {
 3748 heikki.linnakangas        548 UIC           0 :                 CheckXLogRemoved(segno, tli);
 3748 heikki.linnakangas        549 UBC           0 :                 ereport(ERROR,
                                550                 :                         (errcode_for_file_access(),
 1363 tgl                       551 EUB             :                          errmsg("unexpected WAL file size \"%s\"", walFileName)));
 3748 heikki.linnakangas        552                 :             }
                                553                 : 
                                554                 :             /* send the WAL file itself */
  520 rhaas                     555 GIC          20 :             _tarWriteHeader(sink, pathbuf, NULL, &statbuf, false);
                                556                 : 
  520 rhaas                     557 CBC          20 :             while ((cnt = basebackup_read_file(fd, sink->bbs_buffer,
  520 rhaas                     558 GBC       10240 :                                                Min(sink->bbs_buffer_length,
                                559                 :                                                    wal_segment_size - len),
 1026 rhaas                     560 GIC       10240 :                                                len, pathbuf, true)) > 0)
                                561                 :             {
 3748 heikki.linnakangas        562 CBC       10240 :                 CheckXLogRemoved(segno, tli);
  520 rhaas                     563 GIC       10240 :                 bbsink_archive_contents(sink, cnt);
 3748 heikki.linnakangas        564 EUB             : 
 3748 heikki.linnakangas        565 GBC       10240 :                 len += cnt;
                                566                 : 
 2028 andres                    567 GIC       10240 :                 if (len == wal_segment_size)
 3748 heikki.linnakangas        568              20 :                     break;
                                569                 :             }
                                570                 : 
 2028 andres                    571 CBC          20 :             if (len != wal_segment_size)
                                572                 :             {
 3748 heikki.linnakangas        573 LBC           0 :                 CheckXLogRemoved(segno, tli);
                                574               0 :                 ereport(ERROR,
                                575                 :                         (errcode_for_file_access(),
 1363 tgl                       576 ECB             :                          errmsg("unexpected WAL file size \"%s\"", walFileName)));
                                577                 :             }
 3748 heikki.linnakangas        578                 : 
 1080 rhaas                     579                 :             /*
                                580                 :              * wal_segment_size is a multiple of TAR_BLOCK_SIZE, so no need
                                581                 :              * for padding.
                                582                 :              */
 1080 rhaas                     583 CBC          20 :             Assert(wal_segment_size % TAR_BLOCK_SIZE == 0);
 3018 andres                    584 ECB             : 
 1026 rhaas                     585 GIC          20 :             CloseTransientFile(fd);
                                586                 : 
 3018 andres                    587 ECB             :             /*
                                588                 :              * Mark file as archived, otherwise files can get archived again
 3018 andres                    589 EUB             :              * after promotion of a new node. This is in line with
 2881 heikki.linnakangas        590                 :              * walreceiver.c always doing an XLogArchiveForceDone() after a
                                591                 :              * complete segment.
                                592                 :              */
 1363 tgl                       593 GIC          20 :             StatusFilePath(pathbuf, walFileName, ".done");
  520 rhaas                     594              20 :             sendFileWithContent(sink, pathbuf, "", &manifest);
                                595                 :         }
                                596                 : 
                                597                 :         /*
                                598                 :          * Send timeline history files too. Only the latest timeline history
 3748 heikki.linnakangas        599 ECB             :          * file is required for recovery, and even that only if there happens
                                600                 :          * to be a timeline switch in the first WAL segment that contains the
                                601                 :          * checkpoint record, or if we're taking a base backup from a standby
                                602                 :          * server and the target timeline changes while the backup is taken.
                                603                 :          * But they are small and highly useful for debugging purposes, so
                                604                 :          * better include them all, always.
                                605                 :          */
 3748 heikki.linnakangas        606 GIC          20 :         foreach(lc, historyFileList)
                                607                 :         {
 3602 bruce                     608 UIC           0 :             char       *fname = lfirst(lc);
 3602 bruce                     609 ECB             : 
 3748 heikki.linnakangas        610 LBC           0 :             snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", fname);
                                611                 : 
 3748 heikki.linnakangas        612 UIC           0 :             if (lstat(pathbuf, &statbuf) != 0)
                                613               0 :                 ereport(ERROR,
                                614                 :                         (errcode_for_file_access(),
                                615                 :                          errmsg("could not stat file \"%s\": %m", pathbuf)));
                                616                 : 
  520 rhaas                     617               0 :             sendFile(sink, pathbuf, pathbuf, &statbuf, false, InvalidOid,
                                618                 :                      &manifest, NULL);
                                619                 : 
                                620                 :             /* unconditionally mark file as archived */
 3018 andres                    621               0 :             StatusFilePath(pathbuf, fname, ".done");
  520 rhaas                     622 LBC           0 :             sendFileWithContent(sink, pathbuf, "", &manifest);
                                623                 :         }
 4452 magnus                    624 EUB             : 
                                625                 :         /* Properly terminate the tar file. */
  515 rhaas                     626                 :         StaticAssertStmt(2 * TAR_BLOCK_SIZE <= BLCKSZ,
                                627                 :                          "BLCKSZ too small for 2 tar blocks");
  516 rhaas                     628 GBC          20 :         memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
                                629              20 :         bbsink_archive_contents(sink, 2 * TAR_BLOCK_SIZE);
                                630                 : 
                                631                 :         /* OK, that's the end of the archive. */
  520 rhaas                     632 GIC          20 :         bbsink_end_archive(sink);
 4452 magnus                    633 EUB             :     }
                                634                 : 
  520 rhaas                     635 GIC         120 :     AddWALInfoToBackupManifest(&manifest, state.startptr, state.starttli,
                                636                 :                                endptr, endtli);
 1101 rhaas                     637 EUB             : 
  520 rhaas                     638 GBC         120 :     SendBackupManifest(&manifest, sink);
                                639                 : 
  520 rhaas                     640 GIC         120 :     bbsink_end_backup(sink, endptr, endtli);
                                641                 : 
 1832 magnus                    642             120 :     if (total_checksum_failures)
                                643                 :     {
 1832 magnus                    644 CBC           3 :         if (total_checksum_failures > 1)
                                645               2 :             ereport(WARNING,
                                646                 :                     (errmsg_plural("%lld total checksum verification failure",
                                647                 :                                    "%lld total checksum verification failures",
  937 peter                     648 ECB             :                                    total_checksum_failures,
                                649                 :                                    total_checksum_failures)));
                                650                 : 
 1832 magnus                    651 CBC           3 :         ereport(ERROR,
                                652                 :                 (errcode(ERRCODE_DATA_CORRUPTED),
                                653                 :                  errmsg("checksum verification failure during base backup")));
 1832 magnus                    654 ECB             :     }
                                655                 : 
  856 michael                   656                 :     /*
                                657                 :      * Make sure to free the manifest before the resource owners as manifests
                                658                 :      * use cryptohash contexts that may depend on resource owners (like
                                659                 :      * OpenSSL).
                                660                 :      */
  856 michael                   661 CBC         117 :     FreeBackupManifest(&manifest);
                                662                 : 
                                663                 :     /* clean up the resource owner we created */
 1101 rhaas                     664 GIC         117 :     WalSndResourceCleanup(true);
                                665                 : 
  520                           666             117 :     basebackup_progress_done();
 4471 tgl                       667 CBC         117 : }
                                668                 : 
                                669                 : /*
                                670                 :  * list_sort comparison function, to compare log/seg portion of WAL segment
                                671                 :  * filenames, ignoring the timeline portion.
                                672                 :  */
                                673                 : static int
 1363 tgl                       674 UIC           0 : compareWalFileNames(const ListCell *a, const ListCell *b)
                                675                 : {
                                676               0 :     char       *fna = (char *) lfirst(a);
 1363 tgl                       677 LBC           0 :     char       *fnb = (char *) lfirst(b);
                                678                 : 
 3748 heikki.linnakangas        679 UIC           0 :     return strcmp(fna + 8, fnb + 8);
 3748 heikki.linnakangas        680 ECB             : }
                                681                 : 
 4459 magnus                    682                 : /*
                                683                 :  * Parse the base backup options passed down by the parser
                                684                 :  */
                                685                 : static void
 4459 magnus                    686 GIC         142 : parse_basebackup_options(List *options, basebackup_options *opt)
                                687                 : {
                                688                 :     ListCell   *lopt;
                                689             142 :     bool        o_label = false;
 4459 magnus                    690 GBC         142 :     bool        o_progress = false;
  551 rhaas                     691 GIC         142 :     bool        o_checkpoint = false;
 4442 magnus                    692 GBC         142 :     bool        o_nowait = false;
 4452                           693             142 :     bool        o_wal = false;
 3328 alvherre                  694 GIC         142 :     bool        o_maxrate = false;
 2889 andrew                    695 GBC         142 :     bool        o_tablespace_map = false;
 1832 magnus                    696 GIC         142 :     bool        o_noverify_checksums = false;
 1101 rhaas                     697             142 :     bool        o_manifest = false;
                                698             142 :     bool        o_manifest_checksums = false;
  446                           699             142 :     bool        o_target = false;
  509                           700             142 :     bool        o_target_detail = false;
  390                           701             142 :     char       *target_str = NULL;
  390 rhaas                     702 CBC         142 :     char       *target_detail_str = NULL;
  440 rhaas                     703 GIC         142 :     bool        o_compression = false;
  382                           704             142 :     bool        o_compression_detail = false;
  382 rhaas                     705 CBC         142 :     char       *compression_detail_str = NULL;
 4459 magnus                    706 ECB             : 
 4457 magnus                    707 CBC        1562 :     MemSet(opt, 0, sizeof(*opt));
 1101 rhaas                     708             142 :     opt->manifest = MANIFEST_OPTION_NO;
                                709             142 :     opt->manifest_checksum_type = CHECKSUM_TYPE_CRC32C;
  362 michael                   710             142 :     opt->compression = PG_COMPRESSION_NONE;
                                711             142 :     opt->compression_specification.algorithm = PG_COMPRESSION_NONE;
 1101 rhaas                     712 ECB             : 
 4459 magnus                    713 CBC        1087 :     foreach(lopt, options)
 4459 magnus                    714 ECB             :     {
 4459 magnus                    715 CBC         947 :         DefElem    *defel = (DefElem *) lfirst(lopt);
 4459 magnus                    716 ECB             : 
 4459 magnus                    717 CBC         947 :         if (strcmp(defel->defname, "label") == 0)
 4459 magnus                    718 ECB             :         {
 4459 magnus                    719 CBC         142 :             if (o_label)
 4459 magnus                    720 LBC           0 :                 ereport(ERROR,
 4459 magnus                    721 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                722                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     723 CBC         142 :             opt->label = defGetString(defel);
 4459 magnus                    724             142 :             o_label = true;
 4459 magnus                    725 ECB             :         }
 4459 magnus                    726 CBC         805 :         else if (strcmp(defel->defname, "progress") == 0)
 4459 magnus                    727 ECB             :         {
 4459 magnus                    728 GIC         142 :             if (o_progress)
 4459 magnus                    729 LBC           0 :                 ereport(ERROR,
                                730                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 4459 magnus                    731 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     732 GIC         142 :             opt->progress = defGetBoolean(defel);
 4459 magnus                    733 CBC         142 :             o_progress = true;
                                734                 :         }
  551 rhaas                     735             663 :         else if (strcmp(defel->defname, "checkpoint") == 0)
 4459 magnus                    736 EUB             :         {
  551 rhaas                     737 GIC         132 :             char       *optval = defGetString(defel);
                                738                 : 
  551 rhaas                     739 CBC         132 :             if (o_checkpoint)
 4459 magnus                    740 LBC           0 :                 ereport(ERROR,
                                741                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 4459 magnus                    742 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     743 GIC         132 :             if (pg_strcasecmp(optval, "fast") == 0)
  551 rhaas                     744 CBC         132 :                 opt->fastcheckpoint = true;
  551 rhaas                     745 UBC           0 :             else if (pg_strcasecmp(optval, "spread") == 0)
  551 rhaas                     746 UIC           0 :                 opt->fastcheckpoint = false;
                                747                 :             else
  551 rhaas                     748 LBC           0 :                 ereport(ERROR,
  551 rhaas                     749 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                750                 :                          errmsg("unrecognized checkpoint type: \"%s\"",
                                751                 :                                 optval)));
  551 rhaas                     752 GIC         132 :             o_checkpoint = true;
 4459 magnus                    753 ECB             :         }
  551 rhaas                     754 GIC         531 :         else if (strcmp(defel->defname, "wait") == 0)
 4442 magnus                    755 ECB             :         {
 4442 magnus                    756 GBC         135 :             if (o_nowait)
 4442 magnus                    757 UIC           0 :                 ereport(ERROR,
                                758                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 4442 magnus                    759 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     760 CBC         135 :             opt->nowait = !defGetBoolean(defel);
 4442 magnus                    761 GBC         135 :             o_nowait = true;
 4442 magnus                    762 EUB             :         }
 4452 magnus                    763 GIC         396 :         else if (strcmp(defel->defname, "wal") == 0)
 4452 magnus                    764 EUB             :         {
 4452 magnus                    765 GIC          24 :             if (o_wal)
 4452 magnus                    766 UIC           0 :                 ereport(ERROR,
                                767                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 4452 magnus                    768 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     769 GIC          24 :             opt->includewal = defGetBoolean(defel);
 4452 magnus                    770 CBC          24 :             o_wal = true;
                                771                 :         }
 3328 alvherre                  772             372 :         else if (strcmp(defel->defname, "max_rate") == 0)
 3328 alvherre                  773 EUB             :         {
                                774                 :             int64       maxrate;
                                775                 : 
 3328 alvherre                  776 CBC           1 :             if (o_maxrate)
 3328 alvherre                  777 LBC           0 :                 ereport(ERROR,
                                778                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 3328 alvherre                  779 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
                                780                 : 
  551 rhaas                     781 CBC           1 :             maxrate = defGetInt64(defel);
 3328 alvherre                  782 GBC           1 :             if (maxrate < MAX_RATE_LOWER || maxrate > MAX_RATE_UPPER)
 3328 alvherre                  783 UIC           0 :                 ereport(ERROR,
                                784                 :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 3328 alvherre                  785 ECB             :                          errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
 2118 tgl                       786                 :                                 (int) maxrate, "MAX_RATE", MAX_RATE_LOWER, MAX_RATE_UPPER)));
                                787                 : 
 3328 alvherre                  788 CBC           1 :             opt->maxrate = (uint32) maxrate;
 3328 alvherre                  789 GIC           1 :             o_maxrate = true;
                                790                 :         }
 2889 andrew                    791             371 :         else if (strcmp(defel->defname, "tablespace_map") == 0)
 2889 andrew                    792 ECB             :         {
 2889 andrew                    793 GBC          29 :             if (o_tablespace_map)
 2889 andrew                    794 UIC           0 :                 ereport(ERROR,
                                795                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                796                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     797 CBC          29 :             opt->sendtblspcmapfile = defGetBoolean(defel);
 2889 andrew                    798              29 :             o_tablespace_map = true;
 2889 andrew                    799 EUB             :         }
  551 rhaas                     800 GIC         342 :         else if (strcmp(defel->defname, "verify_checksums") == 0)
                                801                 :         {
 1832 magnus                    802               1 :             if (o_noverify_checksums)
 1832 magnus                    803 UIC           0 :                 ereport(ERROR,
 1832 magnus                    804 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                805                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
  551 rhaas                     806 GIC           1 :             noverify_checksums = !defGetBoolean(defel);
 1832 magnus                    807 CBC           1 :             o_noverify_checksums = true;
                                808                 :         }
 1101 rhaas                     809             341 :         else if (strcmp(defel->defname, "manifest") == 0)
 1101 rhaas                     810 EUB             :         {
  551 rhaas                     811 GIC         141 :             char       *optval = defGetString(defel);
                                812                 :             bool        manifest_bool;
 1101 rhaas                     813 ECB             : 
 1101 rhaas                     814 CBC         141 :             if (o_manifest)
 1101 rhaas                     815 UIC           0 :                 ereport(ERROR,
 1101 rhaas                     816 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                817                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
 1101 rhaas                     818 CBC         141 :             if (parse_bool(optval, &manifest_bool))
 1101 rhaas                     819 EUB             :             {
 1101 rhaas                     820 GIC         140 :                 if (manifest_bool)
                                821             140 :                     opt->manifest = MANIFEST_OPTION_YES;
 1101 rhaas                     822 ECB             :                 else
 1101 rhaas                     823 LBC           0 :                     opt->manifest = MANIFEST_OPTION_NO;
                                824                 :             }
 1101 rhaas                     825 CBC           1 :             else if (pg_strcasecmp(optval, "force-encode") == 0)
 1101 rhaas                     826 GIC           1 :                 opt->manifest = MANIFEST_OPTION_FORCE_ENCODE;
 1101 rhaas                     827 ECB             :             else
 1101 rhaas                     828 UIC           0 :                 ereport(ERROR,
                                829                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 1101 rhaas                     830 ECB             :                          errmsg("unrecognized manifest option: \"%s\"",
 1101 rhaas                     831 EUB             :                                 optval)));
 1101 rhaas                     832 GIC         141 :             o_manifest = true;
                                833                 :         }
 1101 rhaas                     834 CBC         200 :         else if (strcmp(defel->defname, "manifest_checksums") == 0)
                                835                 :         {
  551                           836               7 :             char       *optval = defGetString(defel);
 1101 rhaas                     837 ECB             : 
 1101 rhaas                     838 GIC           7 :             if (o_manifest_checksums)
 1101 rhaas                     839 UBC           0 :                 ereport(ERROR,
                                840                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
 1101 rhaas                     841 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
 1101 rhaas                     842 CBC           7 :             if (!pg_checksum_parse_type(optval,
                                843                 :                                         &opt->manifest_checksum_type))
 1101 rhaas                     844 GBC           1 :                 ereport(ERROR,
                                845                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                846                 :                          errmsg("unrecognized checksum algorithm: \"%s\"",
                                847                 :                                 optval)));
 1101 rhaas                     848 CBC           6 :             o_manifest_checksums = true;
                                849                 :         }
  446                           850             193 :         else if (strcmp(defel->defname, "target") == 0)
                                851                 :         {
                                852             141 :             if (o_target)
  446 rhaas                     853 UIC           0 :                 ereport(ERROR,
  446 rhaas                     854 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
  446 rhaas                     855 EUB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  390 rhaas                     856 GIC         141 :             target_str = defGetString(defel);
  446                           857             141 :             o_target = true;
  446 rhaas                     858 ECB             :         }
  509 rhaas                     859 GIC          52 :         else if (strcmp(defel->defname, "target_detail") == 0)
  509 rhaas                     860 ECB             :         {
  509 rhaas                     861 GIC           9 :             char       *optval = defGetString(defel);
                                862                 : 
                                863               9 :             if (o_target_detail)
  509 rhaas                     864 LBC           0 :                 ereport(ERROR,
                                865                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
  509 rhaas                     866 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  390 rhaas                     867 GIC           9 :             target_detail_str = optval;
  509 rhaas                     868 CBC           9 :             o_target_detail = true;
  509 rhaas                     869 EUB             :         }
  440 rhaas                     870 GIC          43 :         else if (strcmp(defel->defname, "compression") == 0)
                                871                 :         {
  440 rhaas                     872 CBC          29 :             char       *optval = defGetString(defel);
  440 rhaas                     873 ECB             : 
  440 rhaas                     874 GIC          29 :             if (o_compression)
  440 rhaas                     875 LBC           0 :                 ereport(ERROR,
                                876                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
  440 rhaas                     877 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  362 michael                   878 GIC          29 :             if (!parse_compress_algorithm(optval, &opt->compression))
  440 rhaas                     879 CBC           1 :                 ereport(ERROR,
  440 rhaas                     880 EUB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                881                 :                          errmsg("unrecognized compression algorithm: \"%s\"",
                                882                 :                                 optval)));
  440 rhaas                     883 CBC          28 :             o_compression = true;
  440 rhaas                     884 ECB             :         }
  382 rhaas                     885 GIC          14 :         else if (strcmp(defel->defname, "compression_detail") == 0)
  440 rhaas                     886 ECB             :         {
  382 rhaas                     887 GIC          14 :             if (o_compression_detail)
  440 rhaas                     888 LBC           0 :                 ereport(ERROR,
                                889                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
  440 rhaas                     890 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
  382 rhaas                     891 GBC          14 :             compression_detail_str = defGetString(defel);
  382 rhaas                     892 GIC          14 :             o_compression_detail = true;
                                893                 :         }
  440 rhaas                     894 ECB             :         else
  440 rhaas                     895 LBC           0 :             ereport(ERROR,
                                896                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                897                 :                      errmsg("unrecognized base backup option: \"%s\"",
                                898                 :                             defel->defname)));
 4459 magnus                    899 ECB             :     }
                                900                 : 
 4459 magnus                    901 CBC         140 :     if (opt->label == NULL)
 4459 magnus                    902 UIC           0 :         opt->label = "base backup";
 1101 rhaas                     903 CBC         140 :     if (opt->manifest == MANIFEST_OPTION_NO)
 1101 rhaas                     904 EUB             :     {
 1101 rhaas                     905 GIC           1 :         if (o_manifest_checksums)
 1101 rhaas                     906 UIC           0 :             ereport(ERROR,
 1101 rhaas                     907 ECB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                908                 :                      errmsg("manifest checksums require a backup manifest")));
 1101 rhaas                     909 GIC           1 :         opt->manifest_checksum_type = CHECKSUM_TYPE_NONE;
                                910                 :     }
  390 rhaas                     911 EUB             : 
  390 rhaas                     912 GIC         140 :     if (target_str == NULL)
                                913                 :     {
  390 rhaas                     914 UIC           0 :         if (target_detail_str != NULL)
  509                           915               0 :             ereport(ERROR,
                                916                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
  390 rhaas                     917 ECB             :                      errmsg("target detail cannot be used without target")));
  390 rhaas                     918 UBC           0 :         opt->use_copytblspc = true;
  390 rhaas                     919 LBC           0 :         opt->send_to_client = true;
                                920                 :     }
  390 rhaas                     921 CBC         140 :     else if (strcmp(target_str, "client") == 0)
  509 rhaas                     922 EUB             :     {
  390 rhaas                     923 GIC         125 :         if (target_detail_str != NULL)
  509 rhaas                     924 UIC           0 :             ereport(ERROR,
  509 rhaas                     925 ECB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                926                 :                      errmsg("target \"%s\" does not accept a target detail",
                                927                 :                             target_str)));
  390 rhaas                     928 CBC         125 :         opt->send_to_client = true;
                                929                 :     }
  390 rhaas                     930 EUB             :     else
  390 rhaas                     931 GBC          13 :         opt->target_handle =
  390 rhaas                     932 GIC          15 :             BaseBackupGetTargetHandle(target_str, target_detail_str);
                                933                 : 
  382 rhaas                     934 GBC         138 :     if (o_compression_detail && !o_compression)
  440 rhaas                     935 UBC           0 :         ereport(ERROR,
                                936                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
  197 peter                     937 ECB             :                  errmsg("compression detail cannot be specified unless compression is enabled")));
                                938                 : 
  382 rhaas                     939 CBC         138 :     if (o_compression)
  382 rhaas                     940 EUB             :     {
                                941                 :         char       *error_detail;
                                942                 : 
  362 michael                   943 GIC          26 :         parse_compress_specification(opt->compression, compression_detail_str,
  362 michael                   944 ECB             :                                      &opt->compression_specification);
                                945                 :         error_detail =
  362 michael                   946 GIC          26 :             validate_compress_specification(&opt->compression_specification);
  382 rhaas                     947 CBC          26 :         if (error_detail != NULL)
                                948               9 :             ereport(ERROR,
                                949                 :                     errcode(ERRCODE_SYNTAX_ERROR),
  382 rhaas                     950 ECB             :                     errmsg("invalid compression specification: %s",
  382 rhaas                     951 EUB             :                            error_detail));
                                952                 :     }
 4459 magnus                    953 GIC         129 : }
                                954                 : 
 4459 magnus                    955 ECB             : 
                                956                 : /*
                                957                 :  * SendBaseBackup() - send a complete base backup.
                                958                 :  *
  368 sfrost                    959                 :  * The function will put the system into backup mode like pg_backup_start()
                                960                 :  * does, so that the backup is consistent even though we read directly from
                                961                 :  * the filesystem, bypassing the buffer cache.
 4472 magnus                    962                 :  */
                                963                 : void
 4459 magnus                    964 CBC         143 : SendBaseBackup(BaseBackupCmd *cmd)
                                965                 : {
                                966                 :     basebackup_options opt;
                                967                 :     bbsink     *sink;
  271 fujii                     968 GIC         143 :     SessionBackupState status = get_backup_status();
  271 fujii                     969 ECB             : 
  271 fujii                     970 GIC         143 :     if (status == SESSION_BACKUP_RUNNING)
                                971               1 :         ereport(ERROR,
                                972                 :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                973                 :                  errmsg("a backup is already in progress in this session")));
                                974                 : 
 4459 magnus                    975             142 :     parse_basebackup_options(cmd->options, &opt);
                                976                 : 
 4471                           977             129 :     WalSndSetState(WALSNDSTATE_BACKUP);
                                978                 : 
 4472                           979             129 :     if (update_process_title)
 4472 magnus                    980 ECB             :     {
                                981                 :         char        activitymsg[50];
                                982                 : 
 4472 magnus                    983 GIC         129 :         snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"",
 4459 magnus                    984 ECB             :                  opt.label);
 1124 peter                     985 GIC         129 :         set_ps_display(activitymsg);
 4472 magnus                    986 ECB             :     }
                                987                 : 
                                988                 :     /*
                                989                 :      * If the target is specifically 'client' then set up to stream the backup
                                990                 :      * to the client; otherwise, it's being sent someplace else and should not
  390 rhaas                     991                 :      * be sent to the client. BaseBackupGetSink has the job of setting up a
                                992                 :      * sink to send the backup data wherever it needs to go.
  446                           993                 :      */
  390 rhaas                     994 GIC         129 :     sink = bbsink_copystream_new(opt.send_to_client);
  390 rhaas                     995 CBC         129 :     if (opt.target_handle != NULL)
  390 rhaas                     996 GIC          13 :         sink = BaseBackupGetSink(opt.target_handle, sink);
                                997                 : 
                                998                 :     /* Set up network throttling, if client requested it */
  520 rhaas                     999 CBC         126 :     if (opt.maxrate > 0)
  520 rhaas                    1000 GIC           1 :         sink = bbsink_throttle_new(sink, opt.maxrate);
 4472 magnus                   1001 ECB             : 
                               1002                 :     /* Set up server-side compression, if client requested it */
  362 michael                  1003 GIC         126 :     if (opt.compression == PG_COMPRESSION_GZIP)
  382 rhaas                    1004               2 :         sink = bbsink_gzip_new(sink, &opt.compression_specification);
  362 michael                  1005             124 :     else if (opt.compression == PG_COMPRESSION_LZ4)
  382 rhaas                    1006               2 :         sink = bbsink_lz4_new(sink, &opt.compression_specification);
  362 michael                  1007             122 :     else if (opt.compression == PG_COMPRESSION_ZSTD)
  382 rhaas                    1008               4 :         sink = bbsink_zstd_new(sink, &opt.compression_specification);
                               1009                 : 
  520 rhaas                    1010 ECB             :     /* Set up progress reporting. */
  520 rhaas                    1011 CBC         126 :     sink = bbsink_progress_new(sink, opt.progress);
 3602 bruce                    1012 ECB             : 
                               1013                 :     /*
                               1014                 :      * Perform the base backup, but make sure we clean up the bbsink even if
  520 rhaas                    1015                 :      * an error occurs.
 3734 heikki.linnakangas       1016                 :      */
  520 rhaas                    1017 GIC         126 :     PG_TRY();
                               1018                 :     {
  520 rhaas                    1019 CBC         126 :         perform_base_backup(&opt, sink);
  520 rhaas                    1020 ECB             :     }
  520 rhaas                    1021 CBC           4 :     PG_FINALLY();
  520 rhaas                    1022 ECB             :     {
  520 rhaas                    1023 CBC         121 :         bbsink_cleanup(sink);
  520 rhaas                    1024 ECB             :     }
  520 rhaas                    1025 GIC         121 :     PG_END_TRY();
 4448 magnus                   1026             117 : }
 4448 magnus                   1027 ECB             : 
                               1028                 : /*
                               1029                 :  * Inject a file with given name and content in the output tar stream.
                               1030                 :  */
                               1031                 : static void
  520 rhaas                    1032 GIC         170 : sendFileWithContent(bbsink *sink, const char *filename, const char *content,
 1081 rhaas                    1033 ECB             :                     backup_manifest_info *manifest)
                               1034                 : {
 4451 heikki.linnakangas       1035                 :     struct stat statbuf;
  520 rhaas                    1036 GIC         170 :     int         bytes_done = 0,
 4382 bruce                    1037 ECB             :                 len;
                               1038                 :     pg_checksum_context checksum_ctx;
 1101 rhaas                    1039                 : 
  858 michael                  1040 GIC         170 :     if (pg_checksum_init(&checksum_ctx, manifest->checksum_type) < 0)
  858 michael                  1041 LBC           0 :         elog(ERROR, "could not initialize checksum of file \"%s\"",
  858 michael                  1042 ECB             :              filename);
                               1043                 : 
 4451 heikki.linnakangas       1044 GIC         170 :     len = strlen(content);
                               1045                 : 
                               1046                 :     /*
                               1047                 :      * Construct a stat struct for the backup_label file we're injecting in
 4382 bruce                    1048 ECB             :      * the tar.
                               1049                 :      */
                               1050                 :     /* Windows doesn't have the concept of uid and gid */
                               1051                 : #ifdef WIN32
 4451 heikki.linnakangas       1052                 :     statbuf.st_uid = 0;
                               1053                 :     statbuf.st_gid = 0;
                               1054                 : #else
 4451 heikki.linnakangas       1055 GIC         170 :     statbuf.st_uid = geteuid();
 4451 heikki.linnakangas       1056 CBC         170 :     statbuf.st_gid = getegid();
 4451 heikki.linnakangas       1057 EUB             : #endif
 4451 heikki.linnakangas       1058 GIC         170 :     statbuf.st_mtime = time(NULL);
 1828 sfrost                   1059             170 :     statbuf.st_mode = pg_file_create_mode;
 4451 heikki.linnakangas       1060 CBC         170 :     statbuf.st_size = len;
                               1061                 : 
  520 rhaas                    1062 GIC         170 :     _tarWriteHeader(sink, filename, NULL, &statbuf, false);
                               1063                 : 
                               1064             170 :     if (pg_checksum_update(&checksum_ctx, (uint8 *) content, len) < 0)
  520 rhaas                    1065 UIC           0 :         elog(ERROR, "could not update checksum of file \"%s\"",
                               1066                 :              filename);
                               1067                 : 
  520 rhaas                    1068 GIC         298 :     while (bytes_done < len)
                               1069                 :     {
                               1070             128 :         size_t      remaining = len - bytes_done;
  520 rhaas                    1071 CBC         128 :         size_t      nbytes = Min(sink->bbs_buffer_length, remaining);
 4382 bruce                    1072 ECB             : 
  520 rhaas                    1073 GIC         128 :         memcpy(sink->bbs_buffer, content, nbytes);
  520 rhaas                    1074 CBC         128 :         bbsink_archive_contents(sink, nbytes);
                               1075             128 :         bytes_done += nbytes;
  118                          1076             128 :         content += nbytes;
                               1077                 :     }
 1101 rhaas                    1078 ECB             : 
  520 rhaas                    1079 GIC         170 :     _tarWritePadding(sink, len);
  858 michael                  1080 ECB             : 
 1081 rhaas                    1081 GBC         170 :     AddFileToBackupManifest(manifest, NULL, filename, len,
 1081 rhaas                    1082 GIC         170 :                             (pg_time_t) statbuf.st_mtime, &checksum_ctx);
 4451 heikki.linnakangas       1083             170 : }
 4472 magnus                   1084 ECB             : 
                               1085                 : /*
 3667 heikki.linnakangas       1086                 :  * Include the tablespace directory pointed to by 'path' in the output tar
 3260 bruce                    1087                 :  * stream.  If 'sizeonly' is true, we just calculate a total length and return
                               1088                 :  * it, without actually sending anything.
 3379 magnus                   1089                 :  *
                               1090                 :  * Only used to send auxiliary tablespaces, not PGDATA.
 3667 heikki.linnakangas       1091                 :  */
 1026 rhaas                    1092                 : static int64
  520 rhaas                    1093 GIC          32 : sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
                               1094                 :                backup_manifest_info *manifest)
 3667 heikki.linnakangas       1095 ECB             : {
                               1096                 :     int64       size;
                               1097                 :     char        pathbuf[MAXPGPATH];
                               1098                 :     struct stat statbuf;
                               1099                 : 
                               1100                 :     /*
                               1101                 :      * 'path' points to the tablespace location, but we only want to include
                               1102                 :      * the version directory in it that belongs to us.
                               1103                 :      */
 3667 heikki.linnakangas       1104 GIC          32 :     snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path,
                               1105                 :              TABLESPACE_VERSION_DIRECTORY);
                               1106                 : 
                               1107                 :     /*
                               1108                 :      * Store a directory entry in the tar file so we get the permissions
 3602 bruce                    1109 ECB             :      * right.
                               1110                 :      */
 3667 heikki.linnakangas       1111 GIC          32 :     if (lstat(pathbuf, &statbuf) != 0)
                               1112                 :     {
 3667 heikki.linnakangas       1113 UIC           0 :         if (errno != ENOENT)
                               1114               0 :             ereport(ERROR,
                               1115                 :                     (errcode_for_file_access(),
                               1116                 :                      errmsg("could not stat file or directory \"%s\": %m",
                               1117                 :                             pathbuf)));
                               1118                 : 
                               1119                 :         /* If the tablespace went away while scanning, it's no error. */
 3667 heikki.linnakangas       1120 LBC           0 :         return 0;
                               1121                 :     }
                               1122                 : 
  520 rhaas                    1123 GIC          32 :     size = _tarWriteHeader(sink, TABLESPACE_VERSION_DIRECTORY, NULL, &statbuf,
                               1124                 :                            sizeonly);
                               1125                 : 
                               1126                 :     /* Send all the files in the tablespace version directory */
  520 rhaas                    1127 CBC          32 :     size += sendDir(sink, pathbuf, strlen(path), sizeonly, NIL, true, manifest,
                               1128                 :                     spcoid);
 3667 heikki.linnakangas       1129 EUB             : 
 3667 heikki.linnakangas       1130 GBC          32 :     return size;
                               1131                 : }
                               1132                 : 
                               1133                 : /*
                               1134                 :  * Include all files from the given directory in the output tar stream. If
                               1135                 :  * 'sizeonly' is true, we just calculate a total length and return it, without
 4451 heikki.linnakangas       1136 EUB             :  * actually sending anything.
                               1137                 :  *
                               1138                 :  * Omit any directory in the tablespaces list, to avoid backing up
 3379 magnus                   1139 ECB             :  * tablespaces twice when they were created inside PGDATA.
                               1140                 :  *
                               1141                 :  * If sendtblspclinks is true, we need to include symlink
                               1142                 :  * information in the tar file. If not, we can skip that
 2889 andrew                   1143                 :  * as it will be sent separately in the tablespace_map file.
                               1144                 :  */
                               1145                 : static int64
  520 rhaas                    1146 CBC        4316 : sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
                               1147                 :         List *tablespaces, bool sendtblspclinks, backup_manifest_info *manifest,
                               1148                 :         const char *spcoid)
                               1149                 : {
                               1150                 :     DIR        *dir;
                               1151                 :     struct dirent *de;
                               1152                 :     char        pathbuf[MAXPGPATH * 2];
                               1153                 :     struct stat statbuf;
 4472 magnus                   1154 GIC        4316 :     int64       size = 0;
                               1155                 :     const char *lastDir;        /* Split last dir from parent path. */
 1809 tgl                      1156            4316 :     bool        isDbDir = false;    /* Does this directory contain relations? */
                               1157                 : 
                               1158                 :     /*
                               1159                 :      * Determine if the current path is a database directory that can contain
                               1160                 :      * relations.
                               1161                 :      *
 1809 tgl                      1162 ECB             :      * Start by finding the location of the delimiter between the parent path
                               1163                 :      * and the current path.
                               1164                 :      */
 1843 teodor                   1165 GIC        4316 :     lastDir = last_dir_separator(path);
                               1166                 : 
                               1167                 :     /* Does this path look like a database path (i.e. all digits)? */
                               1168            4316 :     if (lastDir != NULL &&
                               1169            4064 :         strspn(lastDir + 1, "0123456789") == strlen(lastDir + 1))
 1843 teodor                   1170 ECB             :     {
                               1171                 :         /* Part of path that contains the parent directory. */
 1809 tgl                      1172 CBC         811 :         int         parentPathLen = lastDir - path;
                               1173                 : 
                               1174                 :         /*
                               1175                 :          * Mark path as a database directory if the parent path is either
                               1176                 :          * $PGDATA/base or a tablespace version path.
                               1177                 :          */
 1843 teodor                   1178 GIC         811 :         if (strncmp(path, "./base", parentPathLen) == 0 ||
                               1179              54 :             (parentPathLen >= (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) &&
                               1180              32 :              strncmp(lastDir - (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1),
 1843 teodor                   1181 ECB             :                      TABLESPACE_VERSION_DIRECTORY,
                               1182                 :                      sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) == 0))
 1843 teodor                   1183 GIC         789 :             isDbDir = true;
 1843 teodor                   1184 ECB             :     }
 4472 magnus                   1185                 : 
 4472 magnus                   1186 GIC        4316 :     dir = AllocateDir(path);
                               1187          263588 :     while ((de = ReadDir(dir, path)) != NULL)
 4472 magnus                   1188 ECB             :     {
                               1189                 :         int         excludeIdx;
                               1190                 :         bool        excludeFound;
                               1191                 :         ForkNumber  relForkNum; /* Type of fork if file is a relation */
                               1192                 :         int         relnumchars;    /* Chars in filename that are the
                               1193                 :                                      * relnumber */
                               1194                 : 
                               1195                 :         /* Skip special stuff */
 4472 magnus                   1196 CBC      259286 :         if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
                               1197           12211 :             continue;
                               1198                 : 
                               1199                 :         /* Skip temporary files */
      heikki.linnakangas       1200          250667 :         if (strncmp(de->d_name,
                               1201                 :                     PG_TEMP_FILE_PREFIX,
                               1202                 :                     strlen(PG_TEMP_FILE_PREFIX)) == 0)
                               1203             247 :             continue;
 4472 heikki.linnakangas       1204 ECB             : 
                               1205                 :         /*
                               1206                 :          * Check if the postmaster has signaled us to exit, and abort with an
                               1207                 :          * error in that case. The error handler further up will call
                               1208                 :          * do_pg_abort_backup() for us. Also check that if the backup was
                               1209                 :          * started while still in recovery, the server wasn't promoted.
                               1210                 :          * do_pg_backup_stop() will check that too, but it's better to stop
                               1211                 :          * the backup early than continue to the end and fail there.
                               1212                 :          */
 3769 heikki.linnakangas       1213 CBC      250420 :         CHECK_FOR_INTERRUPTS();
                               1214          250415 :         if (RecoveryInProgress() != backup_started_in_recovery)
 4468 magnus                   1215 UIC           0 :             ereport(ERROR,
                               1216                 :                     (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 3769 heikki.linnakangas       1217 ECB             :                      errmsg("the standby was promoted during online backup"),
                               1218                 :                      errhint("This means that the backup being taken is corrupt "
                               1219                 :                              "and should not be used. "
 2118 tgl                      1220                 :                              "Try taking another online backup.")));
                               1221                 : 
                               1222                 :         /* Scan for files that should be excluded */
 2384 peter_e                  1223 GIC      250415 :         excludeFound = false;
 1140 michael                  1224         2249800 :         for (excludeIdx = 0; excludeFiles[excludeIdx].name != NULL; excludeIdx++)
                               1225                 :         {
                               1226         2000384 :             int         cmplen = strlen(excludeFiles[excludeIdx].name);
                               1227                 : 
                               1228         2000384 :             if (!excludeFiles[excludeIdx].match_prefix)
                               1229         1750103 :                 cmplen++;
 1140 michael                  1230 CBC     2000384 :             if (strncmp(de->d_name, excludeFiles[excludeIdx].name, cmplen) == 0)
 2384 peter_e                  1231 ECB             :             {
 2384 peter_e                  1232 GBC         999 :                 elog(DEBUG1, "file \"%s\" excluded from backup", de->d_name);
 2384 peter_e                  1233 GIC         999 :                 excludeFound = true;
                               1234             999 :                 break;
                               1235                 :             }
                               1236                 :         }
                               1237                 : 
                               1238          250415 :         if (excludeFound)
 4472 magnus                   1239             999 :             continue;
 4472 magnus                   1240 ECB             : 
 1843 teodor                   1241                 :         /* Exclude all forks for unlogged tables except the init fork */
 1843 teodor                   1242 GIC      475116 :         if (isDbDir &&
  255 rhaas                    1243 GNC      225700 :             parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
                               1244                 :                                                 &relForkNum))
 1843 teodor                   1245 ECB             :         {
                               1246                 :             /* Never exclude init forks */
 1843 teodor                   1247 CBC      224148 :             if (relForkNum != INIT_FORKNUM)
                               1248                 :             {
 1809 tgl                      1249 ECB             :                 char        initForkFile[MAXPGPATH];
                               1250                 :                 char        relNumber[OIDCHARS + 1];
 1843 teodor                   1251                 : 
                               1252                 :                 /*
                               1253                 :                  * If any other type of fork, check if there is an init fork
                               1254                 :                  * with the same RelFileNumber. If so, the file can be
                               1255                 :                  * excluded.
                               1256                 :                  */
  255 rhaas                    1257 GNC      224079 :                 memcpy(relNumber, de->d_name, relnumchars);
                               1258          224079 :                 relNumber[relnumchars] = '\0';
 1843 teodor                   1259 GIC      224079 :                 snprintf(initForkFile, sizeof(initForkFile), "%s/%s_init",
                               1260                 :                          path, relNumber);
 1843 teodor                   1261 ECB             : 
 1843 teodor                   1262 GIC      224079 :                 if (lstat(initForkFile, &statbuf) == 0)
                               1263                 :                 {
                               1264              69 :                     elog(DEBUG2,
 1843 teodor                   1265 ECB             :                          "unlogged relation file \"%s\" excluded from backup",
                               1266                 :                          de->d_name);
                               1267                 : 
 1843 teodor                   1268 GIC          69 :                     continue;
                               1269                 :                 }
                               1270                 :             }
                               1271                 :         }
                               1272                 : 
                               1273                 :         /* Exclude temporary relations */
 1839                          1274          249347 :         if (isDbDir && looks_like_temp_rel_name(de->d_name))
 1839 teodor                   1275 ECB             :         {
 1839 teodor                   1276 CBC          40 :             elog(DEBUG2,
 1839 teodor                   1277 ECB             :                  "temporary relation file \"%s\" excluded from backup",
                               1278                 :                  de->d_name);
                               1279                 : 
 1839 teodor                   1280 CBC          40 :             continue;
                               1281                 :         }
 1839 teodor                   1282 ECB             : 
 2189 peter_e                  1283 GIC      249307 :         snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
                               1284                 : 
                               1285                 :         /* Skip pg_control here to back up it last */
 4092 simon                    1286 CBC      249307 :         if (strcmp(pathbuf, "./global/pg_control") == 0)
 4092 simon                    1287 GIC         247 :             continue;
                               1288                 : 
 4472 magnus                   1289          249060 :         if (lstat(pathbuf, &statbuf) != 0)
                               1290                 :         {
 4472 magnus                   1291 UIC           0 :             if (errno != ENOENT)
 4472 magnus                   1292 LBC           0 :                 ereport(ERROR,
                               1293                 :                         (errcode_for_file_access(),
 4472 magnus                   1294 ECB             :                          errmsg("could not stat file or directory \"%s\": %m",
                               1295                 :                                 pathbuf)));
                               1296                 : 
                               1297                 :             /* If the file went away while scanning, it's not an error. */
 4472 magnus                   1298 LBC           0 :             continue;
                               1299                 :         }
                               1300                 : 
 2384 peter_e                  1301 ECB             :         /* Scan for directories whose contents should be excluded */
 2384 peter_e                  1302 GIC      249060 :         excludeFound = false;
                               1303         1985521 :         for (excludeIdx = 0; excludeDirContents[excludeIdx] != NULL; excludeIdx++)
 3352 fujii                    1304 ECB             :         {
 2384 peter_e                  1305 CBC     1738199 :             if (strcmp(de->d_name, excludeDirContents[excludeIdx]) == 0)
                               1306                 :             {
                               1307            1738 :                 elog(DEBUG1, "contents of directory \"%s\" excluded from backup", de->d_name);
  544 rhaas                    1308 GIC        1738 :                 convert_link_to_directory(pathbuf, &statbuf);
  520 rhaas                    1309 GBC        1738 :                 size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, NULL,
  520 rhaas                    1310 EUB             :                                         &statbuf, sizeonly);
 2384 peter_e                  1311 GIC        1738 :                 excludeFound = true;
                               1312            1738 :                 break;
                               1313                 :             }
                               1314                 :         }
                               1315                 : 
 2384 peter_e                  1316 GBC      249060 :         if (excludeFound)
 2384 peter_e                  1317 GIC        1738 :             continue;
                               1318                 : 
                               1319                 :         /*
 2362 rhaas                    1320 ECB             :          * We can skip pg_wal, the WAL segments need to be fetched from the
 4472 magnus                   1321                 :          * WAL archive anyway. But include it as an empty directory anyway, so
                               1322                 :          * we get permissions right.
                               1323                 :          */
 2362 rhaas                    1324 GIC      247322 :         if (strcmp(pathbuf, "./pg_wal") == 0)
 4472 magnus                   1325 ECB             :         {
 2362 rhaas                    1326                 :             /* If pg_wal is a symlink, write it as a directory anyway */
  544 rhaas                    1327 CBC         252 :             convert_link_to_directory(pathbuf, &statbuf);
  520 rhaas                    1328 GIC         252 :             size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, NULL,
  520 rhaas                    1329 ECB             :                                     &statbuf, sizeonly);
 3018 andres                   1330                 : 
                               1331                 :             /*
                               1332                 :              * Also send archive_status directory (by hackishly reusing
                               1333                 :              * statbuf from above ...).
                               1334                 :              */
  520 rhaas                    1335 CBC         252 :             size += _tarWriteHeader(sink, "./pg_wal/archive_status", NULL,
                               1336                 :                                     &statbuf, sizeonly);
                               1337                 : 
 2362 rhaas                    1338 GIC         252 :             continue;           /* don't recurse into pg_wal */
                               1339                 :         }
                               1340                 : 
                               1341                 :         /* Allow symbolic links in pg_tblspc only */
  246 tmunro                   1342 GNC      247070 :         if (strcmp(path, "./pg_tblspc") == 0 && S_ISLNK(statbuf.st_mode))
 4472 magnus                   1343 GIC          29 :         {
                               1344                 :             char        linkpath[MAXPGPATH];
                               1345                 :             int         rllen;
 4472 magnus                   1346 ECB             : 
 4141 tgl                      1347 GIC          29 :             rllen = readlink(pathbuf, linkpath, sizeof(linkpath));
                               1348              29 :             if (rllen < 0)
 4472 magnus                   1349 LBC           0 :                 ereport(ERROR,
                               1350                 :                         (errcode_for_file_access(),
                               1351                 :                          errmsg("could not read symbolic link \"%s\": %m",
                               1352                 :                                 pathbuf)));
 4141 tgl                      1353 CBC          29 :             if (rllen >= sizeof(linkpath))
 4141 tgl                      1354 LBC           0 :                 ereport(ERROR,
                               1355                 :                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                               1356                 :                          errmsg("symbolic link \"%s\" target is too long",
                               1357                 :                                 pathbuf)));
 4141 tgl                      1358 CBC          29 :             linkpath[rllen] = '\0';
 4141 tgl                      1359 ECB             : 
  520 rhaas                    1360 GBC          29 :             size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, linkpath,
                               1361                 :                                     &statbuf, sizeonly);
 4472 magnus                   1362 ECB             :         }
 4472 magnus                   1363 GIC      247041 :         else if (S_ISDIR(statbuf.st_mode))
 4472 magnus                   1364 ECB             :         {
 3379 magnus                   1365 GIC        4056 :             bool        skip_this_dir = false;
                               1366                 :             ListCell   *lc;
                               1367                 : 
                               1368                 :             /*
                               1369                 :              * Store a directory entry in the tar file so we can get the
                               1370                 :              * permissions right.
 4472 magnus                   1371 ECB             :              */
  520 rhaas                    1372 GIC        4056 :             size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, NULL, &statbuf,
                               1373                 :                                     sizeonly);
                               1374                 : 
                               1375                 :             /*
                               1376                 :              * Call ourselves recursively for a directory, unless it happens
                               1377                 :              * to be a separate tablespace located within PGDATA.
 3379 magnus                   1378 ECB             :              */
 3379 magnus                   1379 GIC        8580 :             foreach(lc, tablespaces)
 3379 magnus                   1380 ECB             :             {
 3379 magnus                   1381 GIC        4524 :                 tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc);
                               1382                 : 
                               1383                 :                 /*
                               1384                 :                  * ti->rpath is the tablespace relative path within PGDATA, or
                               1385                 :                  * NULL if the tablespace has been properly located somewhere
                               1386                 :                  * else.
                               1387                 :                  *
                               1388                 :                  * Skip past the leading "./" in pathbuf when comparing.
 3379 magnus                   1389 ECB             :                  */
 3379 magnus                   1390 GIC        4524 :                 if (ti->rpath && strcmp(ti->rpath, pathbuf + 2) == 0)
 3379 magnus                   1391 EUB             :                 {
 3379 magnus                   1392 UBC           0 :                     skip_this_dir = true;
 3379 magnus                   1393 UIC           0 :                     break;
                               1394                 :                 }
                               1395                 :             }
                               1396                 : 
                               1397                 :             /*
                               1398                 :              * skip sending directories inside pg_tblspc, if not required.
 2889 andrew                   1399 ECB             :              */
 2889 andrew                   1400 CBC        4056 :             if (strcmp(pathbuf, "./pg_tblspc") == 0 && !sendtblspclinks)
 2889 andrew                   1401 GIC          24 :                 skip_this_dir = true;
 2889 andrew                   1402 ECB             : 
 3379 magnus                   1403 CBC        4056 :             if (!skip_this_dir)
  520 rhaas                    1404 GIC        4032 :                 size += sendDir(sink, pathbuf, basepathlen, sizeonly, tablespaces,
                               1405                 :                                 sendtblspclinks, manifest, spcoid);
 4472 magnus                   1406 ECB             :         }
 4472 magnus                   1407 GIC      242985 :         else if (S_ISREG(statbuf.st_mode))
 4472 magnus                   1408 ECB             :         {
 3602 bruce                    1409 GIC      242985 :             bool        sent = false;
 3761 heikki.linnakangas       1410 ECB             : 
 4472 magnus                   1411 CBC      242985 :             if (!sizeonly)
  520 rhaas                    1412          229966 :                 sent = sendFile(sink, pathbuf, pathbuf + basepathlen + 1, &statbuf,
 1101 rhaas                    1413 GIC      110721 :                                 true, isDbDir ? atooid(lastDir + 1) : InvalidOid,
                               1414                 :                                 manifest, spcoid);
 3761 heikki.linnakangas       1415 ECB             : 
 3761 heikki.linnakangas       1416 GIC      242984 :             if (sent || sizeonly)
                               1417                 :             {
 1080 rhaas                    1418 ECB             :                 /* Add size. */
 1080 rhaas                    1419 GIC      242984 :                 size += statbuf.st_size;
                               1420                 : 
 1080 rhaas                    1421 ECB             :                 /* Pad to a multiple of the tar block size. */
 1080 rhaas                    1422 GIC      242984 :                 size += tarPaddingBytesRequired(statbuf.st_size);
                               1423                 : 
 1080 rhaas                    1424 ECB             :                 /* Size of the header for the file. */
 1080 rhaas                    1425 GIC      242984 :                 size += TAR_BLOCK_SIZE;
                               1426                 :             }
                               1427                 :         }
 4472 magnus                   1428 EUB             :         else
 4472 magnus                   1429 UIC           0 :             ereport(WARNING,
                               1430                 :                     (errmsg("skipping special file \"%s\"", pathbuf)));
 4472 magnus                   1431 ECB             :     }
 4472 magnus                   1432 CBC        4302 :     FreeDir(dir);
 4472 magnus                   1433 GIC        4302 :     return size;
                               1434                 : }
                               1435                 : 
                               1436                 : /*
                               1437                 :  * Check if a file should have its checksum validated.
                               1438                 :  * We validate checksums on files in regular tablespaces
                               1439                 :  * (including global and default) only, and in those there
                               1440                 :  * are some files that are explicitly excluded.
                               1441                 :  */
 1832 magnus                   1442 ECB             : static bool
 1832 magnus                   1443 GIC       28387 : is_checksummed_file(const char *fullpath, const char *filename)
                               1444                 : {
 1832 magnus                   1445 ECB             :     /* Check that the file is in a tablespace */
 1832 magnus                   1446 CBC       28387 :     if (strncmp(fullpath, "./global/", 9) == 0 ||
                               1447           26618 :         strncmp(fullpath, "./base/", 7) == 0 ||
 1832 magnus                   1448 GIC         329 :         strncmp(fullpath, "/", 1) == 0)
                               1449                 :     {
                               1450                 :         int         excludeIdx;
                               1451                 : 
 1140 michael                  1452 ECB             :         /* Compare file against noChecksumFiles skip list */
 1140 michael                  1453 GIC      139874 :         for (excludeIdx = 0; noChecksumFiles[excludeIdx].name != NULL; excludeIdx++)
 1140 michael                  1454 ECB             :         {
 1140 michael                  1455 GIC      112016 :             int         cmplen = strlen(noChecksumFiles[excludeIdx].name);
 1140 michael                  1456 ECB             : 
 1140 michael                  1457 CBC      112016 :             if (!noChecksumFiles[excludeIdx].match_prefix)
                               1458           84071 :                 cmplen++;
 1140 michael                  1459 GIC      112016 :             if (strncmp(filename, noChecksumFiles[excludeIdx].name,
 1140 michael                  1460 ECB             :                         cmplen) == 0)
 1832 magnus                   1461 GIC         205 :                 return false;
                               1462                 :         }
 1832 magnus                   1463 ECB             : 
 1832 magnus                   1464 GIC       27858 :         return true;
                               1465                 :     }
 1832 magnus                   1466 ECB             :     else
 1832 magnus                   1467 GIC         324 :         return false;
                               1468                 : }
                               1469                 : 
                               1470                 : /*
                               1471                 :  * Given the member, write the TAR header & send the file.
                               1472                 :  *
                               1473                 :  * If 'missing_ok' is true, will not throw an error if the file is not found.
 3761 heikki.linnakangas       1474 ECB             :  *
                               1475                 :  * If dboid is anything other than InvalidOid then any checksum failures
                               1476                 :  * detected will get reported to the cumulative stats system.
                               1477                 :  *
                               1478                 :  * Returns true if the file was successfully sent, false if 'missing_ok',
                               1479                 :  * and the file did not exist.
                               1480                 :  */
                               1481                 : static bool
  520 rhaas                    1482 CBC      119365 : sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
                               1483                 :          struct stat *statbuf, bool missing_ok, Oid dboid,
                               1484                 :          backup_manifest_info *manifest, const char *spcoid)
 4472 magnus                   1485 ECB             : {
                               1486                 :     int         fd;
 1832 magnus                   1487 GIC      119365 :     BlockNumber blkno = 0;
 1832 magnus                   1488 CBC      119365 :     bool        block_retry = false;
                               1489                 :     uint16      checksum;
                               1490          119365 :     int         checksum_failures = 0;
                               1491                 :     off_t       cnt;
                               1492                 :     int         i;
 4472                          1493          119365 :     pgoff_t     len = 0;
 1832 magnus                   1494 EUB             :     char       *page;
                               1495                 :     PageHeader  phdr;
 1832 magnus                   1496 GIC      119365 :     int         segmentno = 0;
 1832 magnus                   1497 ECB             :     char       *segmentpath;
 1832 magnus                   1498 CBC      119365 :     bool        verify_checksum = false;
                               1499                 :     pg_checksum_context checksum_ctx;
 1101 rhaas                    1500 EUB             : 
  858 michael                  1501 GBC      119365 :     if (pg_checksum_init(&checksum_ctx, manifest->checksum_type) < 0)
  858 michael                  1502 UBC           0 :         elog(ERROR, "could not initialize checksum of file \"%s\"",
                               1503                 :              readfilename);
                               1504                 : 
 1026 rhaas                    1505 GIC      119365 :     fd = OpenTransientFile(readfilename, O_RDONLY | PG_BINARY);
                               1506          119365 :     if (fd < 0)
 3761 heikki.linnakangas       1507 ECB             :     {
 3761 heikki.linnakangas       1508 UIC           0 :         if (errno == ENOENT && missing_ok)
 3761 heikki.linnakangas       1509 LBC           0 :             return false;
 4472 magnus                   1510 UIC           0 :         ereport(ERROR,
                               1511                 :                 (errcode_for_file_access(),
                               1512                 :                  errmsg("could not open file \"%s\": %m", readfilename)));
                               1513                 :     }
                               1514                 : 
  520 rhaas                    1515 GIC      119365 :     _tarWriteHeader(sink, tarfilename, NULL, statbuf, false);
                               1516                 : 
 1826 magnus                   1517          119364 :     if (!noverify_checksums && DataChecksumsEnabled())
 1832 magnus                   1518 ECB             :     {
                               1519                 :         char       *filename;
                               1520                 : 
                               1521                 :         /*
                               1522                 :          * Get the filename (excluding path).  As last_dir_separator()
                               1523                 :          * includes the last directory separator, we chop that off by
                               1524                 :          * incrementing the pointer.
                               1525                 :          */
 1832 magnus                   1526 GIC       28387 :         filename = last_dir_separator(readfilename) + 1;
                               1527                 : 
 1832 magnus                   1528 CBC       28387 :         if (is_checksummed_file(readfilename, filename))
 1832 magnus                   1529 ECB             :         {
 1832 magnus                   1530 GIC       27858 :             verify_checksum = true;
 1832 magnus                   1531 EUB             : 
                               1532                 :             /*
                               1533                 :              * Cut off at the segment boundary (".") to get the segment number
                               1534                 :              * in order to mix it into the checksum.
                               1535                 :              */
 1832 magnus                   1536 GIC       27858 :             segmentpath = strstr(filename, ".");
                               1537           27858 :             if (segmentpath != NULL)
                               1538                 :             {
 1832 magnus                   1539 UIC           0 :                 segmentno = atoi(segmentpath + 1);
                               1540               0 :                 if (segmentno == 0)
                               1541               0 :                     ereport(ERROR,
                               1542                 :                             (errmsg("invalid segment number %d in file \"%s\"",
                               1543                 :                                     segmentno, filename)));
                               1544                 :             }
                               1545                 :         }
 1832 magnus                   1546 ECB             :     }
                               1547                 : 
 1026 rhaas                    1548                 :     /*
                               1549                 :      * Loop until we read the amount of data the caller told us to expect. The
                               1550                 :      * file could be longer, if it was extended while we were sending it, but
                               1551                 :      * for a base backup we can ignore such extended data. It will be restored
                               1552                 :      * from WAL.
                               1553                 :      */
 1026 rhaas                    1554 GIC      265468 :     while (len < statbuf->st_size)
                               1555                 :     {
  520                          1556          146104 :         size_t      remaining = statbuf->st_size - len;
                               1557                 : 
                               1558                 :         /* Try to read some more data. */
                               1559          292208 :         cnt = basebackup_read_file(fd, sink->bbs_buffer,
                               1560          146104 :                                    Min(sink->bbs_buffer_length, remaining),
 1026 rhaas                    1561 ECB             :                                    len, readfilename, true);
                               1562                 : 
 1832 magnus                   1563                 :         /*
                               1564                 :          * The checksums are verified at block level, so we iterate over the
 1809 tgl                      1565 EUB             :          * buffer in chunks of BLCKSZ, after making sure that
                               1566                 :          * TAR_SEND_SIZE/buf is divisible by BLCKSZ and we read a multiple of
                               1567                 :          * BLCKSZ bytes.
                               1568                 :          */
  520 rhaas                    1569 GIC      146104 :         Assert((sink->bbs_buffer_length % BLCKSZ) == 0);
 1832 magnus                   1570 EUB             : 
 1832 magnus                   1571 GIC      146104 :         if (verify_checksum && (cnt % BLCKSZ != 0))
                               1572                 :         {
 1832 magnus                   1573 LBC           0 :             ereport(WARNING,
                               1574                 :                     (errmsg("could not verify checksum in file \"%s\", block "
  722 peter                    1575 ECB             :                             "%u: read buffer size %d and page size %d "
                               1576                 :                             "differ",
 1832 magnus                   1577                 :                             readfilename, blkno, (int) cnt, BLCKSZ)));
 1832 magnus                   1578 UIC           0 :             verify_checksum = false;
                               1579                 :         }
                               1580                 : 
 1832 magnus                   1581 GIC      146104 :         if (verify_checksum)
                               1582                 :         {
                               1583          118694 :             for (i = 0; i < cnt / BLCKSZ; i++)
                               1584                 :             {
  520 rhaas                    1585           84496 :                 page = sink->bbs_buffer + BLCKSZ * i;
                               1586                 : 
 1832 magnus                   1587 ECB             :                 /*
                               1588                 :                  * Only check pages which have not been modified since the
                               1589                 :                  * start of the base backup. Otherwise, they might have been
                               1590                 :                  * written only halfway and the checksum would not be valid.
                               1591                 :                  * However, replaying WAL would reinstate the correct page in
                               1592                 :                  * this case. We also skip completely new pages, since they
                               1593                 :                  * don't have a checksum yet.
                               1594                 :                  */
  520 rhaas                    1595 GIC       84496 :                 if (!PageIsNew(page) && PageGetLSN(page) < sink->bbs_state->startptr)
                               1596                 :                 {
 1832 magnus                   1597           84496 :                     checksum = pg_checksum_page((char *) page, blkno + segmentno * RELSEG_SIZE);
                               1598           84496 :                     phdr = (PageHeader) page;
                               1599           84496 :                     if (phdr->pd_checksum != checksum)
                               1600                 :                     {
                               1601                 :                         /*
                               1602                 :                          * Retry the block on the first failure.  It's
                               1603                 :                          * possible that we read the first 4K page of the
                               1604                 :                          * block just before postgres updated the entire block
                               1605                 :                          * so it ends up looking torn to us. If, before we
                               1606                 :                          * retry the read, the concurrent write of the block
                               1607                 :                          * finishes, the page LSN will be updated and we'll
                               1608                 :                          * realize that we should ignore this block.
                               1609                 :                          *
                               1610                 :                          * There's no guarantee that this will actually
                               1611                 :                          * happen, though: the torn write could take an
                               1612                 :                          * arbitrarily long time to complete. Retrying multiple
                               1613                 :                          * times wouldn't fix this problem, either, though
                               1614                 :                          * it would reduce the chances of it happening in
                               1615                 :                          * practice. The only real fix here seems to be to
                               1616                 :                          * have some kind of interlock that allows us to wait
                               1617                 :                          * until we can be certain that no write to the block
                               1618                 :                          * is in progress. Since we don't have any such thing
                               1619                 :                          * right now, we just do this and hope for the best.
                               1620                 :                          */
                               1621              28 :                         if (block_retry == false)
                               1622              14 :                         {
 1026 rhaas                    1623 ECB             :                             int         reread_cnt;
 1832 magnus                   1624                 : 
                               1625                 :                             /* Reread the failed block */
                               1626                 :                             reread_cnt =
  520 rhaas                    1627 GIC          14 :                                 basebackup_read_file(fd,
                               1628              14 :                                                      sink->bbs_buffer + BLCKSZ * i,
 1026 rhaas                    1629 CBC          14 :                                                      BLCKSZ, len + BLCKSZ * i,
 1026 rhaas                    1630 ECB             :                                                      readfilename,
                               1631                 :                                                      false);
 1026 rhaas                    1632 GIC          14 :                             if (reread_cnt == 0)
                               1633                 :                             {
 1311 rhaas                    1634 ECB             :                                 /*
                               1635                 :                                  * If we hit end-of-file, a concurrent
                               1636                 :                                  * truncation must have occurred, so break out
                               1637                 :                                  * of this loop just as if the initial fread()
                               1638                 :                                  * returned 0. We'll drop through to the same
                               1639                 :                                  * code that handles that case. (We must fix
                               1640                 :                                  * up cnt first, though.)
                               1641                 :                                  */
 1026 rhaas                    1642 UIC           0 :                                 cnt = BLCKSZ * i;
                               1643               0 :                                 break;
 1832 magnus                   1644 EUB             :                             }
                               1645                 : 
                               1646                 :                             /* Set flag so we know a retry was attempted */
 1832 magnus                   1647 GIC          14 :                             block_retry = true;
                               1648                 : 
 1832 magnus                   1649 ECB             :                             /* Reset loop to validate the block again */
 1832 magnus                   1650 GIC          14 :                             i--;
                               1651              14 :                             continue;
 1832 magnus                   1652 ECB             :                         }
                               1653                 : 
 1832 magnus                   1654 GIC          14 :                         checksum_failures++;
                               1655                 : 
 1832 magnus                   1656 CBC          14 :                         if (checksum_failures <= 5)
 1832 magnus                   1657 GIC          12 :                             ereport(WARNING,
 1832 magnus                   1658 ECB             :                                     (errmsg("checksum verification failed in "
  722 peter                    1659                 :                                             "file \"%s\", block %u: calculated "
                               1660                 :                                             "%X but expected %X",
                               1661                 :                                             readfilename, blkno, checksum,
                               1662                 :                                             phdr->pd_checksum)));
 1832 magnus                   1663 GIC          14 :                         if (checksum_failures == 5)
                               1664               2 :                             ereport(WARNING,
 1832 magnus                   1665 ECB             :                                     (errmsg("further checksum verification "
                               1666                 :                                             "failures in file \"%s\" will not "
                               1667                 :                                             "be reported", readfilename)));
                               1668                 :                     }
                               1669                 :                 }
 1832 magnus                   1670 GIC       84482 :                 block_retry = false;
                               1671           84482 :                 blkno++;
 1832 magnus                   1672 ECB             :             }
                               1673                 :         }
                               1674                 : 
                               1675                 :         /*
                               1676                 :          * If we hit end-of-file, a concurrent truncation must have occurred.
                               1677                 :          * That's not an error condition, because WAL replay will fix things
                               1678                 :          * up.
                               1679                 :          */
   66 rhaas                    1680 GIC      146104 :         if (cnt == 0)
   66 rhaas                    1681 UIC           0 :             break;
   66 rhaas                    1682 ECB             : 
   66 rhaas                    1683 EUB             :         /* Archive the data we just read. */
  520 rhaas                    1684 GIC      146104 :         bbsink_archive_contents(sink, cnt);
                               1685                 : 
 1101 rhaas                    1686 ECB             :         /* Also feed it to the checksum machinery. */
  520 rhaas                    1687 GIC      146104 :         if (pg_checksum_update(&checksum_ctx,
                               1688          146104 :                                (uint8 *) sink->bbs_buffer, cnt) < 0)
  858 michael                  1689 LBC           0 :             elog(ERROR, "could not update checksum of base backup");
 1101 rhaas                    1690 ECB             : 
 4472 magnus                   1691 GBC      146104 :         len += cnt;
                               1692                 :     }
 4472 magnus                   1693 ECB             : 
                               1694                 :     /* If the file was truncated while we were sending it, pad it with zeros */
  520 rhaas                    1695 GIC      119364 :     while (len < statbuf->st_size)
                               1696                 :     {
  520 rhaas                    1697 LBC           0 :         size_t      remaining = statbuf->st_size - len;
  520 rhaas                    1698 UIC           0 :         size_t      nbytes = Min(sink->bbs_buffer_length, remaining);
  520 rhaas                    1699 EUB             : 
  520 rhaas                    1700 UBC           0 :         MemSet(sink->bbs_buffer, 0, nbytes);
  520 rhaas                    1701 UIC           0 :         if (pg_checksum_update(&checksum_ctx,
  520 rhaas                    1702 UBC           0 :                                (uint8 *) sink->bbs_buffer,
  520 rhaas                    1703 EUB             :                                nbytes) < 0)
  520 rhaas                    1704 UBC           0 :             elog(ERROR, "could not update checksum of base backup");
  520 rhaas                    1705 UIC           0 :         bbsink_archive_contents(sink, nbytes);
  520 rhaas                    1706 UBC           0 :         len += nbytes;
 4472 magnus                   1707 EUB             :     }
                               1708                 : 
                               1709                 :     /*
                               1710                 :      * Pad to a block boundary, per tar format requirements. (This small piece
                               1711                 :      * of data is probably not worth throttling, and is not checksummed
                               1712                 :      * because it's not actually part of the file.)
                               1713                 :      */
  520 rhaas                    1714 GIC      119364 :     _tarWritePadding(sink, len);
                               1715                 : 
 1026 rhaas                    1716 CBC      119364 :     CloseTransientFile(fd);
                               1717                 : 
 1832 magnus                   1718          119364 :     if (checksum_failures > 1)
                               1719                 :     {
                               1720               2 :         ereport(WARNING,
                               1721                 :                 (errmsg_plural("file \"%s\" has a total of %d checksum verification failure",
 1294 peter                    1722 ECB             :                                "file \"%s\" has a total of %d checksum verification failures",
                               1723                 :                                checksum_failures,
                               1724                 :                                readfilename, checksum_failures)));
                               1725                 : 
 1458 magnus                   1726 GIC           2 :         pgstat_report_checksum_failures_in_db(dboid, checksum_failures);
                               1727                 :     }
 1458 magnus                   1728 ECB             : 
 1832 magnus                   1729 GIC      119364 :     total_checksum_failures += checksum_failures;
                               1730                 : 
 1081 rhaas                    1731 CBC      119364 :     AddFileToBackupManifest(manifest, spcoid, tarfilename, statbuf->st_size,
 1081 rhaas                    1732 GIC      119364 :                             (pg_time_t) statbuf->st_mtime, &checksum_ctx);
 1101 rhaas                    1733 ECB             : 
 3761 heikki.linnakangas       1734 CBC      119364 :     return true;
                               1735                 : }
 4472 magnus                   1736 ECB             : 
                               1737                 : static int64
  520 rhaas                    1738 GIC      125914 : _tarWriteHeader(bbsink *sink, const char *filename, const char *linktarget,
                               1739                 :                 struct stat *statbuf, bool sizeonly)
 4472 magnus                   1740 ECB             : {
                               1741                 :     enum tarError rc;
                               1742                 : 
 2384 peter_e                  1743 GIC      125914 :     if (!sizeonly)
                               1744                 :     {
  520 rhaas                    1745 ECB             :         /*
                               1746                 :          * As of this writing, the smallest supported block size is 1kB, which
                               1747                 :          * is twice TAR_BLOCK_SIZE. Since the buffer size is required to be a
                               1748                 :          * multiple of BLCKSZ, it should be safe to assume that the buffer is
                               1749                 :          * large enough to fit an entire tar block. We double-check by means
                               1750                 :          * of these assertions.
                               1751                 :          */
                               1752                 :         StaticAssertDecl(TAR_BLOCK_SIZE <= BLCKSZ,
                               1753                 :                          "BLCKSZ too small for tar block");
  520 rhaas                    1754 GIC      122684 :         Assert(sink->bbs_buffer_length >= TAR_BLOCK_SIZE);
                               1755                 : 
  520 rhaas                    1756 CBC      122684 :         rc = tarCreateHeader(sink->bbs_buffer, filename, linktarget,
                               1757                 :                              statbuf->st_size, statbuf->st_mode,
  520 rhaas                    1758 ECB             :                              statbuf->st_uid, statbuf->st_gid,
                               1759                 :                              statbuf->st_mtime);
                               1760                 : 
 2384 peter_e                  1761 GIC      122684 :         switch (rc)
                               1762                 :         {
 2384 peter_e                  1763 CBC      122683 :             case TAR_OK:
 2384 peter_e                  1764 GIC      122683 :                 break;
 2384 peter_e                  1765 CBC           1 :             case TAR_NAME_TOO_LONG:
                               1766               1 :                 ereport(ERROR,
 2384 peter_e                  1767 ECB             :                         (errmsg("file name too long for tar format: \"%s\"",
                               1768                 :                                 filename)));
                               1769                 :                 break;
 2384 peter_e                  1770 UIC           0 :             case TAR_SYMLINK_TOO_LONG:
                               1771               0 :                 ereport(ERROR,
 2118 tgl                      1772 EUB             :                         (errmsg("symbolic link target too long for tar format: "
                               1773                 :                                 "file name \"%s\", target \"%s\"",
                               1774                 :                                 filename, linktarget)));
                               1775                 :                 break;
 2384 peter_e                  1776 UIC           0 :             default:
                               1777               0 :                 elog(ERROR, "unrecognized tar error: %d", rc);
 2384 peter_e                  1778 EUB             :         }
                               1779                 : 
  520 rhaas                    1780 GIC      122683 :         bbsink_archive_contents(sink, TAR_BLOCK_SIZE);
                               1781                 :     }
 2966 peter_e                  1782 ECB             : 
  520 rhaas                    1783 GIC      125913 :     return TAR_BLOCK_SIZE;
                               1784                 : }
 2384 peter_e                  1785 ECB             : 
                               1786                 : /*
                               1787                 :  * Pad with zero bytes out to a multiple of TAR_BLOCK_SIZE.
                               1788                 :  */
                               1789                 : static void
  520 rhaas                    1790 GIC      119534 : _tarWritePadding(bbsink *sink, int len)
                               1791                 : {
  520 rhaas                    1792 CBC      119534 :     int         pad = tarPaddingBytesRequired(len);
                               1793                 : 
 2042 alvherre                 1794 ECB             :     /*
                               1795                 :      * As in _tarWriteHeader, it should be safe to assume that the buffer is
                               1796                 :      * large enough that we don't need to do this in multiple chunks.
                               1797                 :      */
  520 rhaas                    1798 GIC      119534 :     Assert(sink->bbs_buffer_length >= TAR_BLOCK_SIZE);
                               1799          119534 :     Assert(pad <= TAR_BLOCK_SIZE);
 3328 alvherre                 1800 ECB             : 
  520 rhaas                    1801 CBC      119534 :     if (pad > 0)
                               1802                 :     {
                               1803           22769 :         MemSet(sink->bbs_buffer, 0, pad);
  520 rhaas                    1804 GIC        1768 :         bbsink_archive_contents(sink, pad);
 3328 alvherre                 1805 ECB             :     }
 3328 alvherre                 1806 CBC      119534 : }
                               1807                 : 
 1132 fujii                    1808 ECB             : /*
                               1809                 :  * If the entry in statbuf is a link, then adjust statbuf to make it look like a
                               1810                 :  * directory, so that it will be written that way.
                               1811                 :  */
                               1812                 : static void
  520 rhaas                    1813 GIC        1990 : convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
                               1814                 : {
  520 rhaas                    1815 ECB             :     /* If symlink, write it as a directory anyway */
  520 rhaas                    1816 GIC        1990 :     if (S_ISLNK(statbuf->st_mode))
                               1817              66 :         statbuf->st_mode = S_IFDIR | pg_dir_create_mode;
 1132 fujii                    1818            1990 : }
                               1819                 : 
                               1820                 : /*
                               1821                 :  * Read some data from a file, setting a wait event and reporting any error
                               1822                 :  * encountered.
                               1823                 :  *
                               1824                 :  * If partial_read_ok is false, also report an error if the number of bytes
                               1825                 :  * read is not equal to the number of bytes requested.
                               1826                 :  *
                               1827                 :  * Returns the number of bytes read.
 1026 rhaas                    1828 ECB             :  */
                               1829                 : static int
 1026 rhaas                    1830 GIC      156358 : basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
                               1831                 :                      const char *filename, bool partial_read_ok)
                               1832                 : {
 1026 rhaas                    1833 ECB             :     int         rc;
                               1834                 : 
 1026 rhaas                    1835 CBC      156358 :     pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
  192 tmunro                   1836 GIC      156358 :     rc = pg_pread(fd, buf, nbytes, offset);
 1026 rhaas                    1837 CBC      156358 :     pgstat_report_wait_end();
 1026 rhaas                    1838 EUB             : 
 1026 rhaas                    1839 GIC      156358 :     if (rc < 0)
 1026 rhaas                    1840 UIC           0 :         ereport(ERROR,
 1026 rhaas                    1841 ECB             :                 (errcode_for_file_access(),
 1026 rhaas                    1842 EUB             :                  errmsg("could not read file \"%s\": %m", filename)));
 1026 rhaas                    1843 GIC      156358 :     if (!partial_read_ok && rc > 0 && rc != nbytes)
 1026 rhaas                    1844 UIC           0 :         ereport(ERROR,
                               1845                 :                 (errcode_for_file_access(),
                               1846                 :                  errmsg("could not read file \"%s\": read %d of %zu",
 1026 rhaas                    1847 ECB             :                         filename, rc, nbytes)));
                               1848                 : 
 1026 rhaas                    1849 GIC      156358 :     return rc;
                               1850                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a