PostgreSQL Source Code git master
Loading...
Searching...
No Matches
backup_label.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include "access/xlogdefs.h"
#include "backup_label.h"
#include "common/file_perm.h"
#include "common/logging.h"
#include "write_manifest.h"
Include dependency graph for backup_label.c:

Go to the source code of this file.

Functions

static int get_eol_offset (StringInfo buf)
 
static bool line_starts_with (char *s, char *e, char *match, char **sout)
 
static bool parse_lsn (char *s, char *e, XLogRecPtr *lsn, char **c)
 
static bool parse_tli (char *s, char *e, TimeLineID *tli)
 
void parse_backup_label (char *filename, StringInfo buf, TimeLineID *start_tli, XLogRecPtr *start_lsn, TimeLineID *previous_tli, XLogRecPtr *previous_lsn)
 
void write_backup_label (char *output_directory, StringInfo buf, pg_checksum_type checksum_type, manifest_writer *mwriter)
 

Function Documentation

◆ get_eol_offset()

static int get_eol_offset ( StringInfo  buf)
static

Definition at line 202 of file backup_label.c.

203{
204 int eo = buf->cursor;
205
206 while (eo < buf->len)
207 {
208 if (buf->data[eo] == '\n')
209 return eo + 1;
210 ++eo;
211 }
212
213 return eo;
214}
const void size_t len
static char buf[DEFAULT_XLOG_SEG_SIZE]
static int fb(int x)

References buf, fb(), and len.

Referenced by parse_backup_label(), and write_backup_label().

◆ line_starts_with()

static bool line_starts_with ( char s,
char e,
char match,
char **  sout 
)
static

Definition at line 225 of file backup_label.c.

226{
227 while (s < e && *match != '\0' && *s == *match)
228 ++s, ++match;
229
230 if (*match == '\0' && sout != NULL)
231 *sout = s;
232
233 return (*match == '\0');
234}
e

References fb().

Referenced by parse_backup_label(), and write_backup_label().

◆ parse_backup_label()

void parse_backup_label ( char filename,
StringInfo  buf,
TimeLineID start_tli,
XLogRecPtr start_lsn,
TimeLineID previous_tli,
XLogRecPtr previous_lsn 
)

Definition at line 45 of file backup_label.c.

48{
49 int found = 0;
50
51 *start_tli = 0;
52 *start_lsn = InvalidXLogRecPtr;
53 *previous_tli = 0;
55
56 while (buf->cursor < buf->len)
57 {
58 char *s = &buf->data[buf->cursor];
59 int eo = get_eol_offset(buf);
60 char *e = &buf->data[eo];
61 char *c;
62
63 if (line_starts_with(s, e, "START WAL LOCATION: ", &s))
64 {
65 if (!parse_lsn(s, e, start_lsn, &c))
66 pg_fatal("%s: could not parse %s",
67 filename, "START WAL LOCATION");
68 if (c >= e || *c != ' ')
69 pg_fatal("%s: improper terminator for %s",
70 filename, "START WAL LOCATION");
71 found |= 1;
72 }
73 else if (line_starts_with(s, e, "START TIMELINE: ", &s))
74 {
75 if (!parse_tli(s, e, start_tli))
76 pg_fatal("%s: could not parse TLI for %s",
77 filename, "START TIMELINE");
78 if (*start_tli == 0)
79 pg_fatal("%s: invalid TLI", filename);
80 found |= 2;
81 }
82 else if (line_starts_with(s, e, "INCREMENTAL FROM LSN: ", &s))
83 {
84 if (!parse_lsn(s, e, previous_lsn, &c))
85 pg_fatal("%s: could not parse %s",
86 filename, "INCREMENTAL FROM LSN");
87 if (c >= e || *c != '\n')
88 pg_fatal("%s: improper terminator for %s",
89 filename, "INCREMENTAL FROM LSN");
90 found |= 4;
91 }
92 else if (line_starts_with(s, e, "INCREMENTAL FROM TLI: ", &s))
93 {
94 if (!parse_tli(s, e, previous_tli))
95 pg_fatal("%s: could not parse %s",
96 filename, "INCREMENTAL FROM TLI");
97 if (*previous_tli == 0)
98 pg_fatal("%s: invalid TLI", filename);
99 found |= 8;
100 }
101
102 buf->cursor = eo;
103 }
104
105 if ((found & 1) == 0)
106 pg_fatal("%s: could not find %s", filename, "START WAL LOCATION");
107 if ((found & 2) == 0)
108 pg_fatal("%s: could not find %s", filename, "START TIMELINE");
109 if ((found & 4) != 0 && (found & 8) == 0)
110 pg_fatal("%s: %s requires %s", filename,
111 "INCREMENTAL FROM LSN", "INCREMENTAL FROM TLI");
112 if ((found & 8) != 0 && (found & 4) == 0)
113 pg_fatal("%s: %s requires %s", filename,
114 "INCREMENTAL FROM TLI", "INCREMENTAL FROM LSN");
115}
static int get_eol_offset(StringInfo buf)
static bool parse_lsn(char *s, char *e, XLogRecPtr *lsn, char **c)
static bool line_starts_with(char *s, char *e, char *match, char **sout)
static bool parse_tli(char *s, char *e, TimeLineID *tli)
#define pg_fatal(...)
static char * filename
Definition pg_dumpall.c:120
char * c
#define InvalidXLogRecPtr
Definition xlogdefs.h:28

References buf, fb(), filename, get_eol_offset(), InvalidXLogRecPtr, line_starts_with(), parse_lsn(), parse_tli(), and pg_fatal.

Referenced by check_backup_label_files().

◆ parse_lsn()

static bool parse_lsn ( char s,
char e,
XLogRecPtr lsn,
char **  c 
)
static

Definition at line 242 of file backup_label.c.

243{
244 char save = *e;
245 int nchars;
246 bool success;
247 unsigned hi;
248 unsigned lo;
249
250 *e = '\0';
251 success = (sscanf(s, "%X/%08X%n", &hi, &lo, &nchars) == 2);
252 *e = save;
253
254 if (success)
255 {
256 *lsn = ((XLogRecPtr) hi) << 32 | (XLogRecPtr) lo;
257 *c = s + nchars;
258 }
259
260 return success;
261}
static bool success
Definition initdb.c:188
uint64 XLogRecPtr
Definition xlogdefs.h:21

References fb(), and success.

Referenced by parse_backup_label().

◆ parse_tli()

static bool parse_tli ( char s,
char e,
TimeLineID tli 
)
static

Definition at line 270 of file backup_label.c.

271{
272 char save = *e;
273 int nchars;
274 bool success;
275
276 *e = '\0';
277 success = (sscanf(s, "%u%n", tli, &nchars) == 1);
278 *e = save;
279
280 if (success && s[nchars] != '\n')
281 success = false;
282
283 return success;
284}

References fb(), and success.

Referenced by parse_backup_label().

◆ write_backup_label()

void write_backup_label ( char output_directory,
StringInfo  buf,
pg_checksum_type  checksum_type,
manifest_writer mwriter 
)

Definition at line 127 of file backup_label.c.

129{
131 int output_fd;
132 pg_checksum_context checksum_ctx;
133 uint8 checksum_payload[PG_CHECKSUM_MAX_LENGTH];
134 int checksum_length;
135
136 pg_checksum_init(&checksum_ctx, checksum_type);
137
139
143 pg_fatal("could not open file \"%s\": %m", output_filename);
144
145 while (buf->cursor < buf->len)
146 {
147 char *s = &buf->data[buf->cursor];
148 int eo = get_eol_offset(buf);
149 char *e = &buf->data[eo];
150
151 if (!line_starts_with(s, e, "INCREMENTAL FROM LSN: ", NULL) &&
152 !line_starts_with(s, e, "INCREMENTAL FROM TLI: ", NULL))
153 {
154 const size_t bytes_left = e - s;
155 ssize_t wb;
156
158 if (wb != bytes_left)
159 {
160 if (wb < 0)
161 pg_fatal("could not write file \"%s\": %m", output_filename);
162 else
163 pg_fatal("could not write file \"%s\": wrote %zd of %zu",
165 }
166 if (pg_checksum_update(&checksum_ctx, (uint8 *) s, bytes_left) < 0)
167 pg_fatal("could not update checksum of file \"%s\"",
169 }
170
171 buf->cursor = eo;
172 }
173
174 if (close(output_fd) != 0)
175 pg_fatal("could not close file \"%s\": %m", output_filename);
176
177 checksum_length = pg_checksum_final(&checksum_ctx, checksum_payload);
178
179 if (mwriter != NULL)
180 {
181 struct stat sb;
182
183 /*
184 * We could track the length ourselves, but must stat() to get the
185 * mtime.
186 */
187 if (stat(output_filename, &sb) < 0)
188 pg_fatal("could not stat file \"%s\": %m", output_filename);
189 add_file_to_manifest(mwriter, "backup_label", sb.st_size,
190 sb.st_mtime, checksum_type,
191 checksum_length, checksum_payload);
192 }
193}
uint8_t uint8
Definition c.h:681
#define PG_BINARY
Definition c.h:1431
int pg_checksum_final(pg_checksum_context *context, uint8 *output)
int pg_checksum_update(pg_checksum_context *context, const uint8 *input, size_t len)
int pg_checksum_init(pg_checksum_context *context, pg_checksum_type type)
#define PG_CHECKSUM_MAX_LENGTH
char * output_filename
Definition ecpg.c:24
int pg_file_create_mode
Definition file_perm.c:19
#define close(a)
Definition win32.h:12
#define write(a, b, c)
Definition win32.h:14
#define MAXPGPATH
#define snprintf
Definition port.h:261
#define stat
Definition win32_port.h:74
void add_file_to_manifest(manifest_writer *mwriter, const char *manifest_path, uint64 size, time_t mtime, pg_checksum_type checksum_type, int checksum_length, uint8 *checksum_payload)

References add_file_to_manifest(), buf, close, fb(), get_eol_offset(), line_starts_with(), MAXPGPATH, output_filename, PG_BINARY, pg_checksum_final(), pg_checksum_init(), PG_CHECKSUM_MAX_LENGTH, pg_checksum_update(), pg_fatal, pg_file_create_mode, snprintf, stat, and write.

Referenced by main().