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 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 52 of file controldata_utils.c.

53{
55
57
59}
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 68 of file controldata_utils.c.

69{
71 int fd;
73 int r;
74#ifdef FRONTEND
76 int retries = 0;
77#endif
78
80
82
83#ifdef FRONTEND
85
86retry:
87#endif
88
89#ifndef FRONTEND
93 errmsg("could not open file \"%s\" for reading: %m",
95#else
96 if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
97 pg_fatal("could not open file \"%s\" for reading: %m",
99#endif
100
101 r = read(fd, ControlFile, sizeof(ControlFileData));
102 if (r != sizeof(ControlFileData))
103 {
104 if (r < 0)
105#ifndef FRONTEND
108 errmsg("could not read file \"%s\": %m", ControlFilePath)));
109#else
110 pg_fatal("could not read file \"%s\": %m", ControlFilePath);
111#endif
112 else
113#ifndef FRONTEND
116 errmsg("could not read file \"%s\": read %d of %zu",
117 ControlFilePath, r, sizeof(ControlFileData))));
118#else
119 pg_fatal("could not read file \"%s\": read %d of %zu",
120 ControlFilePath, r, sizeof(ControlFileData));
121#endif
122 }
123
124#ifndef FRONTEND
125 if (CloseTransientFile(fd) != 0)
128 errmsg("could not close file \"%s\": %m",
130#else
131 if (close(fd) != 0)
132 pg_fatal("could not close file \"%s\": %m", ControlFilePath);
133#endif
134
135 /* Check the CRC. */
141
143
144#ifdef FRONTEND
145
146 /*
147 * If the server was writing at the same time, it is possible that we read
148 * partially updated contents on some systems. If the CRC doesn't match,
149 * retry a limited number of times until we compute the same bad CRC twice
150 * in a row with a short sleep in between. Then the failure is unlikely
151 * to be due to a concurrent write.
152 */
153 if (!*crc_ok_p &&
154 (retries == 0 || !EQ_CRC32C(crc, last_crc)) &&
155 retries < 10)
156 {
157 retries++;
158 last_crc = crc;
159 pg_usleep(10000);
160 goto retry;
161 }
162#endif
163
164 /* Make sure the control file is valid byte order. */
165 if (ControlFile->pg_control_version % 65536 == 0 &&
166 ControlFile->pg_control_version / 65536 != 0)
167#ifndef FRONTEND
168 elog(ERROR, _("byte ordering mismatch"));
169#else
170 pg_log_warning("possible byte ordering mismatch\n"
171 "The byte ordering used to store the pg_control file might not match the one\n"
172 "used by this program. In that case the results below would be incorrect, and\n"
173 "the PostgreSQL installation would be incompatible with this data directory.");
174#endif
175
176 return ControlFile;
177}
#define Assert(condition)
Definition c.h:873
#define PG_BINARY
Definition c.h:1287
int errcode_for_file_access(void)
Definition elog.c:886
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define _(x)
Definition elog.c:91
#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:2851
int OpenTransientFile(const char *fileName, int fileFlags)
Definition fd.c:2674
#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
#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:576

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 189 of file controldata_utils.c.

191{
192 int fd;
193 char buffer[PG_CONTROL_FILE_SIZE];
195
196 /* Update timestamp */
197 ControlFile->time = (pg_time_t) time(NULL);
198
199 /* Recalculate CRC of control file */
205
206 /*
207 * Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding
208 * the excess over sizeof(ControlFileData), to avoid premature EOF related
209 * errors when reading it.
210 */
211 memset(buffer, 0, PG_CONTROL_FILE_SIZE);
212 memcpy(buffer, ControlFile, sizeof(ControlFileData));
213
215
216#ifndef FRONTEND
217
218 /*
219 * All errors issue a PANIC, so no need to use OpenTransientFile() and to
220 * worry about file descriptor leaks.
221 */
225 errmsg("could not open file \"%s\": %m",
227#else
229 pg_file_create_mode)) == -1)
230 pg_fatal("could not open file \"%s\": %m", ControlFilePath);
231#endif
232
233 errno = 0;
234#ifndef FRONTEND
236#endif
238 {
239 /* if write didn't set errno, assume problem is no disk space */
240 if (errno == 0)
241 errno = ENOSPC;
242
243#ifndef FRONTEND
246 errmsg("could not write file \"%s\": %m",
248#else
249 pg_fatal("could not write file \"%s\": %m", ControlFilePath);
250#endif
251 }
252#ifndef FRONTEND
254#endif
255
256 if (do_sync)
257 {
258#ifndef FRONTEND
260 if (pg_fsync(fd) != 0)
263 errmsg("could not fsync file \"%s\": %m",
266#else
267 if (fsync(fd) != 0)
268 pg_fatal("could not fsync file \"%s\": %m", ControlFilePath);
269#endif
270 }
271
272 if (close(fd) != 0)
273 {
274#ifndef FRONTEND
277 errmsg("could not close file \"%s\": %m",
279#else
280 pg_fatal("could not close file \"%s\": %m", ControlFilePath);
281#endif
282 }
283}
#define PANIC
Definition elog.h:42
int BasicOpenFile(const char *fileName, int fileFlags)
Definition fd.c:1086
int pg_fsync(int fd)
Definition fd.c:386
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().