Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * controldata_utils.c
4 : * Common code for control data file output.
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : *
11 : * IDENTIFICATION
12 : * src/common/controldata_utils.c
13 : *
14 : *-------------------------------------------------------------------------
15 : */
16 :
17 : #ifndef FRONTEND
18 : #include "postgres.h"
19 : #else
20 : #include "postgres_fe.h"
21 : #endif
22 :
23 : #include <unistd.h>
24 : #include <sys/stat.h>
25 : #include <fcntl.h>
26 :
27 : #include "catalog/pg_control.h"
28 : #include "common/controldata_utils.h"
29 : #include "port/pg_crc32c.h"
30 :
31 : /*
32 : * get_controlfile(char *DataDir, const char *progname, bool *crc_ok_p)
33 : *
34 : * Get controlfile values. The result is returned as a palloc'd copy of the
35 : * control file data.
36 : *
37 : * crc_ok_p can be used by the caller to see whether the CRC of the control
38 : * file data is correct.
39 : */
40 : ControlFileData *
41 0 : get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p)
42 : {
43 : ControlFileData *ControlFile;
44 : int fd;
45 : char ControlFilePath[MAXPGPATH];
46 : pg_crc32c crc;
47 :
48 0 : AssertArg(crc_ok_p);
49 :
50 0 : ControlFile = palloc(sizeof(ControlFileData));
51 0 : snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
52 :
53 0 : if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
54 : #ifndef FRONTEND
55 0 : ereport(ERROR,
56 : (errcode_for_file_access(),
57 : errmsg("could not open file \"%s\" for reading: %m",
58 : ControlFilePath)));
59 : #else
60 : {
61 0 : fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
62 0 : progname, ControlFilePath, strerror(errno));
63 0 : exit(EXIT_FAILURE);
64 : }
65 : #endif
66 :
67 0 : if (read(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
68 : #ifndef FRONTEND
69 0 : ereport(ERROR,
70 : (errcode_for_file_access(),
71 : errmsg("could not read file \"%s\": %m", ControlFilePath)));
72 : #else
73 : {
74 0 : fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
75 0 : progname, ControlFilePath, strerror(errno));
76 0 : exit(EXIT_FAILURE);
77 : }
78 : #endif
79 :
80 0 : close(fd);
81 :
82 : /* Check the CRC. */
83 0 : INIT_CRC32C(crc);
84 0 : COMP_CRC32C(crc,
85 : (char *) ControlFile,
86 : offsetof(ControlFileData, crc));
87 0 : FIN_CRC32C(crc);
88 :
89 0 : *crc_ok_p = EQ_CRC32C(crc, ControlFile->crc);
90 :
91 : /* Make sure the control file is valid byte order. */
92 0 : if (ControlFile->pg_control_version % 65536 == 0 &&
93 0 : ControlFile->pg_control_version / 65536 != 0)
94 : #ifndef FRONTEND
95 0 : elog(ERROR, _("byte ordering mismatch"));
96 : #else
97 0 : printf(_("WARNING: possible byte ordering mismatch\n"
98 : "The byte ordering used to store the pg_control file might not match the one\n"
99 : "used by this program. In that case the results below would be incorrect, and\n"
100 : "the PostgreSQL installation would be incompatible with this data directory.\n"));
101 : #endif
102 :
103 0 : return ControlFile;
104 : }
|