PostgreSQL Source Code  git master
recovery_gen.c File Reference
Include dependency graph for recovery_gen.c:

Go to the source code of this file.

Functions

static char * escape_quotes (const char *src)
 
PQExpBuffer GenerateRecoveryConfig (PGconn *pgconn, char *replication_slot)
 
void WriteRecoveryConfig (PGconn *pgconn, char *target_dir, PQExpBuffer contents)
 

Function Documentation

◆ escape_quotes()

static char * escape_quotes ( const char *  src)
static

Definition at line 165 of file recovery_gen.c.

References escape_single_quotes_ascii(), and pg_log_error.

Referenced by GenerateRecoveryConfig().

166 {
167  char *result = escape_single_quotes_ascii(src);
168 
169  if (!result)
170  {
171  pg_log_error("out of memory");
172  exit(1);
173  }
174  return result;
175 }
#define pg_log_error(...)
Definition: logging.h:79
char * escape_single_quotes_ascii(const char *src)
Definition: quotes.c:33

◆ GenerateRecoveryConfig()

PQExpBuffer GenerateRecoveryConfig ( PGconn pgconn,
char *  replication_slot 
)

Definition at line 23 of file recovery_gen.c.

References appendConnStrVal(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), Assert, createPQExpBuffer(), PQExpBufferData::data, escape_quotes(), free, initPQExpBuffer(), _PQconninfoOption::keyword, PQExpBufferData::len, MINIMUM_VERSION_FOR_RECOVERY_GUC, pg_log_error, PQconninfo(), PQconninfoFree(), PQExpBufferBroken, PQExpBufferDataBroken, PQserverVersion(), and termPQExpBuffer().

Referenced by BaseBackup(), and main().

24 {
25  PQconninfoOption *connOptions;
26  PQExpBufferData conninfo_buf;
27  char *escaped;
28  PQExpBuffer contents;
29 
30  Assert(pgconn != NULL);
31 
32  contents = createPQExpBuffer();
33  if (!contents)
34  {
35  pg_log_error("out of memory");
36  exit(1);
37  }
38 
39  /*
40  * In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by
41  * standby.signal to trigger a standby state at recovery.
42  */
44  appendPQExpBufferStr(contents, "standby_mode = 'on'\n");
45 
46  connOptions = PQconninfo(pgconn);
47  if (connOptions == NULL)
48  {
49  pg_log_error("out of memory");
50  exit(1);
51  }
52 
53  initPQExpBuffer(&conninfo_buf);
54  for (PQconninfoOption *opt = connOptions; opt && opt->keyword; opt++)
55  {
56  /* Omit empty settings and those libpqwalreceiver overrides. */
57  if (strcmp(opt->keyword, "replication") == 0 ||
58  strcmp(opt->keyword, "dbname") == 0 ||
59  strcmp(opt->keyword, "fallback_application_name") == 0 ||
60  (opt->val == NULL) ||
61  (opt->val != NULL && opt->val[0] == '\0'))
62  continue;
63 
64  /* Separate key-value pairs with spaces */
65  if (conninfo_buf.len != 0)
66  appendPQExpBufferChar(&conninfo_buf, ' ');
67 
68  /*
69  * Write "keyword=value" pieces, the value string is escaped and/or
70  * quoted if necessary.
71  */
72  appendPQExpBuffer(&conninfo_buf, "%s=", opt->keyword);
73  appendConnStrVal(&conninfo_buf, opt->val);
74  }
75  if (PQExpBufferDataBroken(conninfo_buf))
76  {
77  pg_log_error("out of memory");
78  exit(1);
79  }
80 
81  /*
82  * Escape the connection string, so that it can be put in the config file.
83  * Note that this is different from the escaping of individual connection
84  * options above!
85  */
86  escaped = escape_quotes(conninfo_buf.data);
87  termPQExpBuffer(&conninfo_buf);
88  appendPQExpBuffer(contents, "primary_conninfo = '%s'\n", escaped);
89  free(escaped);
90 
91  if (replication_slot)
92  {
93  /* unescaped: ReplicationSlotValidateName allows [a-z0-9_] only */
94  appendPQExpBuffer(contents, "primary_slot_name = '%s'\n",
96  }
97 
98  if (PQExpBufferBroken(contents))
99  {
100  pg_log_error("out of memory");
101  exit(1);
102  }
103 
104  PQconninfoFree(connOptions);
105 
106  return contents;
107 }
static char * escape_quotes(const char *src)
Definition: recovery_gen.c:165
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
#define pg_log_error(...)
Definition: logging.h:79
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545
#define MINIMUM_VERSION_FOR_RECOVERY_GUC
Definition: recovery_gen.h:21
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6613
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6455
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:6414
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
#define free(a)
Definition: header.h:65
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define Assert(condition)
Definition: c.h:739
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
static char * replication_slot
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ WriteRecoveryConfig()

void WriteRecoveryConfig ( PGconn pgconn,
char *  target_dir,
PQExpBuffer  contents 
)

Definition at line 117 of file recovery_gen.c.

References Assert, PQExpBufferData::data, filename, PQExpBufferData::len, MAXPGPATH, MINIMUM_VERSION_FOR_RECOVERY_GUC, pg_log_error, PQserverVersion(), and snprintf.

Referenced by main(), and ReceiveAndUnpackTarFile().

118 {
119  char filename[MAXPGPATH];
120  FILE *cf;
121  bool use_recovery_conf;
122 
123  Assert(pgconn != NULL);
124 
125  use_recovery_conf =
127 
128  snprintf(filename, MAXPGPATH, "%s/%s", target_dir,
129  use_recovery_conf ? "recovery.conf" : "postgresql.auto.conf");
130 
131  cf = fopen(filename, use_recovery_conf ? "a" : "w");
132  if (cf == NULL)
133  {
134  pg_log_error("could not open file \"%s\": %m", filename);
135  exit(1);
136  }
137 
138  if (fwrite(contents->data, contents->len, 1, cf) != 1)
139  {
140  pg_log_error("could not write to file \"%s\": %m", filename);
141  exit(1);
142  }
143 
144  fclose(cf);
145 
146  if (!use_recovery_conf)
147  {
148  snprintf(filename, MAXPGPATH, "%s/%s", target_dir, "standby.signal");
149  cf = fopen(filename, "w");
150  if (cf == NULL)
151  {
152  pg_log_error("could not create file \"%s\": %m", filename);
153  exit(1);
154  }
155 
156  fclose(cf);
157  }
158 }
#define pg_log_error(...)
Definition: logging.h:79
#define MINIMUM_VERSION_FOR_RECOVERY_GUC
Definition: recovery_gen.h:21
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6613
#define MAXPGPATH
#define Assert(condition)
Definition: c.h:739
static char * filename
Definition: pg_dumpall.c:90
#define snprintf
Definition: port.h:192