mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / src / kernel / blocks / backup / read.cpp
blobdb32c82192410265708a710e36dabd84c4a07875
1 /* Copyright (c) 2003-2005 MySQL AB, 2009 Sun Microsystems, Inc.
2 Use is subject to license terms.
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 */
18 #include <ndb_global.h>
20 #include <NdbTCP.h>
21 #include <NdbOut.hpp>
22 #include "BackupFormat.hpp"
23 #include <AttributeHeader.hpp>
24 #include <SimpleProperties.hpp>
25 #include <ndb_version.h>
27 bool readHeader(FILE*, BackupFormat::FileHeader *);
28 bool readFragHeader(FILE*, BackupFormat::DataFile::FragmentHeader *);
29 bool readFragFooter(FILE*, BackupFormat::DataFile::FragmentFooter *);
30 Int32 readRecord(FILE*, Uint32 **);
32 NdbOut & operator<<(NdbOut&, const BackupFormat::FileHeader &);
33 NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentHeader &);
34 NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentFooter &);
36 bool readTableList(FILE*, BackupFormat::CtlFile::TableList **);
37 bool readTableDesc(FILE*, BackupFormat::CtlFile::TableDescription **);
38 bool readGCPEntry(FILE*, BackupFormat::CtlFile::GCPEntry **);
40 NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableList &);
41 NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableDescription &);
42 NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::GCPEntry &);
44 Int32 readLogEntry(FILE*, Uint32**);
46 static Uint32 recNo;
47 static Uint32 logEntryNo;
49 int
50 main(int argc, const char * argv[]){
52 ndb_init();
53 if(argc <= 1){
54 printf("Usage: %s <filename>\n", argv[0]);
55 exit(1);
57 FILE * f = fopen(argv[1], "rb");
58 if(!f){
59 ndbout << "No such file!" << endl;
60 exit(1);
63 BackupFormat::FileHeader fileHeader;
64 if(!readHeader(f, &fileHeader)){
65 ndbout << "Invalid file!" << endl;
66 exit(1);
68 ndbout << fileHeader << endl;
70 switch(fileHeader.FileType){
71 case BackupFormat::DATA_FILE:
72 while(!feof(f)){
73 BackupFormat::DataFile::FragmentHeader fragHeader;
74 if(!readFragHeader(f, &fragHeader))
75 break;
76 ndbout << fragHeader << endl;
78 Uint32 len, * data;
79 while((len = readRecord(f, &data)) > 0){
80 #if 0
81 ndbout << "-> " << hex;
82 for(Uint32 i = 0; i<len; i++){
83 ndbout << data[i] << " ";
85 ndbout << endl;
86 #endif
89 BackupFormat::DataFile::FragmentFooter fragFooter;
90 if(!readFragFooter(f, &fragFooter))
91 break;
92 ndbout << fragFooter << endl;
94 break;
95 case BackupFormat::CTL_FILE:{
96 BackupFormat::CtlFile::TableList * tabList;
97 if(!readTableList(f, &tabList)){
98 ndbout << "Invalid file! No table list" << endl;
99 break;
101 ndbout << (* tabList) << endl;
103 const Uint32 noOfTables = tabList->SectionLength - 2;
104 for(Uint32 i = 0; i<noOfTables; i++){
105 BackupFormat::CtlFile::TableDescription * tabDesc;
106 if(!readTableDesc(f, &tabDesc)){
107 ndbout << "Invalid file missing table description" << endl;
108 break;
110 ndbout << (* tabDesc) << endl;
113 BackupFormat::CtlFile::GCPEntry * gcpE;
114 if(!readGCPEntry(f, &gcpE)){
115 ndbout << "Invalid file! GCP ENtry" << endl;
116 break;
118 ndbout << (* gcpE) << endl;
120 break;
122 case BackupFormat::LOG_FILE:{
123 logEntryNo = 0;
125 typedef BackupFormat::LogFile::LogEntry LogEntry;
127 Uint32 len, * data;
128 while((len = readLogEntry(f, &data)) > 0){
129 LogEntry * logEntry = (LogEntry *) data;
131 * Log Entry
133 Uint32 event = ntohl(logEntry->TriggerEvent);
134 bool gcp = (event & 0x10000) != 0;
135 event &= 0xFFFF;
136 if(gcp)
137 len --;
139 ndbout << "LogEntry Table: " << (Uint32)ntohl(logEntry->TableId)
140 << " Event: " << event
141 << " Length: " << (len - 2);
143 const Uint32 dataLen = len - 2;
144 #if 0
145 Uint32 pos = 0;
146 while(pos < dataLen){
147 AttributeHeader * ah = (AttributeHeader*)&logEntry->Data[pos];
148 ndbout_c(" Attribut: %d Size: %d",
149 ah->getAttributeId(),
150 ah->getDataSize());
151 pos += ah->getDataSize() + 1;
153 #endif
154 if(gcp)
155 ndbout << " GCP: " << (Uint32)ntohl(logEntry->Data[dataLen]);
156 ndbout << endl;
158 break;
160 case BackupFormat::LCP_FILE:
162 BackupFormat::CtlFile::TableList * tabList;
163 if(!readTableList(f, &tabList)){
164 ndbout << "Invalid file! No table list" << endl;
165 break;
167 ndbout << (* tabList) << endl;
169 const Uint32 noOfTables = tabList->SectionLength - 2;
170 for(Uint32 i = 0; i<noOfTables; i++){
171 BackupFormat::CtlFile::TableDescription * tabDesc;
172 if(!readTableDesc(f, &tabDesc)){
173 ndbout << "Invalid file missing table description" << endl;
174 break;
176 ndbout << (* tabDesc) << endl;
179 while(!feof(f)){
180 BackupFormat::DataFile::FragmentHeader fragHeader;
181 if(!readFragHeader(f, &fragHeader))
182 break;
183 ndbout << fragHeader << endl;
185 Uint32 len, * data;
186 while((len = readRecord(f, &data)) > 0){
187 #if 0
188 ndbout << "-> " << hex;
189 for(Uint32 i = 0; i<len; i++){
190 ndbout << data[i] << " ";
192 ndbout << endl;
193 #endif
196 BackupFormat::DataFile::FragmentFooter fragFooter;
197 if(!readFragFooter(f, &fragFooter))
198 break;
199 ndbout << fragFooter << endl;
201 break;
203 default:
204 ndbout << "Unsupported file type for printer: "
205 << fileHeader.FileType << endl;
206 break;
208 fclose(f);
209 return 0;
212 #define RETURN_FALSE() { ndbout_c("false: %d", __LINE__); abort(); return false; }
214 static bool endian = false;
216 bool
217 readHeader(FILE* f, BackupFormat::FileHeader * dst){
218 if(fread(dst, 4, 3, f) != 3)
219 RETURN_FALSE();
221 if(memcmp(dst->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC)) != 0)
222 RETURN_FALSE();
224 dst->NdbVersion = ntohl(dst->NdbVersion);
225 if(dst->NdbVersion != NDB_VERSION)
226 RETURN_FALSE();
228 if(fread(&dst->SectionType, 4, 2, f) != 2)
229 RETURN_FALSE();
230 dst->SectionType = ntohl(dst->SectionType);
231 dst->SectionLength = ntohl(dst->SectionLength);
233 if(dst->SectionType != BackupFormat::FILE_HEADER)
234 RETURN_FALSE();
236 if(dst->SectionLength != ((sizeof(BackupFormat::FileHeader) - 12) >> 2))
237 RETURN_FALSE();
239 if(fread(&dst->FileType, 4, dst->SectionLength - 2, f) !=
240 (dst->SectionLength - 2))
241 RETURN_FALSE();
243 dst->FileType = ntohl(dst->FileType);
244 dst->BackupId = ntohl(dst->BackupId);
245 dst->BackupKey_0 = ntohl(dst->BackupKey_0);
246 dst->BackupKey_1 = ntohl(dst->BackupKey_1);
248 if(dst->ByteOrder != 0x12345678)
249 endian = true;
251 return true;
254 bool
255 readFragHeader(FILE* f, BackupFormat::DataFile::FragmentHeader * dst){
256 if(fread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
257 return false;
259 dst->SectionType = ntohl(dst->SectionType);
260 dst->SectionLength = ntohl(dst->SectionLength);
261 dst->TableId = ntohl(dst->TableId);
262 dst->FragmentNo = ntohl(dst->FragmentNo);
263 dst->ChecksumType = ntohl(dst->ChecksumType);
265 if(dst->SectionLength != (sizeof(* dst) >> 2))
266 RETURN_FALSE();
268 if(dst->SectionType != BackupFormat::FRAGMENT_HEADER)
269 RETURN_FALSE();
271 recNo = 0;
273 return true;
276 bool
277 readFragFooter(FILE* f, BackupFormat::DataFile::FragmentFooter * dst){
278 if(fread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
279 RETURN_FALSE();
281 dst->SectionType = ntohl(dst->SectionType);
282 dst->SectionLength = ntohl(dst->SectionLength);
283 dst->TableId = ntohl(dst->TableId);
284 dst->FragmentNo = ntohl(dst->FragmentNo);
285 dst->NoOfRecords = ntohl(dst->NoOfRecords);
286 dst->Checksum = ntohl(dst->Checksum);
288 if(dst->SectionLength != (sizeof(* dst) >> 2))
289 RETURN_FALSE();
291 if(dst->SectionType != BackupFormat::FRAGMENT_FOOTER)
292 RETURN_FALSE();
293 return true;
296 static Uint32 buf[8192];
298 Int32
299 readRecord(FILE* f, Uint32 **dst){
300 Uint32 len;
301 if(fread(&len, 1, 4, f) != 4)
302 RETURN_FALSE();
304 len = ntohl(len);
306 if(fread(buf, 4, len, f) != len)
308 return -1;
311 if(len > 0)
312 recNo++;
313 else
314 ndbout_c("Found %d records", recNo);
316 * dst = &buf[0];
319 return len;
322 Int32
323 readLogEntry(FILE* f, Uint32 **dst){
324 Uint32 len;
325 if(fread(&len, 1, 4, f) != 4)
326 RETURN_FALSE();
328 len = ntohl(len);
330 if(fread(&buf[1], 4, len, f) != len)
331 return -1;
333 buf[0] = len;
335 if(len > 0)
336 logEntryNo++;
338 * dst = &buf[0];
340 return len;
344 NdbOut &
345 operator<<(NdbOut& ndbout, const BackupFormat::FileHeader & hf){
347 char buf[9];
348 memcpy(buf, hf.Magic, sizeof(hf.Magic));
349 buf[8] = 0;
351 ndbout << "-- FileHeader:" << endl;
352 ndbout << "Magic: " << buf << endl;
353 ndbout << "NdbVersion: " << hf.NdbVersion << endl;
354 ndbout << "SectionType: " << hf.SectionType << endl;
355 ndbout << "SectionLength: " << hf.SectionLength << endl;
356 ndbout << "FileType: " << hf.FileType << endl;
357 ndbout << "BackupId: " << hf.BackupId << endl;
358 ndbout << "BackupKey: [ " << hex << hf.BackupKey_0
359 << " "<< hf.BackupKey_1 << " ]" << endl;
360 ndbout << "ByteOrder: " << hex << hf.ByteOrder << endl;
361 return ndbout;
364 NdbOut & operator<<(NdbOut& ndbout,
365 const BackupFormat::DataFile::FragmentHeader & hf){
367 ndbout << "-- Fragment header:" << endl;
368 ndbout << "SectionType: " << hf.SectionType << endl;
369 ndbout << "SectionLength: " << hf.SectionLength << endl;
370 ndbout << "TableId: " << hf.TableId << endl;
371 ndbout << "FragmentNo: " << hf.FragmentNo << endl;
372 ndbout << "ChecksumType: " << hf.ChecksumType << endl;
374 return ndbout;
376 NdbOut & operator<<(NdbOut& ndbout,
377 const BackupFormat::DataFile::FragmentFooter & hf){
379 ndbout << "-- Fragment footer:" << endl;
380 ndbout << "SectionType: " << hf.SectionType << endl;
381 ndbout << "SectionLength: " << hf.SectionLength << endl;
382 ndbout << "TableId: " << hf.TableId << endl;
383 ndbout << "FragmentNo: " << hf.FragmentNo << endl;
384 ndbout << "NoOfRecords: " << hf.NoOfRecords << endl;
385 ndbout << "Checksum: " << hf.Checksum << endl;
387 return ndbout;
390 bool
391 readTableList(FILE* f, BackupFormat::CtlFile::TableList **ret){
392 BackupFormat::CtlFile::TableList * dst =
393 (BackupFormat::CtlFile::TableList *)&buf[0];
395 if(fread(dst, 4, 2, f) != 2)
396 RETURN_FALSE();
398 dst->SectionType = ntohl(dst->SectionType);
399 dst->SectionLength = ntohl(dst->SectionLength);
401 if(dst->SectionType != BackupFormat::TABLE_LIST)
402 RETURN_FALSE();
404 const Uint32 len = dst->SectionLength - 2;
405 if(fread(&dst->TableIds[0], 4, len, f) != len)
406 RETURN_FALSE();
408 for(Uint32 i = 0; i<len; i++){
409 dst->TableIds[i] = ntohl(dst->TableIds[i]);
412 * ret = dst;
414 return true;
417 bool
418 readTableDesc(FILE* f, BackupFormat::CtlFile::TableDescription **ret){
419 BackupFormat::CtlFile::TableDescription * dst =
420 (BackupFormat::CtlFile::TableDescription *)&buf[0];
422 if(fread(dst, 4, 2, f) != 2)
423 RETURN_FALSE();
425 dst->SectionType = ntohl(dst->SectionType);
426 dst->SectionLength = ntohl(dst->SectionLength);
428 if(dst->SectionType != BackupFormat::TABLE_DESCRIPTION)
429 RETURN_FALSE();
431 const Uint32 len = dst->SectionLength - 2;
432 if(fread(&dst->DictTabInfo[0], 4, len, f) != len)
433 RETURN_FALSE();
435 * ret = dst;
437 return true;
440 bool
441 readGCPEntry(FILE* f, BackupFormat::CtlFile::GCPEntry **ret){
442 BackupFormat::CtlFile::GCPEntry * dst =
443 (BackupFormat::CtlFile::GCPEntry *)&buf[0];
445 if(fread(dst, 4, 4, f) != 4)
446 RETURN_FALSE();
448 dst->SectionType = ntohl(dst->SectionType);
449 dst->SectionLength = ntohl(dst->SectionLength);
451 if(dst->SectionType != BackupFormat::GCP_ENTRY)
452 RETURN_FALSE();
454 dst->StartGCP = ntohl(dst->StartGCP);
455 dst->StopGCP = ntohl(dst->StopGCP);
457 * ret = dst;
459 return true;
463 NdbOut &
464 operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableList & hf) {
465 ndbout << "-- Table List:" << endl;
466 ndbout << "SectionType: " << hf.SectionType << endl;
467 ndbout << "SectionLength: " << hf.SectionLength << endl;
468 for(Uint32 i = 0; i < hf.SectionLength - 2; i++){
469 ndbout << hf.TableIds[i] << " ";
470 if((i + 1) % 16 == 0)
471 ndbout << endl;
473 return ndbout;
476 NdbOut &
477 operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableDescription & hf){
478 ndbout << "-- Table Description:" << endl;
479 ndbout << "SectionType: " << hf.SectionType << endl;
480 ndbout << "SectionLength: " << hf.SectionLength << endl;
482 SimplePropertiesLinearReader it(&hf.DictTabInfo[0], hf.SectionLength - 2);
483 char buf[1024];
484 for(it.first(); it.valid(); it.next()){
485 switch(it.getValueType()){
486 case SimpleProperties::Uint32Value:
487 ndbout << "Key: " << it.getKey()
488 << " value(" << it.getValueLen() << ") : "
489 << it.getUint32() << endl;
490 break;
491 case SimpleProperties::StringValue:
492 if(it.getValueLen() < sizeof(buf)){
493 it.getString(buf);
494 ndbout << "Key: " << it.getKey()
495 << " value(" << it.getValueLen() << ") : "
496 << "\"" << buf << "\"" << endl;
497 } else {
498 ndbout << "Key: " << it.getKey()
499 << " value(" << it.getValueLen() << ") : "
500 << "\"" << "<TOO LONG>" << "\"" << endl;
503 break;
504 default:
505 ndbout << "Unknown type for key: " << it.getKey()
506 << " type: " << it.getValueType() << endl;
510 return ndbout;
513 NdbOut &
514 operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::GCPEntry & hf) {
515 ndbout << "-- GCP Entry:" << endl;
516 ndbout << "SectionType: " << hf.SectionType << endl;
517 ndbout << "SectionLength: " << hf.SectionLength << endl;
518 ndbout << "Start GCP: " << hf.StartGCP << endl;
519 ndbout << "Stop GCP: " << hf.StopGCP << endl;
521 return ndbout;