PostgreSQL Source Code git master
controldata_utils.h File Reference
Include dependency graph for controldata_utils.h:
This graph shows which files directly or indirectly include this file:

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{
54 char ControlFilePath[MAXPGPATH];
55
56 snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
57
58 return get_controlfile_by_exact_path(ControlFilePath, crc_ok_p);
59}
ControlFileData * get_controlfile_by_exact_path(const char *ControlFilePath, bool *crc_ok_p)
char * DataDir
Definition: globals.c:70
#define MAXPGPATH
#define snprintf
Definition: port.h:238

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

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
75 pg_crc32c last_crc;
76 int retries = 0;
77#endif
78
79 Assert(crc_ok_p);
80
82
83#ifdef FRONTEND
84 INIT_CRC32C(last_crc);
85
86retry:
87#endif
88
89#ifndef FRONTEND
90 if ((fd = OpenTransientFile(ControlFilePath, O_RDONLY | PG_BINARY)) == -1)
93 errmsg("could not open file \"%s\" for reading: %m",
94 ControlFilePath)));
95#else
96 if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
97 pg_fatal("could not open file \"%s\" for reading: %m",
98 ControlFilePath);
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",
129 ControlFilePath)));
130#else
131 if (close(fd) != 0)
132 pg_fatal("could not close file \"%s\": %m", ControlFilePath);
133#endif
134
135 /* Check the CRC. */
138 (char *) ControlFile,
139 offsetof(ControlFileData, crc));
141
142 *crc_ok_p = EQ_CRC32C(crc, ControlFile->crc);
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:815
#define PG_BINARY
Definition: c.h:1230
int errcode_for_file_access(void)
Definition: elog.c:876
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define _(x)
Definition: elog.c:90
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
int CloseTransientFile(int fd)
Definition: fd.c:2831
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2655
#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
Definition: pg_basebackup.c:41
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:98
#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:103
return crc
#define pg_log_warning(...)
Definition: pgfnames.c:24
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pg_usleep(long microsec)
Definition: signal.c:53
uint32 pg_control_version
Definition: pg_control.h:125
pg_crc32c crc
Definition: pg_control.h:232
static ControlFileData * ControlFile
Definition: xlog.c:574

References _, Assert, close, CloseTransientFile(), COMP_CRC32C, ControlFile, ControlFileData::crc, crc, elog, EQ_CRC32C, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errcode_for_file_access(), errmsg(), ERROR, 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];
194 char ControlFilePath[MAXPGPATH];
195
196 /* Update timestamp */
197 ControlFile->time = (pg_time_t) time(NULL);
198
199 /* Recalculate CRC of control file */
202 (char *) ControlFile,
203 offsetof(ControlFileData, crc));
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
214 snprintf(ControlFilePath, sizeof(ControlFilePath), "%s/%s", DataDir, XLOG_CONTROL_FILE);
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 */
222 if ((fd = BasicOpenFile(ControlFilePath, O_RDWR | PG_BINARY)) < 0)
225 errmsg("could not open file \"%s\": %m",
226 ControlFilePath)));
227#else
228 if ((fd = open(ControlFilePath, O_WRONLY | PG_BINARY,
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
235 pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE);
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",
247 ControlFilePath)));
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
259 pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE);
260 if (pg_fsync(fd) != 0)
263 errmsg("could not fsync file \"%s\": %m",
264 ControlFilePath)));
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",
278 ControlFilePath)));
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:385
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:250
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:132
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
#define fsync(fd)
Definition: win32_port.h:83
#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, 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().