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>
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
**);
47 static Uint32 logEntryNo
;
50 main(int argc
, const char * argv
[]){
54 printf("Usage: %s <filename>\n", argv
[0]);
57 FILE * f
= fopen(argv
[1], "rb");
59 ndbout
<< "No such file!" << endl
;
63 BackupFormat::FileHeader fileHeader
;
64 if(!readHeader(f
, &fileHeader
)){
65 ndbout
<< "Invalid file!" << endl
;
68 ndbout
<< fileHeader
<< endl
;
70 switch(fileHeader
.FileType
){
71 case BackupFormat::DATA_FILE
:
73 BackupFormat::DataFile::FragmentHeader fragHeader
;
74 if(!readFragHeader(f
, &fragHeader
))
76 ndbout
<< fragHeader
<< endl
;
79 while((len
= readRecord(f
, &data
)) > 0){
81 ndbout
<< "-> " << hex
;
82 for(Uint32 i
= 0; i
<len
; i
++){
83 ndbout
<< data
[i
] << " ";
89 BackupFormat::DataFile::FragmentFooter fragFooter
;
90 if(!readFragFooter(f
, &fragFooter
))
92 ndbout
<< fragFooter
<< endl
;
95 case BackupFormat::CTL_FILE
:{
96 BackupFormat::CtlFile::TableList
* tabList
;
97 if(!readTableList(f
, &tabList
)){
98 ndbout
<< "Invalid file! No table list" << endl
;
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
;
110 ndbout
<< (* tabDesc
) << endl
;
113 BackupFormat::CtlFile::GCPEntry
* gcpE
;
114 if(!readGCPEntry(f
, &gcpE
)){
115 ndbout
<< "Invalid file! GCP ENtry" << endl
;
118 ndbout
<< (* gcpE
) << endl
;
122 case BackupFormat::LOG_FILE
:{
125 typedef BackupFormat::LogFile::LogEntry LogEntry
;
128 while((len
= readLogEntry(f
, &data
)) > 0){
129 LogEntry
* logEntry
= (LogEntry
*) data
;
133 Uint32 event
= ntohl(logEntry
->TriggerEvent
);
134 bool gcp
= (event
& 0x10000) != 0;
139 ndbout
<< "LogEntry Table: " << (Uint32
)ntohl(logEntry
->TableId
)
140 << " Event: " << event
141 << " Length: " << (len
- 2);
143 const Uint32 dataLen
= len
- 2;
146 while(pos
< dataLen
){
147 AttributeHeader
* ah
= (AttributeHeader
*)&logEntry
->Data
[pos
];
148 ndbout_c(" Attribut: %d Size: %d",
149 ah
->getAttributeId(),
151 pos
+= ah
->getDataSize() + 1;
155 ndbout
<< " GCP: " << (Uint32
)ntohl(logEntry
->Data
[dataLen
]);
160 case BackupFormat::LCP_FILE
:
162 BackupFormat::CtlFile::TableList
* tabList
;
163 if(!readTableList(f
, &tabList
)){
164 ndbout
<< "Invalid file! No table list" << endl
;
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
;
176 ndbout
<< (* tabDesc
) << endl
;
180 BackupFormat::DataFile::FragmentHeader fragHeader
;
181 if(!readFragHeader(f
, &fragHeader
))
183 ndbout
<< fragHeader
<< endl
;
186 while((len
= readRecord(f
, &data
)) > 0){
188 ndbout
<< "-> " << hex
;
189 for(Uint32 i
= 0; i
<len
; i
++){
190 ndbout
<< data
[i
] << " ";
196 BackupFormat::DataFile::FragmentFooter fragFooter
;
197 if(!readFragFooter(f
, &fragFooter
))
199 ndbout
<< fragFooter
<< endl
;
204 ndbout
<< "Unsupported file type for printer: "
205 << fileHeader
.FileType
<< endl
;
212 #define RETURN_FALSE() { ndbout_c("false: %d", __LINE__); abort(); return false; }
214 static bool endian
= false;
217 readHeader(FILE* f
, BackupFormat::FileHeader
* dst
){
218 if(fread(dst
, 4, 3, f
) != 3)
221 if(memcmp(dst
->Magic
, BACKUP_MAGIC
, sizeof(BACKUP_MAGIC
)) != 0)
224 dst
->NdbVersion
= ntohl(dst
->NdbVersion
);
225 if(dst
->NdbVersion
!= NDB_VERSION
)
228 if(fread(&dst
->SectionType
, 4, 2, f
) != 2)
230 dst
->SectionType
= ntohl(dst
->SectionType
);
231 dst
->SectionLength
= ntohl(dst
->SectionLength
);
233 if(dst
->SectionType
!= BackupFormat::FILE_HEADER
)
236 if(dst
->SectionLength
!= ((sizeof(BackupFormat::FileHeader
) - 12) >> 2))
239 if(fread(&dst
->FileType
, 4, dst
->SectionLength
- 2, f
) !=
240 (dst
->SectionLength
- 2))
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)
255 readFragHeader(FILE* f
, BackupFormat::DataFile::FragmentHeader
* dst
){
256 if(fread(dst
, 1, sizeof(* dst
), f
) != sizeof(* dst
))
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))
268 if(dst
->SectionType
!= BackupFormat::FRAGMENT_HEADER
)
277 readFragFooter(FILE* f
, BackupFormat::DataFile::FragmentFooter
* dst
){
278 if(fread(dst
, 1, sizeof(* dst
), f
) != sizeof(* dst
))
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))
291 if(dst
->SectionType
!= BackupFormat::FRAGMENT_FOOTER
)
296 static Uint32 buf
[8192];
299 readRecord(FILE* f
, Uint32
**dst
){
301 if(fread(&len
, 1, 4, f
) != 4)
306 if(fread(buf
, 4, len
, f
) != len
)
314 ndbout_c("Found %d records", recNo
);
323 readLogEntry(FILE* f
, Uint32
**dst
){
325 if(fread(&len
, 1, 4, f
) != 4)
330 if(fread(&buf
[1], 4, len
, f
) != len
)
345 operator<<(NdbOut
& ndbout
, const BackupFormat::FileHeader
& hf
){
348 memcpy(buf
, hf
.Magic
, sizeof(hf
.Magic
));
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
;
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
;
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
;
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)
398 dst
->SectionType
= ntohl(dst
->SectionType
);
399 dst
->SectionLength
= ntohl(dst
->SectionLength
);
401 if(dst
->SectionType
!= BackupFormat::TABLE_LIST
)
404 const Uint32 len
= dst
->SectionLength
- 2;
405 if(fread(&dst
->TableIds
[0], 4, len
, f
) != len
)
408 for(Uint32 i
= 0; i
<len
; i
++){
409 dst
->TableIds
[i
] = ntohl(dst
->TableIds
[i
]);
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)
425 dst
->SectionType
= ntohl(dst
->SectionType
);
426 dst
->SectionLength
= ntohl(dst
->SectionLength
);
428 if(dst
->SectionType
!= BackupFormat::TABLE_DESCRIPTION
)
431 const Uint32 len
= dst
->SectionLength
- 2;
432 if(fread(&dst
->DictTabInfo
[0], 4, len
, f
) != len
)
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)
448 dst
->SectionType
= ntohl(dst
->SectionType
);
449 dst
->SectionLength
= ntohl(dst
->SectionLength
);
451 if(dst
->SectionType
!= BackupFormat::GCP_ENTRY
)
454 dst
->StartGCP
= ntohl(dst
->StartGCP
);
455 dst
->StopGCP
= ntohl(dst
->StopGCP
);
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)
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);
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
;
491 case SimpleProperties::StringValue
:
492 if(it
.getValueLen() < sizeof(buf
)){
494 ndbout
<< "Key: " << it
.getKey()
495 << " value(" << it
.getValueLen() << ") : "
496 << "\"" << buf
<< "\"" << endl
;
498 ndbout
<< "Key: " << it
.getKey()
499 << " value(" << it
.getValueLen() << ") : "
500 << "\"" << "<TOO LONG>" << "\"" << endl
;
505 ndbout
<< "Unknown type for key: " << it
.getKey()
506 << " type: " << it
.getValueType() << endl
;
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
;