PostgreSQL Source Code  git master
controldata_utils.c File Reference
#include "postgres.h"
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include "access/xlog_internal.h"
#include "catalog/pg_control.h"
#include "common/controldata_utils.h"
#include "common/file_perm.h"
#include "port/pg_crc32c.h"
#include "pgstat.h"
#include "storage/fd.h"
Include dependency graph for controldata_utils.c:

Go to the source code of this file.

Functions

ControlFileDataget_controlfile (const char *DataDir, bool *crc_ok_p)
 
void update_controlfile (const char *DataDir, ControlFileData *ControlFile, bool do_sync)
 

Function Documentation

◆ get_controlfile()

ControlFileData* get_controlfile ( const char *  DataDir,
bool crc_ok_p 
)

Definition at line 52 of file controldata_utils.c.

53 {
55  int fd;
56  char ControlFilePath[MAXPGPATH];
57  pg_crc32c crc;
58  int r;
59 
60  AssertArg(crc_ok_p);
61 
63  snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
64 
65 #ifndef FRONTEND
66  if ((fd = OpenTransientFile(ControlFilePath, O_RDONLY | PG_BINARY)) == -1)
67  ereport(ERROR,
69  errmsg("could not open file \"%s\" for reading: %m",
70  ControlFilePath)));
71 #else
72  if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
73  pg_fatal("could not open file \"%s\" for reading: %m",
74  ControlFilePath);
75 #endif
76 
77  r = read(fd, ControlFile, sizeof(ControlFileData));
78  if (r != sizeof(ControlFileData))
79  {
80  if (r < 0)
81 #ifndef FRONTEND
82  ereport(ERROR,
84  errmsg("could not read file \"%s\": %m", ControlFilePath)));
85 #else
86  pg_fatal("could not read file \"%s\": %m", ControlFilePath);
87 #endif
88  else
89 #ifndef FRONTEND
90  ereport(ERROR,
92  errmsg("could not read file \"%s\": read %d of %zu",
93  ControlFilePath, r, sizeof(ControlFileData))));
94 #else
95  pg_fatal("could not read file \"%s\": read %d of %zu",
96  ControlFilePath, r, sizeof(ControlFileData));
97 #endif
98  }
99 
100 #ifndef FRONTEND
101  if (CloseTransientFile(fd) != 0)
102  ereport(ERROR,
104  errmsg("could not close file \"%s\": %m",
105  ControlFilePath)));
106 #else
107  if (close(fd) != 0)
108  pg_fatal("could not close file \"%s\": %m", ControlFilePath);
109 #endif
110 
111  /* Check the CRC. */
112  INIT_CRC32C(crc);
114  (char *) ControlFile,
116  FIN_CRC32C(crc);
117 
118  *crc_ok_p = EQ_CRC32C(crc, ControlFile->crc);
119 
120  /* Make sure the control file is valid byte order. */
121  if (ControlFile->pg_control_version % 65536 == 0 &&
122  ControlFile->pg_control_version / 65536 != 0)
123 #ifndef FRONTEND
124  elog(ERROR, _("byte ordering mismatch"));
125 #else
126  pg_log_warning("possible byte ordering mismatch\n"
127  "The byte ordering used to store the pg_control file might not match the one\n"
128  "used by this program. In that case the results below would be incorrect, and\n"
129  "the PostgreSQL installation would be incompatible with this data directory.");
130 #endif
131 
132  return ControlFile;
133 }
#define offsetof(type, field)
Definition: c.h:738
#define PG_BINARY
Definition: c.h:1279
#define AssertArg(condition)
Definition: c.h:817
int errcode_for_file_access(void)
Definition: elog.c:716
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define _(x)
Definition: elog.c:89
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
int CloseTransientFile(int fd)
Definition: fd.c:2625
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2448
char * DataDir
Definition: globals.c:66
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
void * palloc(Size size)
Definition: mcxt.c:1068
#define pg_fatal(...)
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:43
#define MAXPGPATH
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
return crc
#define pg_log_warning(...)
Definition: pgfnames.c:24
#define snprintf
Definition: port.h:225
static int fd(const char *x, int i)
Definition: preproc-init.c:105
uint32 pg_control_version
Definition: pg_control.h:123
pg_crc32c crc
Definition: pg_control.h:230
static ControlFileData * ControlFile
Definition: xlog.c:566

References _, AssertArg, close, CloseTransientFile(), COMP_CRC32C, ControlFile, ControlFileData::crc, crc, DataDir, elog(), EQ_CRC32C, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errcode_for_file_access(), errmsg(), ERROR, fd(), FIN_CRC32C, INIT_CRC32C, MAXPGPATH, offsetof, OpenTransientFile(), palloc(), PG_BINARY, ControlFileData::pg_control_version, pg_fatal, pg_log_warning, read, and snprintf.

Referenced by get_control_dbstate(), main(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), and pg_control_system().

◆ update_controlfile()

void update_controlfile ( const char *  DataDir,
ControlFileData ControlFile,
bool  do_sync 
)

Definition at line 145 of file controldata_utils.c.

147 {
148  int fd;
149  char buffer[PG_CONTROL_FILE_SIZE];
150  char ControlFilePath[MAXPGPATH];
151 
152  /*
153  * Apply the same static assertions as in backend's WriteControlFile().
154  */
156  "pg_control is too large for atomic disk writes");
158  "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE");
159 
160  /* Update timestamp */
161  ControlFile->time = (pg_time_t) time(NULL);
162 
163  /* Recalculate CRC of control file */
166  (char *) ControlFile,
169 
170  /*
171  * Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding
172  * the excess over sizeof(ControlFileData), to avoid premature EOF related
173  * errors when reading it.
174  */
175  memset(buffer, 0, PG_CONTROL_FILE_SIZE);
176  memcpy(buffer, ControlFile, sizeof(ControlFileData));
177 
178  snprintf(ControlFilePath, sizeof(ControlFilePath), "%s/%s", DataDir, XLOG_CONTROL_FILE);
179 
180 #ifndef FRONTEND
181 
182  /*
183  * All errors issue a PANIC, so no need to use OpenTransientFile() and to
184  * worry about file descriptor leaks.
185  */
186  if ((fd = BasicOpenFile(ControlFilePath, O_RDWR | PG_BINARY)) < 0)
187  ereport(PANIC,
189  errmsg("could not open file \"%s\": %m",
190  ControlFilePath)));
191 #else
192  if ((fd = open(ControlFilePath, O_WRONLY | PG_BINARY,
193  pg_file_create_mode)) == -1)
194  pg_fatal("could not open file \"%s\": %m", ControlFilePath);
195 #endif
196 
197  errno = 0;
198 #ifndef FRONTEND
200 #endif
202  {
203  /* if write didn't set errno, assume problem is no disk space */
204  if (errno == 0)
205  errno = ENOSPC;
206 
207 #ifndef FRONTEND
208  ereport(PANIC,
210  errmsg("could not write file \"%s\": %m",
211  ControlFilePath)));
212 #else
213  pg_fatal("could not write file \"%s\": %m", ControlFilePath);
214 #endif
215  }
216 #ifndef FRONTEND
218 #endif
219 
220  if (do_sync)
221  {
222 #ifndef FRONTEND
224  if (pg_fsync(fd) != 0)
225  ereport(PANIC,
227  errmsg("could not fsync file \"%s\": %m",
228  ControlFilePath)));
230 #else
231  if (fsync(fd) != 0)
232  pg_fatal("could not fsync file \"%s\": %m", ControlFilePath);
233 #endif
234  }
235 
236  if (close(fd) != 0)
237  {
238 #ifndef FRONTEND
239  ereport(PANIC,
241  errmsg("could not close file \"%s\": %m",
242  ControlFilePath)));
243 #else
244  pg_fatal("could not close file \"%s\": %m", ControlFilePath);
245 #endif
246  }
247 }
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:929
#define PANIC
Definition: elog.h:36
int BasicOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1008
int pg_fsync(int fd)
Definition: fd.c:359
int pg_file_create_mode
Definition: file_perm.c:19
static bool do_sync
Definition: initdb.c:147
#define write(a, b, c)
Definition: win32.h:14
#define PG_CONTROL_MAX_SAFE_SIZE
Definition: pg_control.h:239
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:248
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:130
@ WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE
Definition: wait_event.h:170
@ WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE
Definition: wait_event.h:168
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 fsync(fd)
Definition: win32_port.h:76
#define XLOG_CONTROL_FILE

References BasicOpenFile(), close, COMP_CRC32C, ControlFile, ControlFileData::crc, crc, DataDir, do_sync, ereport, errcode_for_file_access(), errmsg(), fd(), FIN_CRC32C, fsync, INIT_CRC32C, MAXPGPATH, offsetof, PANIC, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_MAX_SAFE_SIZE, pg_fatal, pg_file_create_mode, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), snprintf, StaticAssertStmt, ControlFileData::time, WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE, WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE, write, and XLOG_CONTROL_FILE.

Referenced by main(), perform_rewind(), RewriteControlFile(), and UpdateControlFile().