2
Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; version 2 of the License.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
#include <ndb_global.h>
20
#include <util/version.h>
21
#include <my_global.h>
27
#include "SchemaFile.hpp"
28
#include <kernel_types.h>
30
static const char* progname = 0;
31
static bool allflag = false;
32
static bool checkonly = false;
33
static bool equalcontents = false;
34
static bool okquiet = false;
35
static bool transok = false;
41
<< "Usage: " << progname << " [-aceq]" << " file ..." << endl
42
<< "-a print also unused slots" << endl
43
<< "-c check only (return status 1 on error)" << endl
44
<< "-e check also that the files have identical contents" << endl
45
<< "-q no output if file is ok" << endl
46
<< "-t non-zero trans key is not error (has active trans)" << endl
47
<< "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl;
53
fill(const char * buf, int mod)
55
int len = strlen(buf)+1;
57
while((len % mod) != 0){
68
sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF);
73
print_head(const char * filename, const SchemaFile * sf)
78
ndbout << "----- Schemafile: " << filename << " -----" << endl;
79
ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d",
80
(int) sizeof(sf->Magic),
83
version(sf->NdbVersion),
87
if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) {
88
ndbout << filename << ": invalid header magic" << endl;
92
if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) {
93
ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl;
102
table_version_minor(Uint32 ver)
108
print_old(const char * filename, const SchemaFile * sf, Uint32 sz)
112
if (print_head(filename, sf) != 0)
115
for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) {
116
SchemaFile::TableEntry_old te = sf->TableEntries_old[i];
118
(te.m_tableState != SchemaFile::SF_UNUSED))
121
ndbout << "Table " << i << ":"
122
<< " State = " << te.m_tableState
123
<< " version = " << table_version_major(te.m_tableVersion)
124
<< "(" << table_version_minor(te.m_tableVersion) << ")"
125
<< " type = " << te.m_tableType
126
<< " noOfPages = " << te.m_noOfPages
127
<< " gcp: " << te.m_gcp << endl;
134
print(const char * filename, const SchemaFile * xsf, Uint32 sz)
138
if (print_head(filename, xsf) != 0)
141
assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE);
142
if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) {
143
ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl;
146
Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE;
147
for (Uint32 n = 0; n < noOfPages; n++) {
149
ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl;
151
const SchemaFile * sf = &xsf[n];
152
if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) {
153
ndbout << filename << ": page " << n << " invalid magic" << endl;
156
if (sf->FileSize != xsf->FileSize) {
157
ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
161
for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++)
162
cs ^= ((const Uint32*)sf)[j];
164
ndbout << filename << ": page " << n << " invalid CheckSum" << endl;
167
if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) {
168
ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
171
for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
172
SchemaFile::TableEntry te = sf->TableEntries[i];
173
Uint32 j = n * NDB_SF_PAGE_ENTRIES + i;
174
bool entryerr = false;
175
if (! transok && te.m_transId != 0) {
176
ndbout << filename << ": entry " << j << ": active transaction, transId: " << hex << te.m_transId << endl;
180
const Uint32 num_unused = sizeof(te.m_unused) / sizeof(te.m_unused[0]);
181
for (Uint32 k = 0; k < num_unused; k++) {
182
if (te.m_unused[k] != 0) {
183
ndbout << filename << ": entry " << j << ": garbage in unused word " << k << ": " << te.m_unused[k] << endl;
189
(te.m_tableState != SchemaFile::SF_UNUSED) ||
191
if (! checkonly || entryerr)
192
ndbout << "Table " << j << ":"
193
<< " State = " << te.m_tableState
194
<< " version = " << table_version_major(te.m_tableVersion)
195
<< "(" << table_version_minor(te.m_tableVersion) << ")"
196
<< " type = " << te.m_tableType
197
<< " noOfWords = " << te.m_info_words
198
<< " gcp: " << te.m_gcp
199
<< " transId: " << hex << te.m_transId << endl;
207
NDB_COMMAND(printSchemafile,
208
"printSchemafile", "printSchemafile", "Prints a schemafile", 16384)
214
while (argc > 1 && argv[1][0] == '-') {
215
if (strchr(argv[1], 'a') != 0)
217
if (strchr(argv[1], 'c') != 0)
219
if (strchr(argv[1], 'e') != 0)
220
equalcontents = true;
221
if (strchr(argv[1], 'q') != 0)
223
if (strchr(argv[1], 't') != 0)
225
if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) {
232
const char * prevfilename = 0;
233
Uint32 * prevbuf = 0;
234
Uint32 prevbytes = 0;
237
const char * filename = argv[1];
241
if(!(st=my_stat(filename, &sbuf,0)))
243
ndbout << filename << ": not found my_errno=" << my_errno << endl;
247
const Uint32 bytes = sbuf.st_size;
249
Uint32 * buf = new Uint32[bytes/4+1];
251
FILE * f = fopen(filename, "rb");
253
ndbout << filename << ": open failed errno=" << errno << endl;
258
Uint32 sz = (Uint32)fread(buf, 1, bytes, f);
261
ndbout << filename << ": read failed errno=" << errno << endl;
268
ndbout << filename << ": too short (no header)" << endl;
274
SchemaFile* sf = (SchemaFile *)&buf[0];
276
if (sf->NdbVersion < NDB_SF_VERSION_5_0_6)
277
ret = print_old(filename, sf, sz);
279
ret = print(filename, sf, sz);
282
ndbout << filename << ": check failed"
283
<< " version=" << version(sf->NdbVersion) << endl;
285
} else if (! okquiet) {
286
ndbout << filename << ": ok"
287
<< " version=" << version(sf->NdbVersion) << endl;
290
if (equalcontents && prevfilename != 0) {
291
if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) {
292
ndbout << filename << ": differs from " << prevfilename << endl;
297
prevfilename = filename;