PostgreSQL Source Code  git master
shell_archive.c File Reference
#include "postgres.h"
#include <sys/wait.h>
#include "access/xlog.h"
#include "pgstat.h"
#include "postmaster/pgarch.h"
Include dependency graph for shell_archive.c:

Go to the source code of this file.

Functions

static bool shell_archive_configured (void)
 
static bool shell_archive_file (const char *file, const char *path)
 
void shell_archive_init (ArchiveModuleCallbacks *cb)
 

Function Documentation

◆ shell_archive_configured()

static bool shell_archive_configured ( void  )
static

Definition at line 37 of file shell_archive.c.

38 {
39  return XLogArchiveCommand[0] != '\0';
40 }
char * XLogArchiveCommand
Definition: xlog.c:121

References XLogArchiveCommand.

Referenced by shell_archive_init().

◆ shell_archive_file()

static bool shell_archive_file ( const char *  file,
const char *  path 
)
static

Definition at line 43 of file shell_archive.c.

44 {
45  char xlogarchcmd[MAXPGPATH];
46  char *dp;
47  char *endp;
48  const char *sp;
49  int rc;
50 
51  /*
52  * construct the command to be executed
53  */
54  dp = xlogarchcmd;
55  endp = xlogarchcmd + MAXPGPATH - 1;
56  *endp = '\0';
57 
58  for (sp = XLogArchiveCommand; *sp; sp++)
59  {
60  if (*sp == '%')
61  {
62  switch (sp[1])
63  {
64  case 'p':
65  /* %p: relative path of source file */
66  sp++;
67  strlcpy(dp, path, endp - dp);
68  make_native_path(dp);
69  dp += strlen(dp);
70  break;
71  case 'f':
72  /* %f: filename of source file */
73  sp++;
74  strlcpy(dp, file, endp - dp);
75  dp += strlen(dp);
76  break;
77  case '%':
78  /* convert %% to a single % */
79  sp++;
80  if (dp < endp)
81  *dp++ = *sp;
82  break;
83  default:
84  /* otherwise treat the % as not special */
85  if (dp < endp)
86  *dp++ = *sp;
87  break;
88  }
89  }
90  else
91  {
92  if (dp < endp)
93  *dp++ = *sp;
94  }
95  }
96  *dp = '\0';
97 
99  (errmsg_internal("executing archive command \"%s\"",
100  xlogarchcmd)));
101 
103  rc = system(xlogarchcmd);
105 
106  if (rc != 0)
107  {
108  /*
109  * If either the shell itself, or a called command, died on a signal,
110  * abort the archiver. We do this because system() ignores SIGINT and
111  * SIGQUIT while waiting; so a signal is very likely something that
112  * should have interrupted us too. Also die if the shell got a hard
113  * "command not found" type of error. If we overreact it's no big
114  * deal, the postmaster will just start the archiver again.
115  */
116  int lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG;
117 
118  if (WIFEXITED(rc))
119  {
120  ereport(lev,
121  (errmsg("archive command failed with exit code %d",
122  WEXITSTATUS(rc)),
123  errdetail("The failed archive command was: %s",
124  xlogarchcmd)));
125  }
126  else if (WIFSIGNALED(rc))
127  {
128 #if defined(WIN32)
129  ereport(lev,
130  (errmsg("archive command was terminated by exception 0x%X",
131  WTERMSIG(rc)),
132  errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
133  errdetail("The failed archive command was: %s",
134  xlogarchcmd)));
135 #else
136  ereport(lev,
137  (errmsg("archive command was terminated by signal %d: %s",
138  WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
139  errdetail("The failed archive command was: %s",
140  xlogarchcmd)));
141 #endif
142  }
143  else
144  {
145  ereport(lev,
146  (errmsg("archive command exited with unrecognized status %d",
147  rc),
148  errdetail("The failed archive command was: %s",
149  xlogarchcmd)));
150  }
151 
152  return false;
153  }
154 
155  elog(DEBUG1, "archived write-ahead log file \"%s\"", file);
156  return true;
157 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:991
int errdetail(const char *fmt,...)
Definition: elog.c:1037
int errhint(const char *fmt,...)
Definition: elog.c:1151
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define LOG
Definition: elog.h:25
#define DEBUG3
Definition: elog.h:22
#define FATAL
Definition: elog.h:35
#define DEBUG1
Definition: elog.h:24
#define elog(elevel,...)
Definition: elog.h:218
#define ereport(elevel,...)
Definition: elog.h:143
#define MAXPGPATH
void make_native_path(char *path)
Definition: path.c:167
const char * pg_strsignal(int signum)
Definition: pgstrsignal.c:42
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
bool wait_result_is_any_signal(int exit_status, bool include_command_not_found)
Definition: wait_error.c:111
@ WAIT_EVENT_ARCHIVE_COMMAND
Definition: wait_event.h:83
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:266
static void pgstat_report_wait_end(void)
Definition: wait_event.h:282
#define WIFEXITED(w)
Definition: win32_port.h:151
#define WIFSIGNALED(w)
Definition: win32_port.h:152
#define WTERMSIG(w)
Definition: win32_port.h:154
#define WEXITSTATUS(w)
Definition: win32_port.h:153

References DEBUG1, DEBUG3, elog, ereport, errdetail(), errhint(), errmsg(), errmsg_internal(), FATAL, LOG, make_native_path(), MAXPGPATH, pg_strsignal(), pgstat_report_wait_end(), pgstat_report_wait_start(), strlcpy(), WAIT_EVENT_ARCHIVE_COMMAND, wait_result_is_any_signal(), WEXITSTATUS, WIFEXITED, WIFSIGNALED, WTERMSIG, and XLogArchiveCommand.

Referenced by shell_archive_init().

◆ shell_archive_init()

void shell_archive_init ( ArchiveModuleCallbacks cb)

Definition at line 28 of file shell_archive.c.

29 {
31 
34 }
#define AssertVariableIsOfType(varname, typename)
Definition: c.h:963
void(* ArchiveModuleInit)(ArchiveModuleCallbacks *cb)
Definition: pgarch.h:64
static bool shell_archive_file(const char *file, const char *path)
Definition: shell_archive.c:43
static bool shell_archive_configured(void)
Definition: shell_archive.c:37
void shell_archive_init(ArchiveModuleCallbacks *cb)
Definition: shell_archive.c:28
ArchiveFileCB archive_file_cb
Definition: pgarch.h:56
ArchiveCheckConfiguredCB check_configured_cb
Definition: pgarch.h:55

References ArchiveModuleCallbacks::archive_file_cb, AssertVariableIsOfType, ArchiveModuleCallbacks::check_configured_cb, shell_archive_configured(), and shell_archive_file().

Referenced by LoadArchiveLibrary().