LCOV - code coverage report
Current view: top level - src/fe_utils - archive.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 60.0 % 20 12
Test Date: 2026-03-12 01:15:13 Functions: 100.0 % 1 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * archive.c
       4              :  *    Routines to access WAL archives from frontend
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  *
      10              :  * IDENTIFICATION
      11              :  *    src/fe_utils/archive.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : 
      16              : #include "postgres_fe.h"
      17              : 
      18              : #include <unistd.h>
      19              : #include <sys/stat.h>
      20              : 
      21              : #include "access/xlog_internal.h"
      22              : #include "common/archive.h"
      23              : #include "common/logging.h"
      24              : #include "fe_utils/archive.h"
      25              : 
      26              : 
      27              : /*
      28              :  * RestoreArchivedFile
      29              :  *
      30              :  * Attempt to retrieve the specified file from off-line archival storage.
      31              :  * If successful, return a file descriptor of the restored file, else
      32              :  * return -1.
      33              :  *
      34              :  * For fixed-size files, the caller may pass the expected size as an
      35              :  * additional crosscheck on successful recovery.  If the file size is not
      36              :  * known, set expectedSize = 0.
      37              :  */
      38              : int
      39            1 : RestoreArchivedFile(const char *path, const char *xlogfname,
      40              :                     off_t expectedSize, const char *restoreCommand)
      41              : {
      42              :     char        xlogpath[MAXPGPATH];
      43              :     char       *xlogRestoreCmd;
      44              :     int         rc;
      45              :     struct stat stat_buf;
      46              : 
      47            1 :     snprintf(xlogpath, MAXPGPATH, "%s/" XLOGDIR "/%s", path, xlogfname);
      48              : 
      49            1 :     xlogRestoreCmd = BuildRestoreCommand(restoreCommand, xlogpath,
      50              :                                          xlogfname, NULL);
      51              : 
      52              :     /*
      53              :      * Execute restore_command, which should copy the missing file from
      54              :      * archival storage.
      55              :      */
      56            1 :     fflush(NULL);
      57            1 :     rc = system(xlogRestoreCmd);
      58            1 :     pfree(xlogRestoreCmd);
      59              : 
      60            1 :     if (rc == 0)
      61              :     {
      62              :         /*
      63              :          * Command apparently succeeded, but let's make sure the file is
      64              :          * really there now and has the correct size.
      65              :          */
      66            1 :         if (stat(xlogpath, &stat_buf) == 0)
      67              :         {
      68            1 :             if (expectedSize > 0 && stat_buf.st_size != expectedSize)
      69            0 :                 pg_fatal("unexpected file size for \"%s\": %lld instead of %lld",
      70              :                          xlogfname, (long long int) stat_buf.st_size,
      71              :                          (long long int) expectedSize);
      72              :             else
      73              :             {
      74            1 :                 int         xlogfd = open(xlogpath, O_RDONLY | PG_BINARY, 0);
      75              : 
      76            1 :                 if (xlogfd < 0)
      77            0 :                     pg_fatal("could not open file \"%s\" restored from archive: %m",
      78              :                              xlogpath);
      79              :                 else
      80            1 :                     return xlogfd;
      81              :             }
      82              :         }
      83              :         else
      84              :         {
      85            0 :             if (errno != ENOENT)
      86            0 :                 pg_fatal("could not stat file \"%s\": %m",
      87              :                          xlogpath);
      88              :         }
      89              :     }
      90              : 
      91              :     /*
      92              :      * If the failure was due to a signal, then it would be misleading to
      93              :      * return with a failure at restoring the file.  So just bail out and
      94              :      * exit.  Hard shell errors such as "command not found" are treated as
      95              :      * fatal too.
      96              :      */
      97            0 :     if (wait_result_is_any_signal(rc, true))
      98            0 :         pg_fatal("\"restore_command\" failed: %s",
      99              :                  wait_result_to_str(rc));
     100              : 
     101              :     /*
     102              :      * The file is not available, so just let the caller decide what to do
     103              :      * next.
     104              :      */
     105            0 :     pg_log_error("could not restore file \"%s\" from archive",
     106              :                  xlogfname);
     107            0 :     return -1;
     108              : }
        

Generated by: LCOV version 2.0-1