LCOV - code coverage report
Current view: top level - src/fe_utils - archive.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 12 20 60.0 %
Date: 2024-04-18 15:11:28 Functions: 1 1 100.0 %
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-2024, 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           2 : 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           2 :     snprintf(xlogpath, MAXPGPATH, "%s/" XLOGDIR "/%s", path, xlogfname);
      48             : 
      49           2 :     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           2 :     fflush(NULL);
      57           2 :     rc = system(xlogRestoreCmd);
      58           2 :     pfree(xlogRestoreCmd);
      59             : 
      60           2 :     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           2 :         if (stat(xlogpath, &stat_buf) == 0)
      67             :         {
      68           2 :             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           2 :                 int         xlogfd = open(xlogpath, O_RDONLY | PG_BINARY, 0);
      75             : 
      76           2 :                 if (xlogfd < 0)
      77           0 :                     pg_fatal("could not open file \"%s\" restored from archive: %m",
      78             :                              xlogpath);
      79             :                 else
      80           2 :                     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 1.14