1 /*-------------------------------------------------------------------------
4 * Common code for control data file output.
7 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/common/controldata_utils.c
14 *-------------------------------------------------------------------------
20 #include "postgres_fe.h"
28 #include "access/xlog_internal.h"
29 #include "catalog/pg_control.h"
30 #include "common/controldata_utils.h"
32 #include "common/file_perm.h"
33 #include "common/logging.h"
35 #include "port/pg_crc32c.h"
39 #include "storage/fd.h"
45 * Get controlfile values. The result is returned as a palloc'd copy of the
48 * crc_ok_p can be used by the caller to see whether the CRC of the control
49 * file data is correct.
52 get_controlfile(const char *DataDir
, bool *crc_ok_p
)
54 char ControlFilePath
[MAXPGPATH
];
56 snprintf(ControlFilePath
, MAXPGPATH
, "%s/global/pg_control", DataDir
);
58 return get_controlfile_by_exact_path(ControlFilePath
, crc_ok_p
);
62 * get_controlfile_by_exact_path()
64 * As above, but the caller specifies the path to the control file itself,
65 * rather than the path to the data directory.
68 get_controlfile_by_exact_path(const char *ControlFilePath
, bool *crc_ok_p
)
70 ControlFileData
*ControlFile
;
81 ControlFile
= palloc_object(ControlFileData
);
84 INIT_CRC32C(last_crc
);
90 if ((fd
= OpenTransientFile(ControlFilePath
, O_RDONLY
| PG_BINARY
)) == -1)
92 (errcode_for_file_access(),
93 errmsg("could not open file \"%s\" for reading: %m",
96 if ((fd
= open(ControlFilePath
, O_RDONLY
| PG_BINARY
, 0)) == -1)
97 pg_fatal("could not open file \"%s\" for reading: %m",
101 r
= read(fd
, ControlFile
, sizeof(ControlFileData
));
102 if (r
!= sizeof(ControlFileData
))
107 (errcode_for_file_access(),
108 errmsg("could not read file \"%s\": %m", ControlFilePath
)));
110 pg_fatal("could not read file \"%s\": %m", ControlFilePath
);
115 (errcode(ERRCODE_DATA_CORRUPTED
),
116 errmsg("could not read file \"%s\": read %d of %zu",
117 ControlFilePath
, r
, sizeof(ControlFileData
))));
119 pg_fatal("could not read file \"%s\": read %d of %zu",
120 ControlFilePath
, r
, sizeof(ControlFileData
));
125 if (CloseTransientFile(fd
) != 0)
127 (errcode_for_file_access(),
128 errmsg("could not close file \"%s\": %m",
132 pg_fatal("could not close file \"%s\": %m", ControlFilePath
);
138 (char *) ControlFile
,
139 offsetof(ControlFileData
, crc
));
142 *crc_ok_p
= EQ_CRC32C(crc
, ControlFile
->crc
);
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.
154 (retries
== 0 || !EQ_CRC32C(crc
, last_crc
)) &&
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)
168 elog(ERROR
, _("byte ordering mismatch"));
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.");
180 * update_controlfile()
182 * Update controlfile values with the contents given by caller. The
183 * contents to write are included in "ControlFile". "do_sync" can be
184 * optionally used to flush the updated control file. Note that it is up
185 * to the caller to properly lock ControlFileLock when calling this
186 * routine in the backend.
189 update_controlfile(const char *DataDir
,
190 ControlFileData
*ControlFile
, bool do_sync
)
193 char buffer
[PG_CONTROL_FILE_SIZE
];
194 char ControlFilePath
[MAXPGPATH
];
196 /* Update timestamp */
197 ControlFile
->time
= (pg_time_t
) time(NULL
);
199 /* Recalculate CRC of control file */
200 INIT_CRC32C(ControlFile
->crc
);
201 COMP_CRC32C(ControlFile
->crc
,
202 (char *) ControlFile
,
203 offsetof(ControlFileData
, crc
));
204 FIN_CRC32C(ControlFile
->crc
);
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.
211 memset(buffer
, 0, PG_CONTROL_FILE_SIZE
);
212 memcpy(buffer
, ControlFile
, sizeof(ControlFileData
));
214 snprintf(ControlFilePath
, sizeof(ControlFilePath
), "%s/%s", DataDir
, XLOG_CONTROL_FILE
);
219 * All errors issue a PANIC, so no need to use OpenTransientFile() and to
220 * worry about file descriptor leaks.
222 if ((fd
= BasicOpenFile(ControlFilePath
, O_RDWR
| PG_BINARY
)) < 0)
224 (errcode_for_file_access(),
225 errmsg("could not open file \"%s\": %m",
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
);
235 pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE
);
237 if (write(fd
, buffer
, PG_CONTROL_FILE_SIZE
) != PG_CONTROL_FILE_SIZE
)
239 /* if write didn't set errno, assume problem is no disk space */
245 (errcode_for_file_access(),
246 errmsg("could not write file \"%s\": %m",
249 pg_fatal("could not write file \"%s\": %m", ControlFilePath
);
253 pgstat_report_wait_end();
259 pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE
);
260 if (pg_fsync(fd
) != 0)
262 (errcode_for_file_access(),
263 errmsg("could not fsync file \"%s\": %m",
265 pgstat_report_wait_end();
268 pg_fatal("could not fsync file \"%s\": %m", ControlFilePath
);
276 (errcode_for_file_access(),
277 errmsg("could not close file \"%s\": %m",
280 pg_fatal("could not close file \"%s\": %m", ControlFilePath
);