1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-31 17:02:12 +03:00

Expose control file data via SQL accessible functions.

Add four new SQL accessible functions: pg_control_system(),
pg_control_checkpoint(), pg_control_recovery(), and pg_control_init()
which expose a subset of the control file data.

Along the way move the code to read and validate the control file to
src/common, where it can be shared by the new backend functions
and the original pg_controldata frontend program.

Patch by me, significant input, testing, and review by Michael Paquier.
This commit is contained in:
Joe Conway
2016-03-05 11:10:19 -08:00
parent d34794f7d5
commit dc7d70ea05
11 changed files with 900 additions and 105 deletions

View File

@@ -36,8 +36,8 @@ override CPPFLAGS += -DVAL_LDFLAGS_EX="\"$(LDFLAGS_EX)\""
override CPPFLAGS += -DVAL_LDFLAGS_SL="\"$(LDFLAGS_SL)\""
override CPPFLAGS += -DVAL_LIBS="\"$(LIBS)\""
OBJS_COMMON = config_info.o exec.o pg_lzcompress.o pgfnames.o psprintf.o \
relpath.o rmtree.o string.o username.o wait_error.o
OBJS_COMMON = config_info.o controldata_utils.o exec.o pg_lzcompress.o \
pgfnames.o psprintf.o relpath.o rmtree.o string.o username.o wait_error.o
OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o restricted_token.o

View File

@@ -0,0 +1,100 @@
/*-------------------------------------------------------------------------
*
* controldata_utils.c
* Common code for control data file output.
*
*
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/common/controldata_utils.c
*
*-------------------------------------------------------------------------
*/
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "catalog/pg_control.h"
#include "common/controldata_utils.h"
#include "port/pg_crc32c.h"
#ifndef FRONTEND
/* NOTE: caller must provide gettext call around the format string */
#define log_error(...) \
elog(ERROR, __VA_ARGS__)
#else
#define log_error(...) \
do { \
char *buf = psprintf(__VA_ARGS__); \
fprintf(stderr, "%s: %s\n", progname, buf); \
exit(2); \
} while (0)
#endif
/*
* get_controlfile(char *DataDir, const char *progname)
*
* Get controlfile values. The caller is responsible
* for pfreeing the result.
*/
ControlFileData *
get_controlfile(char *DataDir, const char *progname)
{
ControlFileData *ControlFile;
int fd;
char ControlFilePath[MAXPGPATH];
pg_crc32c crc;
ControlFile = palloc(sizeof(ControlFileData));
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
log_error(_("could not open file \"%s\" for reading: %s"),
ControlFilePath, strerror(errno));
if (read(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
log_error(_("could not read file \"%s\": %s"),
ControlFilePath, strerror(errno));
close(fd);
/* Check the CRC. */
INIT_CRC32C(crc);
COMP_CRC32C(crc,
(char *) ControlFile,
offsetof(ControlFileData, crc));
FIN_CRC32C(crc);
if (!EQ_CRC32C(crc, ControlFile->crc))
#ifndef FRONTEND
elog(ERROR, _("calculated CRC checksum does not match value stored in file"));
#else
printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
"Either the file is corrupt, or it has a different layout than this program\n"
"is expecting. The results below are untrustworthy.\n\n"));
#endif
/* Make sure the control file is valid byte order. */
if (ControlFile->pg_control_version % 65536 == 0 &&
ControlFile->pg_control_version / 65536 != 0)
#ifndef FRONTEND
elog(ERROR, _("byte ordering mismatch"));
#else
printf(_("WARNING: possible byte ordering mismatch\n"
"The byte ordering used to store the pg_control file might not match the one\n"
"used by this program. In that case the results below would be incorrect, and\n"
"the PostgreSQL installation would be incompatible with this data directory.\n"));
#endif
return ControlFile;
}