LCOV - differential code coverage report
Current view: top level - src/backend/archive - shell_archive.c (source / functions) Coverage Total Hit UIC GBC GIC GNC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 90.3 % 31 28 3 1 13 14 2 12 16
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 4 4 4 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 6 6 6
Legend: Lines: hit not hit (60,120] days: 100.0 % 7 7 7
(120,180] days: 100.0 % 2 2 2
(180,240] days: 100.0 % 1 1 1
(240..) days: 80.0 % 15 12 3 1 11 2 12
Function coverage date bins:
[..60] days: 100.0 % 4 4 4
(240..) days: 0.0 % 4 0 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * shell_archive.c
                                  4                 :  *
                                  5                 :  * This archiving function uses a user-specified shell command (the
                                  6                 :  * archive_command GUC) to copy write-ahead log files.  It is used as the
                                  7                 :  * default, but other modules may define their own custom archiving logic.
                                  8                 :  *
                                  9                 :  * Copyright (c) 2022-2023, PostgreSQL Global Development Group
                                 10                 :  *
                                 11                 :  * IDENTIFICATION
                                 12                 :  *    src/backend/archive/shell_archive.c
                                 13                 :  *
                                 14                 :  *-------------------------------------------------------------------------
                                 15                 :  */
                                 16                 : #include "postgres.h"
                                 17                 : 
                                 18                 : #include <sys/wait.h>
                                 19                 : 
                                 20                 : #include "access/xlog.h"
                                 21                 : #include "archive/archive_module.h"
                                 22                 : #include "archive/shell_archive.h"
                                 23                 : #include "common/percentrepl.h"
                                 24                 : #include "pgstat.h"
                                 25                 : 
                                 26                 : static bool shell_archive_configured(ArchiveModuleState *state);
                                 27                 : static bool shell_archive_file(ArchiveModuleState *state,
                                 28                 :                                const char *file,
                                 29                 :                                const char *path);
                                 30                 : static void shell_archive_shutdown(ArchiveModuleState *state);
                                 31                 : 
                                 32                 : static const ArchiveModuleCallbacks shell_archive_callbacks = {
                                 33                 :     .startup_cb = NULL,
                                 34                 :     .check_configured_cb = shell_archive_configured,
                                 35                 :     .archive_file_cb = shell_archive_file,
                                 36                 :     .shutdown_cb = shell_archive_shutdown
                                 37                 : };
                                 38                 : 
                                 39                 : const ArchiveModuleCallbacks *
   51 michael                    40 GNC           9 : shell_archive_init(void)
                                 41                 : {
                                 42               9 :     return &shell_archive_callbacks;
                                 43                 : }
                                 44                 : 
                                 45                 : static bool
                                 46              23 : shell_archive_configured(ArchiveModuleState *state)
  430 rhaas                      47 ECB             : {
  430 rhaas                      48 GIC          23 :     return XLogArchiveCommand[0] != '\0';
  430 rhaas                      49 ECB             : }
                                 50                 : 
                                 51                 : static bool
   51 michael                    52 GNC          23 : shell_archive_file(ArchiveModuleState *state, const char *file,
                                 53                 :                    const char *path)
  436 rhaas                      54 ECB             : {
                                 55                 :     char       *xlogarchcmd;
   88 peter                      56 GNC          23 :     char       *nativePath = NULL;
                                 57                 :     int         rc;
  436 rhaas                      58 ECB             : 
   88 peter                      59 GNC          23 :     if (path)
  436 rhaas                      60 ECB             :     {
   88 peter                      61 GNC          23 :         nativePath = pstrdup(path);
                                 62              23 :         make_native_path(nativePath);
                                 63                 :     }
                                 64                 : 
   51 michael                    65              23 :     xlogarchcmd = replace_percent_placeholders(XLogArchiveCommand,
                                 66                 :                                                "archive_command", "fp",
                                 67                 :                                                file, nativePath);
                                 68                 : 
   88 peter                      69              23 :     if (nativePath)
                                 70              23 :         pfree(nativePath);
                                 71                 : 
  436 rhaas                      72 GIC          23 :     ereport(DEBUG3,
  436 rhaas                      73 EUB             :             (errmsg_internal("executing archive command \"%s\"",
                                 74                 :                              xlogarchcmd)));
                                 75                 : 
  223 tgl                        76 GNC          23 :     fflush(NULL);
  436 rhaas                      77 GIC          23 :     pgstat_report_wait_start(WAIT_EVENT_ARCHIVE_COMMAND);
                                 78              23 :     rc = system(xlogarchcmd);
                                 79              23 :     pgstat_report_wait_end();
                                 80                 : 
                                 81              23 :     if (rc != 0)
                                 82                 :     {
                                 83                 :         /*
  436 rhaas                      84 EUB             :          * If either the shell itself, or a called command, died on a signal,
                                 85                 :          * abort the archiver.  We do this because system() ignores SIGINT and
                                 86                 :          * SIGQUIT while waiting; so a signal is very likely something that
                                 87                 :          * should have interrupted us too.  Also die if the shell got a hard
                                 88                 :          * "command not found" type of error.  If we overreact it's no big
                                 89                 :          * deal, the postmaster will just start the archiver again.
                                 90                 :          */
  436 rhaas                      91 GIC           1 :         int         lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG;
                                 92                 : 
  436 rhaas                      93 GBC           1 :         if (WIFEXITED(rc))
                                 94                 :         {
  436 rhaas                      95 GIC           1 :             ereport(lev,
                                 96                 :                     (errmsg("archive command failed with exit code %d",
                                 97                 :                             WEXITSTATUS(rc)),
                                 98                 :                      errdetail("The failed archive command was: %s",
                                 99                 :                                xlogarchcmd)));
  436 rhaas                     100 ECB             :         }
  436 rhaas                     101 UIC           0 :         else if (WIFSIGNALED(rc))
                                102                 :         {
  436 rhaas                     103 ECB             : #if defined(WIN32)
                                104                 :             ereport(lev,
                                105                 :                     (errmsg("archive command was terminated by exception 0x%X",
                                106                 :                             WTERMSIG(rc)),
                                107                 :                      errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
                                108                 :                      errdetail("The failed archive command was: %s",
                                109                 :                                xlogarchcmd)));
                                110                 : #else
  436 rhaas                     111 UIC           0 :             ereport(lev,
  436 rhaas                     112 ECB             :                     (errmsg("archive command was terminated by signal %d: %s",
                                113                 :                             WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
                                114                 :                      errdetail("The failed archive command was: %s",
                                115                 :                                xlogarchcmd)));
                                116                 : #endif
                                117                 :         }
                                118                 :         else
                                119                 :         {
  436 rhaas                     120 UIC           0 :             ereport(lev,
                                121                 :                     (errmsg("archive command exited with unrecognized status %d",
                                122                 :                             rc),
                                123                 :                      errdetail("The failed archive command was: %s",
                                124                 :                                xlogarchcmd)));
                                125                 :         }
                                126                 : 
  436 rhaas                     127 GIC           1 :         return false;
                                128                 :     }
                                129                 : 
   88 peter                     130 GNC          22 :     pfree(xlogarchcmd);
                                131                 : 
  436 rhaas                     132 GIC          22 :     elog(DEBUG1, "archived write-ahead log file \"%s\"", file);
                                133              22 :     return true;
                                134                 : }
                                135                 : 
                                136                 : static void
   51 michael                   137 GNC           9 : shell_archive_shutdown(ArchiveModuleState *state)
                                138                 : {
  172 michael                   139 GIC           9 :     elog(DEBUG1, "archiver process shutting down");
                                140               9 : }
        

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