PostgreSQL Source Code  git master
astreamer_inject.c File Reference
#include "postgres_fe.h"
#include "astreamer_inject.h"
#include "common/file_perm.h"
#include "common/logging.h"
Include dependency graph for astreamer_inject.c:

Go to the source code of this file.

Data Structures

struct  astreamer_recovery_injector
 

Typedefs

typedef struct astreamer_recovery_injector astreamer_recovery_injector
 

Functions

static void astreamer_recovery_injector_content (astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
 
static void astreamer_recovery_injector_finalize (astreamer *streamer)
 
static void astreamer_recovery_injector_free (astreamer *streamer)
 
astreamerastreamer_recovery_injector_new (astreamer *next, bool is_recovery_guc_supported, PQExpBuffer recoveryconfcontents)
 
void astreamer_inject_file (astreamer *streamer, char *pathname, char *data, int len)
 

Variables

static const astreamer_ops astreamer_recovery_injector_ops
 

Typedef Documentation

◆ astreamer_recovery_injector

Function Documentation

◆ astreamer_inject_file()

void astreamer_inject_file ( astreamer streamer,
char *  pathname,
char *  data,
int  len 
)

Definition at line 219 of file astreamer_inject.c.

221 {
222  astreamer_member member;
223 
224  strlcpy(member.pathname, pathname, MAXPGPATH);
225  member.size = len;
226  member.mode = pg_file_create_mode;
227  member.is_directory = false;
228  member.is_link = false;
229  member.linktarget[0] = '\0';
230 
231  /*
232  * There seems to be no principled argument for these values, but they are
233  * what PostgreSQL has historically used.
234  */
235  member.uid = 04000;
236  member.gid = 02000;
237 
238  /*
239  * We don't know here how to generate valid member headers and trailers
240  * for the archiving format in use, so if those are needed, some successor
241  * astreamer will have to generate them using the data from 'member'.
242  */
243  astreamer_content(streamer, &member, NULL, 0,
245  astreamer_content(streamer, &member, data, len,
247  astreamer_content(streamer, &member, NULL, 0,
249 }
static void astreamer_content(astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
Definition: astreamer.h:135
@ ASTREAMER_MEMBER_HEADER
Definition: astreamer.h:65
@ ASTREAMER_MEMBER_CONTENTS
Definition: astreamer.h:66
@ ASTREAMER_MEMBER_TRAILER
Definition: astreamer.h:67
int pg_file_create_mode
Definition: file_perm.c:19
#define MAXPGPATH
const void size_t len
const void * data
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char linktarget[MAXPGPATH]
Definition: astreamer.h:88
char pathname[MAXPGPATH]
Definition: astreamer.h:81
pgoff_t size
Definition: astreamer.h:82

References astreamer_content(), ASTREAMER_MEMBER_CONTENTS, ASTREAMER_MEMBER_HEADER, ASTREAMER_MEMBER_TRAILER, data, astreamer_member::gid, astreamer_member::is_directory, astreamer_member::is_link, len, astreamer_member::linktarget, MAXPGPATH, astreamer_member::mode, astreamer_member::pathname, pg_file_create_mode, astreamer_member::size, strlcpy(), and astreamer_member::uid.

Referenced by astreamer_recovery_injector_content(), ReceiveArchiveStream(), and ReceiveTarFile().

◆ astreamer_recovery_injector_content()

static void astreamer_recovery_injector_content ( astreamer streamer,
astreamer_member member,
const char *  data,
int  len,
astreamer_archive_context  context 
)
static

Definition at line 85 of file astreamer_inject.c.

89 {
90  astreamer_recovery_injector *mystreamer;
91 
92  mystreamer = (astreamer_recovery_injector *) streamer;
93  Assert(member != NULL || context == ASTREAMER_ARCHIVE_TRAILER);
94 
95  switch (context)
96  {
98  /* Must copy provided data so we have the option to modify it. */
99  memcpy(&mystreamer->member, member, sizeof(astreamer_member));
100 
101  /*
102  * On v12+, skip standby.signal and edit postgresql.auto.conf; on
103  * older versions, skip recovery.conf.
104  */
105  if (mystreamer->is_recovery_guc_supported)
106  {
107  mystreamer->skip_file =
108  (strcmp(member->pathname, "standby.signal") == 0);
109  mystreamer->is_postgresql_auto_conf =
110  (strcmp(member->pathname, "postgresql.auto.conf") == 0);
111  if (mystreamer->is_postgresql_auto_conf)
112  {
113  /* Remember we saw it so we don't add it again. */
114  mystreamer->found_postgresql_auto_conf = true;
115 
116  /* Increment length by data to be injected. */
117  mystreamer->member.size +=
118  mystreamer->recoveryconfcontents->len;
119 
120  /*
121  * Zap data and len because the archive header is no
122  * longer valid; some subsequent astreamer must regenerate
123  * it if it's necessary.
124  */
125  data = NULL;
126  len = 0;
127  }
128  }
129  else
130  mystreamer->skip_file =
131  (strcmp(member->pathname, "recovery.conf") == 0);
132 
133  /* Do not forward if the file is to be skipped. */
134  if (mystreamer->skip_file)
135  return;
136  break;
137 
139  /* Do not forward if the file is to be skipped. */
140  if (mystreamer->skip_file)
141  return;
142  break;
143 
145  /* Do not forward it the file is to be skipped. */
146  if (mystreamer->skip_file)
147  return;
148 
149  /* Append provided content to whatever we already sent. */
150  if (mystreamer->is_postgresql_auto_conf)
151  astreamer_content(mystreamer->base.bbs_next, member,
152  mystreamer->recoveryconfcontents->data,
153  mystreamer->recoveryconfcontents->len,
155  break;
156 
158  if (mystreamer->is_recovery_guc_supported)
159  {
160  /*
161  * If we didn't already find (and thus modify)
162  * postgresql.auto.conf, inject it as an additional archive
163  * member now.
164  */
165  if (!mystreamer->found_postgresql_auto_conf)
166  astreamer_inject_file(mystreamer->base.bbs_next,
167  "postgresql.auto.conf",
168  mystreamer->recoveryconfcontents->data,
169  mystreamer->recoveryconfcontents->len);
170 
171  /* Inject empty standby.signal file. */
172  astreamer_inject_file(mystreamer->base.bbs_next,
173  "standby.signal", "", 0);
174  }
175  else
176  {
177  /* Inject recovery.conf file with specified contents. */
178  astreamer_inject_file(mystreamer->base.bbs_next,
179  "recovery.conf",
180  mystreamer->recoveryconfcontents->data,
181  mystreamer->recoveryconfcontents->len);
182  }
183 
184  /* Nothing to do here. */
185  break;
186 
187  default:
188  /* Shouldn't happen. */
189  pg_fatal("unexpected state while injecting recovery settings");
190  }
191 
192  astreamer_content(mystreamer->base.bbs_next, &mystreamer->member,
193  data, len, context);
194 }
@ ASTREAMER_ARCHIVE_TRAILER
Definition: astreamer.h:68
void astreamer_inject_file(astreamer *streamer, char *pathname, char *data, int len)
#define Assert(condition)
Definition: c.h:849
#define pg_fatal(...)
tree context
Definition: radixtree.h:1835
astreamer * bbs_next
Definition: astreamer.h:110

References Assert, ASTREAMER_ARCHIVE_TRAILER, astreamer_content(), astreamer_inject_file(), ASTREAMER_MEMBER_CONTENTS, ASTREAMER_MEMBER_HEADER, ASTREAMER_MEMBER_TRAILER, astreamer_recovery_injector::base, astreamer::bbs_next, context, PQExpBufferData::data, data, astreamer_recovery_injector::found_postgresql_auto_conf, astreamer_recovery_injector::is_postgresql_auto_conf, astreamer_recovery_injector::is_recovery_guc_supported, PQExpBufferData::len, len, astreamer_recovery_injector::member, astreamer_member::pathname, pg_fatal, astreamer_recovery_injector::recoveryconfcontents, astreamer_member::size, and astreamer_recovery_injector::skip_file.

◆ astreamer_recovery_injector_finalize()

static void astreamer_recovery_injector_finalize ( astreamer streamer)
static

Definition at line 200 of file astreamer_inject.c.

201 {
202  astreamer_finalize(streamer->bbs_next);
203 }
static void astreamer_finalize(astreamer *streamer)
Definition: astreamer.h:145

References astreamer_finalize(), and astreamer::bbs_next.

◆ astreamer_recovery_injector_free()

static void astreamer_recovery_injector_free ( astreamer streamer)
static

Definition at line 209 of file astreamer_inject.c.

210 {
211  astreamer_free(streamer->bbs_next);
212  pfree(streamer);
213 }
static void astreamer_free(astreamer *streamer)
Definition: astreamer.h:153
void pfree(void *pointer)
Definition: mcxt.c:1521

References astreamer_free(), astreamer::bbs_next, and pfree().

◆ astreamer_recovery_injector_new()

astreamer* astreamer_recovery_injector_new ( astreamer next,
bool  is_recovery_guc_supported,
PQExpBuffer  recoveryconfcontents 
)

Definition at line 65 of file astreamer_inject.c.

68 {
70 
71  streamer = palloc0(sizeof(astreamer_recovery_injector));
72  *((const astreamer_ops **) &streamer->base.bbs_ops) =
74  streamer->base.bbs_next = next;
75  streamer->is_recovery_guc_supported = is_recovery_guc_supported;
77 
78  return &streamer->base;
79 }
static const astreamer_ops astreamer_recovery_injector_ops
static int32 next
Definition: blutils.c:222
void * palloc0(Size size)
Definition: mcxt.c:1347
static PQExpBuffer recoveryconfcontents
const astreamer_ops * bbs_ops
Definition: astreamer.h:109

References astreamer_recovery_injector_ops, astreamer_recovery_injector::base, astreamer::bbs_next, astreamer::bbs_ops, astreamer_recovery_injector::is_recovery_guc_supported, next, palloc0(), astreamer_recovery_injector::recoveryconfcontents, and recoveryconfcontents.

Referenced by CreateBackupStreamer().

Variable Documentation

◆ astreamer_recovery_injector_ops

const astreamer_ops astreamer_recovery_injector_ops
static
Initial value:
= {
}
static void astreamer_recovery_injector_content(astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
static void astreamer_recovery_injector_finalize(astreamer *streamer)
static void astreamer_recovery_injector_free(astreamer *streamer)

Definition at line 36 of file astreamer_inject.c.

Referenced by astreamer_recovery_injector_new().