LCOV - code coverage report
Current view: top level - src/fe_utils - archive.c (source / functions) Hit Total Coverage
Test: PostgreSQL 15devel Lines: 12 26 46.2 %
Date: 2021-12-03 04:09:03 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-2021, 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           2 :     if (xlogRestoreCmd == NULL)
      52             :     {
      53           0 :         pg_log_fatal("cannot use restore_command with %%r placeholder");
      54           0 :         exit(1);
      55             :     }
      56             : 
      57             :     /*
      58             :      * Execute restore_command, which should copy the missing file from
      59             :      * archival storage.
      60             :      */
      61           2 :     rc = system(xlogRestoreCmd);
      62           2 :     pfree(xlogRestoreCmd);
      63             : 
      64           2 :     if (rc == 0)
      65             :     {
      66             :         /*
      67             :          * Command apparently succeeded, but let's make sure the file is
      68             :          * really there now and has the correct size.
      69             :          */
      70           2 :         if (stat(xlogpath, &stat_buf) == 0)
      71             :         {
      72           2 :             if (expectedSize > 0 && stat_buf.st_size != expectedSize)
      73             :             {
      74           0 :                 pg_log_fatal("unexpected file size for \"%s\": %lld instead of %lld",
      75             :                              xlogfname, (long long int) stat_buf.st_size,
      76             :                              (long long int) expectedSize);
      77           0 :                 exit(1);
      78             :             }
      79             :             else
      80             :             {
      81           2 :                 int         xlogfd = open(xlogpath, O_RDONLY | PG_BINARY, 0);
      82             : 
      83           2 :                 if (xlogfd < 0)
      84             :                 {
      85           0 :                     pg_log_fatal("could not open file \"%s\" restored from archive: %m",
      86             :                                  xlogpath);
      87           0 :                     exit(1);
      88             :                 }
      89             :                 else
      90           2 :                     return xlogfd;
      91             :             }
      92             :         }
      93             :         else
      94             :         {
      95           0 :             if (errno != ENOENT)
      96             :             {
      97           0 :                 pg_log_fatal("could not stat file \"%s\": %m",
      98             :                              xlogpath);
      99           0 :                 exit(1);
     100             :             }
     101             :         }
     102             :     }
     103             : 
     104             :     /*
     105             :      * If the failure was due to a signal, then it would be misleading to
     106             :      * return with a failure at restoring the file.  So just bail out and
     107             :      * exit.  Hard shell errors such as "command not found" are treated as
     108             :      * fatal too.
     109             :      */
     110           0 :     if (wait_result_is_any_signal(rc, true))
     111             :     {
     112           0 :         pg_log_fatal("restore_command failed: %s",
     113             :                      wait_result_to_str(rc));
     114           0 :         exit(1);
     115             :     }
     116             : 
     117             :     /*
     118             :      * The file is not available, so just let the caller decide what to do
     119             :      * next.
     120             :      */
     121           0 :     pg_log_error("could not restore file \"%s\" from archive",
     122             :                  xlogfname);
     123           0 :     return -1;
     124             : }

Generated by: LCOV version 1.14