~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/bin/pg_controldata/pg_controldata.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * pg_controldata
 
3
 *
 
4
 * reads the data from $PGDATA/global/pg_control
 
5
 *
 
6
 * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
 
7
 * licence: BSD
 
8
 *
 
9
 * $PostgreSQL$
 
10
 */
 
11
#include "postgres_fe.h"
 
12
 
 
13
#include <unistd.h>
 
14
#include <time.h>
 
15
#include <sys/stat.h>
 
16
#include <fcntl.h>
 
17
 
 
18
#include "catalog/pg_control.h"
 
19
 
 
20
 
 
21
static void
 
22
usage(const char *progname)
 
23
{
 
24
        printf(_("%s displays control information of a PostgreSQL database cluster.\n\n"), progname);
 
25
        printf
 
26
                (
 
27
                 _(
 
28
                   "Usage:\n"
 
29
                   "  %s [OPTION] [DATADIR]\n\n"
 
30
                   "Options:\n"
 
31
                   "  --help         show this help, then exit\n"
 
32
                   "  --version      output version information, then exit\n"
 
33
                   ),
 
34
                 progname
 
35
                );
 
36
        printf(_("\nIf no data directory (DATADIR) is specified, "
 
37
                         "the environment variable PGDATA\nis used.\n\n"));
 
38
        printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
 
39
}
 
40
 
 
41
 
 
42
static const char *
 
43
dbState(DBState state)
 
44
{
 
45
        switch (state)
 
46
        {
 
47
                case DB_STARTUP:
 
48
                        return _("starting up");
 
49
                case DB_SHUTDOWNED:
 
50
                        return _("shut down");
 
51
                case DB_SHUTDOWNING:
 
52
                        return _("shutting down");
 
53
                case DB_IN_CRASH_RECOVERY:
 
54
                        return _("in crash recovery");
 
55
                case DB_IN_ARCHIVE_RECOVERY:
 
56
                        return _("in archive recovery");
 
57
                case DB_IN_PRODUCTION:
 
58
                        return _("in production");
 
59
        }
 
60
        return _("unrecognized status code");
 
61
}
 
62
 
 
63
 
 
64
int
 
65
main(int argc, char *argv[])
 
66
{
 
67
        ControlFileData ControlFile;
 
68
        int                     fd;
 
69
        char            ControlFilePath[MAXPGPATH];
 
70
        char       *DataDir;
 
71
        pg_crc32        crc;
 
72
        time_t          time_tmp;
 
73
        char            pgctime_str[128];
 
74
        char            ckpttime_str[128];
 
75
        char            sysident_str[32];
 
76
        const char *strftime_fmt = "%c";
 
77
        const char *progname;
 
78
 
 
79
        set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata"));
 
80
 
 
81
        progname = get_progname(argv[0]);
 
82
 
 
83
        if (argc > 1)
 
84
        {
 
85
                if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
 
86
                {
 
87
                        usage(progname);
 
88
                        exit(0);
 
89
                }
 
90
                if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
 
91
                {
 
92
                        puts("pg_controldata (PostgreSQL) " PG_VERSION);
 
93
                        exit(0);
 
94
                }
 
95
        }
 
96
 
 
97
        if (argc > 1)
 
98
                DataDir = argv[1];
 
99
        else
 
100
                DataDir = getenv("PGDATA");
 
101
        if (DataDir == NULL)
 
102
        {
 
103
                fprintf(stderr, _("%s: no data directory specified\n"), progname);
 
104
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 
105
                exit(1);
 
106
        }
 
107
 
 
108
        snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
 
109
 
 
110
        if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
 
111
        {
 
112
                fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
 
113
                                progname, ControlFilePath, strerror(errno));
 
114
                exit(2);
 
115
        }
 
116
 
 
117
        if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
 
118
        {
 
119
                fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
 
120
                                progname, ControlFilePath, strerror(errno));
 
121
                exit(2);
 
122
        }
 
123
        close(fd);
 
124
 
 
125
        /* Check the CRC. */
 
126
        INIT_CRC32(crc);
 
127
        COMP_CRC32(crc,
 
128
                           (char *) &ControlFile,
 
129
                           offsetof(ControlFileData, crc));
 
130
        FIN_CRC32(crc);
 
131
 
 
132
        if (!EQ_CRC32(crc, ControlFile.crc))
 
133
                printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
 
134
                                 "Either the file is corrupt, or it has a different layout than this program\n"
 
135
                                 "is expecting.  The results below are untrustworthy.\n\n"));
 
136
 
 
137
        /*
 
138
         * This slightly-chintzy coding will work as long as the control file
 
139
         * timestamps are within the range of time_t; that should be the case
 
140
         * in all foreseeable circumstances, so we don't bother importing the
 
141
         * backend's timezone library into pg_controldata.
 
142
         *
 
143
         * Use variable for format to suppress overly-anal-retentive gcc warning
 
144
         * about %c
 
145
         */
 
146
        time_tmp = (time_t) ControlFile.time;
 
147
        strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
 
148
                         localtime(&time_tmp));
 
149
        time_tmp = (time_t) ControlFile.checkPointCopy.time;
 
150
        strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
 
151
                         localtime(&time_tmp));
 
152
 
 
153
        /*
 
154
         * Format system_identifier separately to keep platform-dependent format
 
155
         * code out of the translatable message string.
 
156
         */
 
157
        snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
 
158
                         ControlFile.system_identifier);
 
159
 
 
160
        printf(_("pg_control version number:            %u\n"),
 
161
                   ControlFile.pg_control_version);
 
162
        if (ControlFile.pg_control_version % 65536 == 0 && ControlFile.pg_control_version / 65536 != 0)
 
163
                printf(_("WARNING: possible byte ordering mismatch\n"
 
164
                                 "The byte ordering used to store the pg_control file might not match the one\n"
 
165
                                 "used by this program.  In that case the results below would be incorrect, and\n"
 
166
                                 "the PostgreSQL installation would be incompatible with this data directory.\n"));
 
167
        printf(_("Catalog version number:               %u\n"),
 
168
                   ControlFile.catalog_version_no);
 
169
        printf(_("Database system identifier:           %s\n"),
 
170
                   sysident_str);
 
171
        printf(_("Database cluster state:               %s\n"),
 
172
                   dbState(ControlFile.state));
 
173
        printf(_("pg_control last modified:             %s\n"),
 
174
                   pgctime_str);
 
175
        printf(_("Latest checkpoint location:           %X/%X\n"),
 
176
                   ControlFile.checkPoint.xlogid,
 
177
                   ControlFile.checkPoint.xrecoff);
 
178
        printf(_("Prior checkpoint location:            %X/%X\n"),
 
179
                   ControlFile.prevCheckPoint.xlogid,
 
180
                   ControlFile.prevCheckPoint.xrecoff);
 
181
        printf(_("Latest checkpoint's REDO location:    %X/%X\n"),
 
182
                   ControlFile.checkPointCopy.redo.xlogid,
 
183
                   ControlFile.checkPointCopy.redo.xrecoff);
 
184
        printf(_("Latest checkpoint's TimeLineID:       %u\n"),
 
185
                   ControlFile.checkPointCopy.ThisTimeLineID);
 
186
        printf(_("Latest checkpoint's NextXID:          %u/%u\n"),
 
187
                   ControlFile.checkPointCopy.nextXidEpoch,
 
188
                   ControlFile.checkPointCopy.nextXid);
 
189
        printf(_("Latest checkpoint's NextOID:          %u\n"),
 
190
                   ControlFile.checkPointCopy.nextOid);
 
191
        printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
 
192
                   ControlFile.checkPointCopy.nextMulti);
 
193
        printf(_("Latest checkpoint's NextMultiOffset:  %u\n"),
 
194
                   ControlFile.checkPointCopy.nextMultiOffset);
 
195
        printf(_("Time of latest checkpoint:            %s\n"),
 
196
                   ckpttime_str);
 
197
        printf(_("Minimum recovery ending location:     %X/%X\n"),
 
198
                   ControlFile.minRecoveryPoint.xlogid,
 
199
                   ControlFile.minRecoveryPoint.xrecoff);
 
200
        printf(_("Maximum data alignment:               %u\n"),
 
201
                   ControlFile.maxAlign);
 
202
        /* we don't print floatFormat since can't say much useful about it */
 
203
        printf(_("Database block size:                  %u\n"),
 
204
                   ControlFile.blcksz);
 
205
        printf(_("Blocks per segment of large relation: %u\n"),
 
206
                   ControlFile.relseg_size);
 
207
        printf(_("WAL block size:                       %u\n"),
 
208
                   ControlFile.xlog_blcksz);
 
209
        printf(_("Bytes per WAL segment:                %u\n"),
 
210
                   ControlFile.xlog_seg_size);
 
211
        printf(_("Maximum length of identifiers:        %u\n"),
 
212
                   ControlFile.nameDataLen);
 
213
        printf(_("Maximum columns in an index:          %u\n"),
 
214
                   ControlFile.indexMaxKeys);
 
215
        printf(_("Maximum size of a TOAST chunk:        %u\n"),
 
216
                   ControlFile.toast_max_chunk_size);
 
217
        printf(_("Date/time type storage:               %s\n"),
 
218
                   (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
 
219
        printf(_("Float4 argument passing:              %s\n"),
 
220
                   (ControlFile.float4ByVal ? _("by value") : _("by reference")));
 
221
        printf(_("Float8 argument passing:              %s\n"),
 
222
                   (ControlFile.float8ByVal ? _("by value") : _("by reference")));
 
223
        return 0;
 
224
}