1- /* pg_controldata
1+ /*
2+ * pg_controldata
23 *
34 * reads the data from $PGDATA/global/pg_control
45 *
56 * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
67 * licence: BSD
78 *
8- */
9+ * $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/pg_controldata.c,v 1.2 2001/03/13 01:17:40 tgl Exp $
10+ */
11+ #include "postgres.h"
912
10- #include <stdio.h>
11- #include <stdlib.h>
1213#include <unistd.h>
1314#include <time.h>
1415#include <sys/types.h>
1516#include <sys/stat.h>
1617#include <fcntl.h>
1718
19+ #include "catalog/pg_control.h"
1820
19- typedef unsigned int uint32 ;
20-
21- #include "config.h"
22- #include "access/xlogdefs.h"
23-
24- /*
25- * #include "access/xlog.h"
26- * #include "c.h"
27- */
28-
29- /* The following definitions are extracted from access/xlog.h and its
30- * recursive includes. There is too much initialisation needed if
31- * they are included direct. Perhaps someone more knowledgeable can
32- * fix that.
33- */
34- typedef struct crc64
35- {
36- uint32 crc1 ;
37- uint32 crc2 ;
38- } crc64 ;
39-
40- #define LOCALE_NAME_BUFLEN 128
4121
42- typedef enum DBState
22+ static const char *
23+ dbState (DBState state )
4324{
44- DB_STARTUP = 0 ,
45- DB_SHUTDOWNED ,
46- DB_SHUTDOWNING ,
47- DB_IN_RECOVERY ,
48- DB_IN_PRODUCTION
49- } DBState ;
25+ switch (state )
26+ {
27+ case DB_STARTUP :
28+ return "STARTUP" ;
29+ case DB_SHUTDOWNED :
30+ return "SHUTDOWNED" ;
31+ case DB_SHUTDOWNING :
32+ return "SHUTDOWNING" ;
33+ case DB_IN_RECOVERY :
34+ return "IN_RECOVERY" ;
35+ case DB_IN_PRODUCTION :
36+ return "IN_PRODUCTION" ;
37+ }
38+ return "unrecognized status code" ;
39+ }
5040
5141
52- typedef struct ControlFileData
42+ int
43+ main ()
5344{
54- crc64 crc ;
55- uint32 logId ; /* current log file id */
56- uint32 logSeg ; /* current log file segment (1-based) */
57- struct
58- XLogRecPtr checkPoint ; /* last check point record ptr */
59- time_t time ; /* time stamp of last modification */
60- DBState state ; /* see enum above */
61-
62- /*
63- * this data is used to make sure that configuration of this DB is
64- * compatible with the backend executable
65- */
66- uint32 blcksz ; /* block size for this DB */
67- uint32 relseg_size ; /* blocks per segment of large relation */
68- uint32 catalog_version_no ; /* internal version number */
69- /* active locales --- "C" if compiled without USE_LOCALE: */
70- char lc_collate [LOCALE_NAME_BUFLEN ];
71- char lc_ctype [LOCALE_NAME_BUFLEN ];
72-
73- /*
74- * important directory locations
75- */
76- char archdir [MAXPGPATH ]; /* where to move offline log files */
77- } ControlFileData ;
78-
79- int main () {
8045 ControlFileData ControlFile ;
8146 int fd ;
8247 char ControlFilePath [MAXPGPATH ];
8348 char * DataDir ;
84- char tmdt [32 ];
49+ crc64 crc ;
50+ char pgctime_str [32 ];
51+ char ckpttime_str [32 ];
8552
8653 DataDir = getenv ("PGDATA" );
8754 if ( DataDir == NULL ) {
@@ -91,33 +58,77 @@ int main() {
9158
9259 snprintf (ControlFilePath , MAXPGPATH , "%s/global/pg_control" , DataDir );
9360
94- if ((fd = open (ControlFilePath , O_RDONLY )) == -1 ) {
61+ if ((fd = open (ControlFilePath , O_RDONLY )) == -1 )
62+ {
9563 perror ("Failed to open $PGDATA/global/pg_control for reading" );
9664 exit (2 );
9765 }
9866
99- read (fd , & ControlFile , sizeof (ControlFileData ));
100- strftime (tmdt , 32 , "%c" , localtime (& (ControlFile .time )));
101-
102- printf ("Log file id: %u\n"
103- "Log file segment: %u\n"
104- "Last modified: %s\n"
105- "Database block size: %u\n"
106- "Blocks per segment of large relation: %u\n"
107- "Catalog version number: %u\n"
108- "LC_COLLATE: %s\n"
109- "LC_CTYPE: %s\n"
110- "Log archive directory: %s\n" ,
111- ControlFile .logId ,
112- ControlFile .logSeg ,
113- tmdt ,
114- ControlFile .blcksz ,
115- ControlFile .relseg_size ,
116- ControlFile .catalog_version_no ,
117- ControlFile .lc_collate ,
118- ControlFile .lc_ctype ,
119- ControlFile .archdir );
120-
67+ if (read (fd , & ControlFile , sizeof (ControlFileData )) != sizeof (ControlFileData ))
68+ {
69+ perror ("Failed to read $PGDATA/global/pg_control" );
70+ exit (2 );
71+ }
72+ close (fd );
73+
74+ /* Check the CRC. */
75+ INIT_CRC64 (crc );
76+ COMP_CRC64 (crc ,
77+ (char * ) & ControlFile + sizeof (crc64 ),
78+ sizeof (ControlFileData ) - sizeof (crc64 ));
79+ FIN_CRC64 (crc );
80+
81+ if (!EQ_CRC64 (crc , ControlFile .crc ))
82+ printf ("WARNING: Calculated CRC checksum does not match value stored in file.\n"
83+ "Either the file is corrupt, or it has a different layout than this program\n"
84+ "is expecting. The results below are untrustworthy.\n\n" );
85+
86+ strftime (pgctime_str , 32 , "%c" ,
87+ localtime (& (ControlFile .time )));
88+ strftime (ckpttime_str , 32 , "%c" ,
89+ localtime (& (ControlFile .checkPointCopy .time )));
90+
91+ printf ("pg_control version number: %u\n"
92+ "Catalog version number: %u\n"
93+ "Database state: %s\n"
94+ "pg_control last modified: %s\n"
95+ "Current log file id: %u\n"
96+ "Next log file segment: %u\n"
97+ "Latest checkpoint location: %X/%X\n"
98+ "Prior checkpoint location: %X/%X\n"
99+ "Latest checkpoint's REDO location: %X/%X\n"
100+ "Latest checkpoint's UNDO location: %X/%X\n"
101+ "Latest checkpoint's StartUpID: %u\n"
102+ "Latest checkpoint's NextXID: %u\n"
103+ "Latest checkpoint's NextOID: %u\n"
104+ "Time of latest checkpoint: %s\n"
105+ "Database block size: %u\n"
106+ "Blocks per segment of large relation: %u\n"
107+ "LC_COLLATE: %s\n"
108+ "LC_CTYPE: %s\n" ,
109+
110+ ControlFile .pg_control_version ,
111+ ControlFile .catalog_version_no ,
112+ dbState (ControlFile .state ),
113+ pgctime_str ,
114+ ControlFile .logId ,
115+ ControlFile .logSeg ,
116+ ControlFile .checkPoint .xlogid ,
117+ ControlFile .checkPoint .xrecoff ,
118+ ControlFile .prevCheckPoint .xlogid ,
119+ ControlFile .prevCheckPoint .xrecoff ,
120+ ControlFile .checkPointCopy .redo .xlogid ,
121+ ControlFile .checkPointCopy .redo .xrecoff ,
122+ ControlFile .checkPointCopy .undo .xlogid ,
123+ ControlFile .checkPointCopy .undo .xrecoff ,
124+ ControlFile .checkPointCopy .ThisStartUpID ,
125+ ControlFile .checkPointCopy .nextXid ,
126+ ControlFile .checkPointCopy .nextOid ,
127+ ckpttime_str ,
128+ ControlFile .blcksz ,
129+ ControlFile .relseg_size ,
130+ ControlFile .lc_collate ,
131+ ControlFile .lc_ctype );
132+
121133 return (0 );
122134}
123-
0 commit comments