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, const char *replication_slot, char *dbname)
 
void WriteRecoveryConfig (PGconn *pgconn, const char *target_dir, PQExpBuffer contents)
 

Function Documentation

◆ escape_quotes()

static char * escape_quotes ( const char *  src)
static

Definition at line 163 of file recovery_gen.c.

164 {
165  char *result = escape_single_quotes_ascii(src);
166 
167  if (!result)
168  pg_fatal("out of memory");
169  return result;
170 }
#define pg_fatal(...)
char * escape_single_quotes_ascii(const char *src)
Definition: quotes.c:33

References escape_single_quotes_ascii(), and pg_fatal.

Referenced by GenerateRecoveryConfig().

◆ GenerateRecoveryConfig()

PQExpBuffer GenerateRecoveryConfig ( PGconn pgconn,
const char *  replication_slot,
char *  dbname 
)

Definition at line 27 of file recovery_gen.c.

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

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

Referenced by BaseBackup(), main(), and setup_recovery().

◆ WriteRecoveryConfig()

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

Definition at line 124 of file recovery_gen.c.

125 {
126  char filename[MAXPGPATH];
127  FILE *cf;
128  bool use_recovery_conf;
129 
130  Assert(pgconn != NULL);
131 
132  use_recovery_conf =
134 
135  snprintf(filename, MAXPGPATH, "%s/%s", target_dir,
136  use_recovery_conf ? "recovery.conf" : "postgresql.auto.conf");
137 
138  cf = fopen(filename, use_recovery_conf ? "w" : "a");
139  if (cf == NULL)
140  pg_fatal("could not open file \"%s\": %m", filename);
141 
142  if (fwrite(contents->data, contents->len, 1, cf) != 1)
143  pg_fatal("could not write to file \"%s\": %m", filename);
144 
145  fclose(cf);
146 
147  if (!use_recovery_conf)
148  {
149  snprintf(filename, MAXPGPATH, "%s/%s", target_dir, "standby.signal");
150  cf = fopen(filename, "w");
151  if (cf == NULL)
152  pg_fatal("could not create file \"%s\": %m", filename);
153 
154  fclose(cf);
155  }
156 }
#define MAXPGPATH
static char * filename
Definition: pg_dumpall.c:119
#define snprintf
Definition: port.h:238

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

Referenced by main(), and setup_recovery().