]> granicus.if.org Git - postgresql/blob - src/common/controldata_utils.c
f218d2558c196ca79ee7854c96975a554b650fd6
[postgresql] / src / common / controldata_utils.c
1 /*-------------------------------------------------------------------------
2  *
3  * controldata_utils.c
4  *              Common code for control data file output.
5  *
6  *
7  * Portions Copyright (c) 1996-2016, 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)
33  *
34  * Get controlfile values. The caller is responsible
35  * for pfreeing the result.
36  *
37  * Returns NULL if the CRC did not match.
38  */
39 ControlFileData *
40 get_controlfile(const char *DataDir, const char *progname)
41 {
42         ControlFileData *ControlFile;
43         int                     fd;
44         char            ControlFilePath[MAXPGPATH];
45         pg_crc32c       crc;
46
47         ControlFile = palloc(sizeof(ControlFileData));
48         snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
49
50         if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
51 #ifndef FRONTEND
52                 ereport(ERROR,
53                                 (errcode_for_file_access(),
54                                  errmsg("could not open file \"%s\" for reading: %m",
55                                                 ControlFilePath)));
56 #else
57         {
58                 fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
59                                 progname, ControlFilePath, strerror(errno));
60                 exit(EXIT_FAILURE);
61         }
62 #endif
63
64         if (read(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
65 #ifndef FRONTEND
66                 ereport(ERROR,
67                                 (errcode_for_file_access(),
68                                  errmsg("could not read file \"%s\": %m", ControlFilePath)));
69 #else
70         {
71                 fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
72                                 progname, ControlFilePath, strerror(errno));
73                 exit(EXIT_FAILURE);
74         }
75 #endif
76
77         close(fd);
78
79         /* Check the CRC. */
80         INIT_CRC32C(crc);
81         COMP_CRC32C(crc,
82                                 (char *) ControlFile,
83                                 offsetof(ControlFileData, crc));
84         FIN_CRC32C(crc);
85
86         if (!EQ_CRC32C(crc, ControlFile->crc))
87         {
88                 pfree(ControlFile);
89                 return NULL;
90         }
91
92         /* Make sure the control file is valid byte order. */
93         if (ControlFile->pg_control_version % 65536 == 0 &&
94                 ControlFile->pg_control_version / 65536 != 0)
95 #ifndef FRONTEND
96                 elog(ERROR, _("byte ordering mismatch"));
97 #else
98                 printf(_("WARNING: possible byte ordering mismatch\n"
99                                  "The byte ordering used to store the pg_control file might not match the one\n"
100                                  "used by this program.  In that case the results below would be incorrect, and\n"
101                                  "the PostgreSQL installation would be incompatible with this data directory.\n"));
102 #endif
103
104         return ControlFile;
105 }