PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 "port/pg_crc32c.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "utils/wait_event.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)
 
ControlFileDataget_controlfile_by_exact_path (const char *ControlFilePath, 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 53 of file controldata_utils.c.

54{
56
58
60}
ControlFileData * get_controlfile_by_exact_path(const char *ControlFilePath, bool *crc_ok_p)
char * DataDir
Definition globals.c:71
#define MAXPGPATH
#define snprintf
Definition port.h:260
static int fb(int x)
#define XLOG_CONTROL_FILE

References DataDir, fb(), get_controlfile_by_exact_path(), MAXPGPATH, snprintf, and XLOG_CONTROL_FILE.

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

◆ get_controlfile_by_exact_path()

ControlFileData * get_controlfile_by_exact_path ( const char ControlFilePath,
bool crc_ok_p 
)

Definition at line 69 of file controldata_utils.c.

70{
72 int fd;
74 int r;
75#ifdef FRONTEND
77 int retries = 0;
78#endif
79
81
83
84#ifdef FRONTEND
86
87retry:
88#endif
89
90#ifndef FRONTEND
94 errmsg("could not open file \"%s\" for reading: %m",
96#else
97 if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
98 pg_fatal("could not open file \"%s\" for reading: %m",
100#endif
101
102 r = read(fd, ControlFile, sizeof(ControlFileData));
103 if (r != sizeof(ControlFileData))
104 {
105 if (r < 0)
106#ifndef FRONTEND
109 errmsg("could not read file \"%s\": %m", ControlFilePath)));
110#else
111 pg_fatal("could not read file \"%s\": %m", ControlFilePath);
112#endif
113 else
114#ifndef FRONTEND
117 errmsg("could not read file \"%s\": read %d of %zu",
118 ControlFilePath, r, sizeof(ControlFileData))));
119#else
120 pg_fatal("could not read file \"%s\": read %d of %zu",
121 ControlFilePath, r, sizeof(ControlFileData));
122#endif
123 }
124
125#ifndef FRONTEND
126 if (CloseTransientFile(fd) != 0)
129 errmsg("could not close file \"%s\": %m",
131#else
132 if (close(fd) != 0)
133 pg_fatal("could not close file \"%s\": %m", ControlFilePath);
134#endif
135
136 /* Check the CRC. */
142
144
145#ifdef FRONTEND
146
147 /*
148 * If the server was writing at the same time, it is possible that we read
149 * partially updated contents on some systems. If the CRC doesn't match,
150 * retry a limited number of times until we compute the same bad CRC twice
151 * in a row with a short sleep in between. Then the failure is unlikely
152 * to be due to a concurrent write.
153 */
154 if (!*crc_ok_p &&
155 (retries == 0 || !EQ_CRC32C(crc, last_crc)) &&
156 retries < 10)
157 {
158 retries++;
159 last_crc = crc;
160 pg_usleep(10000);
161 goto retry;
162 }
163#endif
164
165 /* Make sure the control file is valid byte order. */
166 if (ControlFile->pg_control_version % 65536 == 0 &&
167 ControlFile->pg_control_version / 65536 != 0)
168#ifndef FRONTEND
169 elog(ERROR, _("byte ordering mismatch"));
170#else
171 pg_log_warning("possible byte ordering mismatch\n"
172 "The byte ordering used to store the pg_control file might not match the one\n"
173 "used by this program. In that case the results below would be incorrect, and\n"
174 "the PostgreSQL installation would be incompatible with this data directory.");
175#endif
176
177 return ControlFile;
178}
#define Assert(condition)
Definition c.h:915
#define PG_BINARY
Definition c.h:1346
int errcode_for_file_access(void)
Definition elog.c:897
int errcode(int sqlerrcode)
Definition elog.c:874
#define _(x)
Definition elog.c:95
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
int CloseTransientFile(int fd)
Definition fd.c:2855
int OpenTransientFile(const char *fileName, int fileFlags)
Definition fd.c:2678
#define palloc_object(type)
Definition fe_memutils.h:74
#define close(a)
Definition win32.h:12
#define read(a, b, c)
Definition win32.h:13
static char * errmsg
#define pg_fatal(...)
#define ERRCODE_DATA_CORRUPTED
uint32 pg_crc32c
Definition pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition pg_crc32c.h:153
#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:158
return crc
#define pg_log_warning(...)
Definition pgfnames.c:24
static int fd(const char *x, int i)
void pg_usleep(long microsec)
Definition signal.c:53
uint32 pg_control_version
Definition pg_control.h:127
pg_crc32c crc
Definition pg_control.h:242
static ControlFileData * ControlFile
Definition xlog.c:577

References _, Assert, close, CloseTransientFile(), COMP_CRC32C, ControlFile, ControlFileData::crc, crc, elog, EQ_CRC32C, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errcode_for_file_access(), errmsg, ERROR, fb(), fd(), FIN_CRC32C, INIT_CRC32C, OpenTransientFile(), palloc_object, PG_BINARY, ControlFileData::pg_control_version, pg_fatal, pg_log_warning, pg_usleep(), and read.

Referenced by check_control_files(), get_controlfile(), and verify_control_file().

◆ update_controlfile()

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

Definition at line 190 of file controldata_utils.c.

192{
193 int fd;
194 char buffer[PG_CONTROL_FILE_SIZE];
196
197 /* Update timestamp */
198 ControlFile->time = (pg_time_t) time(NULL);
199
200 /* Recalculate CRC of control file */
206
207 /*
208 * Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding
209 * the excess over sizeof(ControlFileData), to avoid premature EOF related
210 * errors when reading it.
211 */
212 memset(buffer, 0, PG_CONTROL_FILE_SIZE);
213 memcpy(buffer, ControlFile, sizeof(ControlFileData));
214
216
217#ifndef FRONTEND
218
219 /*
220 * All errors issue a PANIC, so no need to use OpenTransientFile() and to
221 * worry about file descriptor leaks.
222 */
226 errmsg("could not open file \"%s\": %m",
228#else
230 pg_file_create_mode)) == -1)
231 pg_fatal("could not open file \"%s\": %m", ControlFilePath);
232#endif
233
234 errno = 0;
235#ifndef FRONTEND
237#endif
239 {
240 /* if write didn't set errno, assume problem is no disk space */
241 if (errno == 0)
242 errno = ENOSPC;
243
244#ifndef FRONTEND
247 errmsg("could not write file \"%s\": %m",
249#else
250 pg_fatal("could not write file \"%s\": %m", ControlFilePath);
251#endif
252 }
253#ifndef FRONTEND
255#endif
256
257 if (do_sync)
258 {
259#ifndef FRONTEND
261 if (pg_fsync(fd) != 0)
264 errmsg("could not fsync file \"%s\": %m",
267#else
268 if (fsync(fd) != 0)
269 pg_fatal("could not fsync file \"%s\": %m", ControlFilePath);
270#endif
271 }
272
273 if (close(fd) != 0)
274 {
275#ifndef FRONTEND
278 errmsg("could not close file \"%s\": %m",
280#else
281 pg_fatal("could not close file \"%s\": %m", ControlFilePath);
282#endif
283 }
284}
#define PANIC
Definition elog.h:42
int BasicOpenFile(const char *fileName, int fileFlags)
Definition fd.c:1090
int pg_fsync(int fd)
Definition fd.c:390
int pg_file_create_mode
Definition file_perm.c:19
static bool do_sync
Definition initdb.c:164
#define write(a, b, c)
Definition win32.h:14
#define PG_CONTROL_FILE_SIZE
Definition pg_control.h:260
int64 pg_time_t
Definition pgtime.h:23
pg_time_t time
Definition pg_control.h:134
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:69
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
#define fsync(fd)
Definition win32_port.h:83

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

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