1 /*
2 * Copyright (C) 2016 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3 *
4 * This file is part of MooseFS.
5 *
6 * MooseFS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2 (only).
9 *
10 * MooseFS is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with MooseFS; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18 * or visit http://www.gnu.org/licenses/gpl-2.0.html
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <inttypes.h>
30
31 #include "MFSCommunication.h"
32 #include "datapack.h"
33
34 #define STR_AUX(x) #x
35 #define STR(x) STR_AUX(x)
36 const char id[]="@(#) version: " VERSSTR ", written by Jakub Kruszona-Zawadzki";
37
38 #define MAX_INDEX 0x7FFFFFFF
39 #define MAX_CHUNKS_PER_FILE (MAX_INDEX+1)
40
dispchar(uint8_t c)41 static inline char dispchar(uint8_t c) {
42 return (c>=32 && c<=126)?c:'.';
43 }
44
makestrip(char strip[16],uint32_t ip)45 static inline void makestrip(char strip[16],uint32_t ip) {
46 snprintf(strip,16,"%03"PRIu8".%03"PRIu8".%03"PRIu8".%03"PRIu8,(uint8_t)(ip>>24),(uint8_t)(ip>>16),(uint8_t)(ip>>8),(uint8_t)ip);
47 strip[15]=0;
48 }
49
print_name(FILE * in,uint32_t nleng)50 void print_name(FILE *in,uint32_t nleng) {
51 uint8_t buff[1024];
52 uint32_t x,y,i;
53 size_t happy;
54 while (nleng>0) {
55 y = (nleng>1024)?1024:nleng;
56 x = fread(buff,1,y,in);
57 for (i=0 ; i<x ; i++) {
58 if (buff[i]<32 || buff[i]>127) {
59 buff[i]='.';
60 }
61 }
62 happy = fwrite(buff,1,x,stdout);
63 (void)happy;
64 if (x!=y) {
65 return;
66 }
67 nleng -= x;
68 }
69 }
70
print_hex(FILE * in,uint32_t vleng)71 void print_hex(FILE *in,uint32_t vleng) {
72 uint8_t buff[1024];
73 uint32_t x,y,i;
74 while (vleng>0) {
75 y = (vleng>1024)?1024:vleng;
76 x = fread(buff,1,y,in);
77 for (i=0 ; i<x ; i++) {
78 printf("%02"PRIX8,buff[i]);
79 }
80 if (x!=y) {
81 return;
82 }
83 vleng -= x;
84 }
85 }
86
chunk_load(FILE * fd,uint8_t mver)87 int chunk_load(FILE *fd,uint8_t mver) {
88 uint8_t hdr[8];
89 uint8_t loadbuff[16];
90 const uint8_t *ptr;
91 int32_t r;
92 uint64_t chunkid,nextchunkid;
93 uint32_t version,lockedto;
94
95 (void)mver;
96
97 if (fread(hdr,1,8,fd)!=8) {
98 return -1;
99 }
100 ptr = hdr;
101 nextchunkid = get64bit(&ptr);
102 printf("# nextchunkid: %016"PRIX64"\n",nextchunkid);
103 for (;;) {
104 r = fread(loadbuff,1,16,fd);
105 (void)r;
106 ptr = loadbuff;
107 chunkid = get64bit(&ptr);
108 version = get32bit(&ptr);
109 lockedto = get32bit(&ptr);
110 if (chunkid==0 && version==0 && lockedto==0) {
111 return 0;
112 }
113 printf("*|i:%016"PRIX64"|v:%08"PRIX32"|t:%10"PRIu32"\n",chunkid,version,lockedto);
114 }
115 }
116
fs_loadedge(FILE * fd,uint8_t mver)117 int fs_loadedge(FILE *fd,uint8_t mver) {
118 uint8_t uedgebuff[4+4+8+2];
119 const uint8_t *ptr;
120 uint32_t parent_id;
121 uint32_t child_id;
122 uint64_t edge_id;
123 uint16_t nleng;
124
125 ptr = uedgebuff;
126 if (mver<=0x10) {
127 if (fread(uedgebuff,1,4+4+2,fd)!=4+4+2) {
128 fprintf(stderr,"loading edge: read error\n");
129 return -1;
130 }
131 parent_id = get32bit(&ptr);
132 child_id = get32bit(&ptr);
133 edge_id = 0;
134 nleng = get16bit(&ptr);
135 } else {
136 if (fread(uedgebuff,1,4+4+8+2,fd)!=4+4+8+2) {
137 fprintf(stderr,"loading edge: read error\n");
138 return -1;
139 }
140 parent_id = get32bit(&ptr);
141 child_id = get32bit(&ptr);
142 edge_id = get64bit(&ptr);
143 nleng = get16bit(&ptr);
144 }
145 if (parent_id==0 && child_id==0) { // last edge
146 return 1;
147 }
148
149 if (parent_id==0) {
150 printf("E|p: NULL|c:%10"PRIu32"|i:%016"PRIX64"|n:",child_id,edge_id);
151 } else {
152 printf("E|p:%10"PRIu32"|c:%10"PRIu32"|i:%016"PRIX64"|n:",parent_id,child_id,edge_id);
153 }
154 print_name(fd,nleng);
155 printf("\n");
156 return 0;
157 }
158
fsnodes_type_convert(uint8_t type)159 static inline uint8_t fsnodes_type_convert(uint8_t type) {
160 switch (type) {
161 case DISP_TYPE_FILE:
162 return TYPE_FILE;
163 case DISP_TYPE_DIRECTORY:
164 return TYPE_DIRECTORY;
165 case DISP_TYPE_SYMLINK:
166 return TYPE_SYMLINK;
167 case DISP_TYPE_FIFO:
168 return TYPE_FIFO;
169 case DISP_TYPE_BLOCKDEV:
170 return TYPE_BLOCKDEV;
171 case DISP_TYPE_CHARDEV:
172 return TYPE_CHARDEV;
173 case DISP_TYPE_SOCKET:
174 return TYPE_SOCKET;
175 case DISP_TYPE_TRASH:
176 return TYPE_TRASH;
177 case DISP_TYPE_SUSTAINED:
178 return TYPE_SUSTAINED;
179 }
180 return 0;
181 }
182
fs_loadnode(FILE * fd,uint8_t mver)183 int fs_loadnode(FILE *fd,uint8_t mver) {
184 uint8_t unodebuff[4+1+1+2+4+4+4+4+4+4+8+4+2+8*65536+4*65536+4];
185 const uint8_t *ptr,*chptr;
186 uint8_t type,goal,flags;
187 uint32_t nodeid,uid,gid,atimestamp,mtimestamp,ctimestamp,trashtime;
188 uint16_t mode;
189 uint32_t hdrsize;
190 char c;
191
192 type = fgetc(fd);
193 if (type==0) { // last node
194 return 1;
195 }
196 if (mver<=0x11) {
197 hdrsize = 4+1+2+6*4;
198 } else {
199 hdrsize = 4+1+1+2+6*4;
200 if (mver<=0x12) {
201 type = fsnodes_type_convert(type);
202 }
203 }
204 switch (type) {
205 case TYPE_DIRECTORY:
206 case TYPE_FIFO:
207 case TYPE_SOCKET:
208 if (fread(unodebuff,1,hdrsize,fd)!=hdrsize) {
209 fprintf(stderr,"loading node: read error\n");
210 return -1;
211 }
212 break;
213 case TYPE_BLOCKDEV:
214 case TYPE_CHARDEV:
215 case TYPE_SYMLINK:
216 if (fread(unodebuff,1,hdrsize+4,fd)!=hdrsize+4) {
217 fprintf(stderr,"loading node: read error\n");
218 return -1;
219 }
220 break;
221 case TYPE_FILE:
222 case TYPE_TRASH:
223 case TYPE_SUSTAINED:
224 if (fread(unodebuff,1,hdrsize+8+4+2,fd)!=hdrsize+8+4+2) {
225 fprintf(stderr,"loading node: read error\n");
226 return -1;
227 }
228 break;
229 default:
230 fprintf(stderr,"loading node: unrecognized node type: %c\n",type);
231 return -1;
232 }
233 c='?';
234 switch (type) {
235 case TYPE_DIRECTORY:
236 c='D';
237 break;
238 case TYPE_SOCKET:
239 c='S';
240 break;
241 case TYPE_FIFO:
242 c='F';
243 break;
244 case TYPE_BLOCKDEV:
245 c='B';
246 break;
247 case TYPE_CHARDEV:
248 c='C';
249 break;
250 case TYPE_SYMLINK:
251 c='L';
252 break;
253 case TYPE_FILE:
254 c='-';
255 break;
256 case TYPE_TRASH:
257 c='T';
258 break;
259 case TYPE_SUSTAINED:
260 c='R';
261 break;
262 }
263 ptr = unodebuff;
264 nodeid = get32bit(&ptr);
265 goal = get8bit(&ptr);
266 if (mver<=0x11) {
267 uint16_t flagsmode = get16bit(&ptr);
268 flags = flagsmode >> 12;
269 mode = flagsmode & 0xFFF;
270 } else {
271 flags = get8bit(&ptr);
272 mode = get16bit(&ptr);
273 }
274 uid = get32bit(&ptr);
275 gid = get32bit(&ptr);
276 atimestamp = get32bit(&ptr);
277 mtimestamp = get32bit(&ptr);
278 ctimestamp = get32bit(&ptr);
279 trashtime = get32bit(&ptr);
280
281 printf("%c|i:%10"PRIu32"|#:%"PRIu8"|e:%1"PRIX8"|m:%04"PRIo16"|u:%10"PRIu32"|g:%10"PRIu32"|a:%10"PRIu32",m:%10"PRIu32",c:%10"PRIu32"|t:%10"PRIu32,c,nodeid,goal,flags,mode,uid,gid,atimestamp,mtimestamp,ctimestamp,trashtime);
282
283 if (type==TYPE_BLOCKDEV || type==TYPE_CHARDEV) {
284 uint32_t rdev;
285 rdev = get32bit(&ptr);
286 printf("|d:%5"PRIu32",%5"PRIu32"\n",rdev>>16,rdev&0xFFFF);
287 } else if (type==TYPE_SYMLINK) {
288 uint32_t pleng;
289 pleng = get32bit(&ptr);
290 printf("|p:");
291 print_name(fd,pleng);
292 printf("\n");
293 } else if (type==TYPE_FILE || type==TYPE_TRASH || type==TYPE_SUSTAINED) {
294 uint64_t length,chunkid;
295 uint32_t ci,ch,sessionid;
296 uint16_t sessionids;
297
298 length = get64bit(&ptr);
299 ch = get32bit(&ptr);
300 sessionids = get16bit(&ptr);
301
302 printf("|l:%20"PRIu64"|c:(",length);
303 while (ch>65536) {
304 chptr = ptr;
305 if (fread((uint8_t*)ptr,1,8*65536,fd)!=8*65536) {
306 fprintf(stderr,"loading node: read error\n");
307 return -1;
308 }
309 for (ci=0 ; ci<65536 ; ci++) {
310 chunkid = get64bit(&chptr);
311 if (chunkid>0) {
312 printf("%016"PRIX64,chunkid);
313 } else {
314 printf("N");
315 }
316 printf(",");
317 }
318 ch-=65536;
319 }
320
321 if (fread((uint8_t*)ptr,1,8*ch+4*sessionids,fd)!=8*ch+4*sessionids) {
322 fprintf(stderr,"loading node: read error\n");
323 return -1;
324 }
325
326 while (ch>0) {
327 chunkid = get64bit(&ptr);
328 if (chunkid>0) {
329 printf("%016"PRIX64,chunkid);
330 } else {
331 printf("N");
332 }
333 if (ch>1) {
334 printf(",");
335 }
336 ch--;
337 }
338 printf(")|r:(");
339 while (sessionids>0) {
340 sessionid = get32bit(&ptr);
341 printf("%"PRIu32,sessionid);
342 if (sessionids>1) {
343 printf(",");
344 }
345 sessionids--;
346 }
347 printf(")\n");
348 } else {
349 printf("\n");
350 }
351
352 return 0;
353 }
354
fs_loadnodes(FILE * fd,uint8_t fver,uint8_t mver)355 int fs_loadnodes(FILE *fd,uint8_t fver,uint8_t mver) {
356 int s;
357 uint8_t hdr[8];
358 const uint8_t *ptr;
359 uint32_t maxnodeid,hashelements;
360 (void)fver;
361 if (fver>=0x20) {
362 if (mver<=0x10) {
363 if (fread(hdr,1,4,fd)!=4) {
364 fprintf(stderr,"loading node: read error\n");
365 return -1;
366 }
367 ptr = hdr;
368 maxnodeid = get32bit(&ptr);
369 printf("# maxinode: %"PRIu32"\n",maxnodeid);
370 } else {
371 if (fread(hdr,1,8,fd)!=8) {
372 fprintf(stderr,"loading node: read error\n");
373 return -1;
374 }
375 ptr = hdr;
376 maxnodeid = get32bit(&ptr);
377 hashelements = get32bit(&ptr);
378 printf("# maxinode: %"PRIu32" ; hashelements: %"PRIu32"\n",maxnodeid,hashelements);
379 }
380 }
381 do {
382 s = fs_loadnode(fd,mver);
383 if (s<0) {
384 return -1;
385 }
386 } while (s==0);
387 return 0;
388 }
389
fs_loadedges(FILE * fd,uint8_t mver)390 int fs_loadedges(FILE *fd,uint8_t mver) {
391 uint8_t hdr[8];
392 const uint8_t *ptr;
393 uint64_t nextedgeid;
394 int s;
395 if (mver>0x10) {
396 if (fread(hdr,1,8,fd)!=8) {
397 fprintf(stderr,"loading edge: read error\n");
398 return -1;
399 }
400 ptr = hdr;
401 nextedgeid = get64bit(&ptr);
402 printf("# nextedgeid: %016"PRIX64"\n",nextedgeid);
403 }
404 do {
405 s = fs_loadedge(fd,mver);
406 if (s<0) {
407 return -1;
408 }
409 } while (s==0);
410 return 0;
411 }
412
fs_loadfree(FILE * fd,uint8_t mver)413 int fs_loadfree(FILE *fd,uint8_t mver) {
414 uint8_t rbuff[8];
415 const uint8_t *ptr;
416 uint32_t t,nodeid,ftime;
417 (void)mver;
418 if (fread(rbuff,1,4,fd)!=4) {
419 return -1;
420 }
421 ptr=rbuff;
422 t = get32bit(&ptr);
423 printf("# free nodes: %"PRIu32"\n",t);
424 while (t>0) {
425 if (fread(rbuff,1,8,fd)!=8) {
426 return -1;
427 }
428 ptr = rbuff;
429 nodeid = get32bit(&ptr);
430 ftime = get32bit(&ptr);
431 printf("I|i:%10"PRIu32"|f:%10"PRIu32"\n",nodeid,ftime);
432 t--;
433 }
434 return 0;
435 }
436
fs_loadquota(FILE * fd,uint8_t mver)437 int fs_loadquota(FILE *fd,uint8_t mver) {
438 uint8_t rbuff[66];
439 const uint8_t *ptr;
440 uint8_t exceeded,flags;
441 uint32_t t,nodeid,stimestamp,sinodes,hinodes;
442 uint64_t slength,hlength,ssize,hsize,srealsize,hrealsize;
443 (void)mver;
444 if (fread(rbuff,1,4,fd)!=4) {
445 return -1;
446 }
447 ptr=rbuff;
448 t = get32bit(&ptr);
449 printf("# quota nodes: %"PRIu32"\n",t);
450 while (t>0) {
451 if (fread(rbuff,1,66,fd)!=66) {
452 return -1;
453 }
454 ptr = rbuff;
455 nodeid = get32bit(&ptr);
456 exceeded = get8bit(&ptr);
457 flags = get8bit(&ptr);
458 stimestamp = get32bit(&ptr);
459 sinodes = get32bit(&ptr);
460 hinodes = get32bit(&ptr);
461 slength = get64bit(&ptr);
462 hlength = get64bit(&ptr);
463 ssize = get64bit(&ptr);
464 hsize = get64bit(&ptr);
465 srealsize = get64bit(&ptr);
466 hrealsize = get64bit(&ptr);
467 printf("Q|i:%10"PRIu32"|e:%c|f:%02"PRIX8"|s:%10"PRIu32,nodeid,(exceeded)?'1':'0',flags,stimestamp);
468 if (flags"A_FLAG_SINODES) {
469 printf("|si:%10"PRIu32,sinodes);
470 } else {
471 printf("|si: -");
472 }
473 if (flags"A_FLAG_HINODES) {
474 printf("|hi:%10"PRIu32,hinodes);
475 } else {
476 printf("|hi: -");
477 }
478 if (flags"A_FLAG_SLENGTH) {
479 printf("|sl:%20"PRIu64,slength);
480 } else {
481 printf("|sl: -");
482 }
483 if (flags"A_FLAG_HLENGTH) {
484 printf("|hl:%20"PRIu64,hlength);
485 } else {
486 printf("|hl: -");
487 }
488 if (flags"A_FLAG_SSIZE) {
489 printf("|ss:%20"PRIu64,ssize);
490 } else {
491 printf("|ss: -");
492 }
493 if (flags"A_FLAG_HSIZE) {
494 printf("|hs:%20"PRIu64,hsize);
495 } else {
496 printf("|hs: -");
497 }
498 if (flags"A_FLAG_SREALSIZE) {
499 printf("|sr:%20"PRIu64,srealsize);
500 } else {
501 printf("|sr: -");
502 }
503 if (flags"A_FLAG_HREALSIZE) {
504 printf("|hr:%20"PRIu64,hrealsize);
505 } else {
506 printf("|hr: -");
507 }
508 printf("\n");
509 t--;
510 }
511 return 0;
512 }
513
xattr_load(FILE * fd,uint8_t mver)514 int xattr_load(FILE *fd,uint8_t mver) {
515 uint8_t hdrbuff[4+1+4];
516 const uint8_t *ptr;
517 uint32_t inode;
518 uint8_t anleng;
519 uint32_t avleng;
520
521 (void)mver;
522
523 while (1) {
524 if (fread(hdrbuff,1,4+1+4,fd)!=4+1+4) {
525 fprintf(stderr,"loading xattr: read error");
526 return -1;
527 }
528 ptr = hdrbuff;
529 inode = get32bit(&ptr);
530 anleng = get8bit(&ptr);
531 avleng = get32bit(&ptr);
532 if (inode==0) {
533 return 0;
534 }
535 if (anleng==0) {
536 fprintf(stderr,"loading xattr: empty name");
537 fseek(fd,anleng+avleng,SEEK_CUR);
538 continue;
539 }
540 printf("X|i:%10"PRIu32"|n:",inode);
541 print_name(fd,anleng);
542 printf("|v:");
543 print_hex(fd,avleng);
544 printf("\n");
545 }
546 }
547
posix_acl_load(FILE * fd,uint8_t mver)548 int posix_acl_load(FILE *fd,uint8_t mver) {
549 uint8_t hdrbuff[4+1+2*6];
550 uint8_t aclbuff[6*100];
551 const uint8_t *ptr;
552 uint32_t inode;
553 uint8_t acltype;
554 uint16_t userperm;
555 uint16_t groupperm;
556 uint16_t otherperm;
557 uint16_t mask;
558 uint16_t namedusers;
559 uint16_t namedgroups;
560 uint32_t aclid;
561 uint16_t aclperm;
562 uint32_t acls,acbcnt;
563
564 (void)mver;
565
566 while (1) {
567 if (fread(hdrbuff,1,4+1+2*6,fd)!=4+1+2*6) {
568 fprintf(stderr,"loading posix_acl: read error");
569 return -1;
570 }
571 ptr = hdrbuff;
572 inode = get32bit(&ptr);
573 if (inode==0) {
574 return 0;
575 }
576 acltype = get8bit(&ptr);
577 userperm = get16bit(&ptr);
578 groupperm = get16bit(&ptr);
579 otherperm = get16bit(&ptr);
580 mask = get16bit(&ptr);
581 namedusers = get16bit(&ptr);
582 namedgroups = get16bit(&ptr);
583 printf("A|i:%10"PRIu32"|t:%"PRIu8"|u:%"PRIo16"|g:%"PRIo16"|o:%"PRIo16"|m:%"PRIo16"|n:(",inode,acltype,userperm,groupperm,otherperm,mask);
584 acls = namedusers+namedgroups;
585 acbcnt = 0;
586 while (acls>0) {
587 if (acbcnt==0) {
588 if (acls>100) {
589 acbcnt=100;
590 } else {
591 acbcnt=acls;
592 }
593 if (fread(aclbuff,6,acbcnt,fd)!=acbcnt) {
594 fprintf(stderr,"loading posix_acl: read error");
595 return -1;
596 }
597 ptr = aclbuff;
598 }
599 aclid = get32bit(&ptr);
600 aclperm = get16bit(&ptr);
601 acls--;
602 acbcnt--;
603 if (acls>=namedgroups) {
604 printf("u(%"PRIu32"):%"PRIo16,aclid,aclperm);
605 } else {
606 printf("g(%"PRIu32"):%"PRIo16,aclid,aclperm);
607 }
608 if (acls>0) {
609 printf(",");
610 }
611 }
612 printf(")\n");
613 }
614 }
615
sessions_load(FILE * fd,uint8_t mver)616 int sessions_load(FILE *fd,uint8_t mver) {
617 uint8_t hdr[8];
618 uint8_t *fsesrecord;
619 const uint8_t *ptr;
620 uint16_t dver,statsinfile;
621 uint32_t recsize;
622 uint32_t i,nextsessionid,sessionid;
623 uint32_t ileng,peerip,rootinode,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid,disconnected;
624 uint8_t sesflags,mingoal,maxgoal;
625 char strip[16];
626
627 if (mver<=0x11) {
628 if (fread(hdr,1,8,fd)!=8) {
629 fprintf(stderr,"loading sessions: read error");
630 return -1;
631 }
632
633 ptr = hdr;
634 dver = get16bit(&ptr);
635 if (dver==1) {
636 mver = 0x10;
637 } else if (dver==2) {
638 mver = 0x11;
639 }
640 } else {
641 dver = 0; // makes old gcc happy
642 if (fread(hdr,1,6,fd)!=6) {
643 fprintf(stderr,"loading sessions: read error");
644 return -1;
645 }
646 ptr = hdr;
647 }
648 nextsessionid = get32bit(&ptr);
649 statsinfile = get16bit(&ptr);
650
651 if (mver<=0x11) {
652 printf("# dver: %"PRIu16" ; nextsessionid: %"PRIu32" ; statscount: %"PRIu16"\n",dver,nextsessionid,statsinfile);
653 } else {
654 printf("# nextsessionid: %"PRIu32" ; statscount: %"PRIu16"\n",nextsessionid,statsinfile);
655 }
656 if (mver<0x11) {
657 recsize = 43+statsinfile*8;
658 } else {
659 recsize = 47+statsinfile*8;
660 }
661 fsesrecord = malloc(recsize);
662 if (fsesrecord==NULL) {
663 fprintf(stderr,"loading sessions: out of memory\n");
664 return -1;
665 }
666
667 while (1) {
668 if (fread(fsesrecord,1,recsize,fd)!=(size_t)(recsize)) {
669 free(fsesrecord);
670 fprintf(stderr,"loading sessions: read error\n");
671 return -1;
672 }
673 ptr = fsesrecord;
674 sessionid = get32bit(&ptr);
675 if (sessionid==0) {
676 free(fsesrecord);
677 return 0;
678 }
679 ileng = get32bit(&ptr);
680 peerip = get32bit(&ptr);
681 rootinode = get32bit(&ptr);
682 sesflags = get8bit(&ptr);
683 mingoal = get8bit(&ptr);
684 maxgoal = get8bit(&ptr);
685 mintrashtime = get32bit(&ptr);
686 maxtrashtime = get32bit(&ptr);
687 rootuid = get32bit(&ptr);
688 rootgid = get32bit(&ptr);
689 mapalluid = get32bit(&ptr);
690 mapallgid = get32bit(&ptr);
691 makestrip(strip,peerip);
692 if (mver>=0x11) {
693 disconnected = get32bit(&ptr);
694 printf("M|s:%10"PRIu32"|p:%s|r:%10"PRIu32"|f:%02"PRIX8"|g:%"PRIu8"-%"PRIu8"|t:%10"PRIu32"-%10"PRIu32"|m:%10"PRIu32",%10"PRIu32",%10"PRIu32",%10"PRIu32"|d:%10"PRIu32"|c:",sessionid,strip,rootinode,sesflags,mingoal,maxgoal,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid,disconnected);
695 } else {
696 printf("M|s:%10"PRIu32"|p:%s|r:%10"PRIu32"|f:%02"PRIX8"|g:%"PRIu8"-%"PRIu8"|t:%10"PRIu32"-%10"PRIu32"|m:%10"PRIu32",%10"PRIu32",%10"PRIu32",%10"PRIu32"|c:",sessionid,strip,rootinode,sesflags,mingoal,maxgoal,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid);
697 }
698 for (i=0 ; i<statsinfile ; i++) {
699 printf("%c%"PRIu32,(i==0)?'[':',',get32bit(&ptr));
700 }
701 printf("]|l:");
702 for (i=0 ; i<statsinfile ; i++) {
703 printf("%c%"PRIu32,(i==0)?'[':',',get32bit(&ptr));
704 }
705 printf("]|i:");
706 print_name(fd,ileng);
707 printf("\n");
708 }
709 }
710
csdb_load(FILE * fd,uint8_t mver)711 int csdb_load(FILE *fd,uint8_t mver) {
712 uint8_t csdbbuff[9];
713 const uint8_t *ptr;
714 uint32_t t;
715 uint32_t ip;
716 uint16_t port;
717 uint16_t csid;
718 uint8_t maintenance;
719 size_t bsize;
720 char strip[16];
721
722 if (mver<=0x10) {
723 bsize = 6;
724 } else if (mver<=0x11) {
725 bsize = 8;
726 } else {
727 bsize = 9;
728 }
729
730 if (fread(csdbbuff,1,4,fd)!=4) {
731 return -1;
732 }
733 ptr = csdbbuff;
734 t = get32bit(&ptr);
735 printf("# chunk servers: %"PRIu32"\n",t);
736 while (t>0) {
737 if (fread(csdbbuff,1,bsize,fd)!=bsize) {
738 fprintf(stderr,"loading chunk servers: read error\n");
739 return -1;
740 }
741 ptr = csdbbuff;
742 if (mver<=0x10) {
743 ip = get32bit(&ptr);
744 port = get16bit(&ptr);
745 makestrip(strip,ip);
746 printf("Z|i:%s|p:%5"PRIu16"\n",strip,port);
747 } else if (mver<=0x11) {
748 ip = get32bit(&ptr);
749 port = get16bit(&ptr);
750 csid = get16bit(&ptr);
751 makestrip(strip,ip);
752 printf("Z|i:%s|p:%5"PRIu16"|#:%5"PRIu16"\n",strip,port,csid);
753 } else {
754 ip = get32bit(&ptr);
755 port = get16bit(&ptr);
756 csid = get16bit(&ptr);
757 maintenance = get8bit(&ptr);
758 makestrip(strip,ip);
759 printf("Z|i:%s|p:%5"PRIu16"|#:%5"PRIu16"|m:%u\n",strip,port,csid,(maintenance)?1:0);
760 }
761 t--;
762 }
763 return 0;
764 }
765
of_load(FILE * fd,uint8_t mver)766 int of_load(FILE *fd,uint8_t mver) {
767 uint8_t loadbuff[8];
768 const uint8_t *ptr;
769 uint32_t sessionid,inode;
770
771 (void)mver;
772
773 for (;;) {
774 if (fread(loadbuff,1,8,fd)!=8) {
775 fprintf(stderr,"loading open files: read error\n");
776 return -1;
777 }
778 ptr = loadbuff;
779 sessionid = get32bit(&ptr);
780 inode = get32bit(&ptr);
781 if (sessionid>0 && inode>0) {
782 printf("O|s:%10"PRIu32"|i:%10"PRIu32"\n",sessionid,inode);
783 } else {
784 return 0;
785 }
786 }
787 return 0; // unreachable
788 }
789
hexdump(FILE * fd,uint64_t sleng)790 int hexdump(FILE *fd,uint64_t sleng) {
791 uint8_t lbuff[32];
792 uint32_t i;
793 while (sleng>32) {
794 if (fread(lbuff,1,32,fd)!=32) {
795 return -1;
796 }
797 for (i=0 ; i<32 ; i++) {
798 printf("%02"PRIX8" ",lbuff[i]);
799 }
800 printf(" |");
801 for (i=0 ; i<32 ; i++) {
802 printf("%c",dispchar(lbuff[i]));
803 }
804 printf("|\n");
805 sleng-=32;
806 }
807 if (sleng>0) {
808 if (fread(lbuff,1,sleng,fd)!=(size_t)sleng) {
809 return -1;
810 }
811 for (i=0 ; i<32 ; i++) {
812 if (i<sleng) {
813 printf("%02"PRIX8" ",lbuff[i]);
814 } else {
815 printf(" ");
816 }
817 }
818 printf(" |");
819 for (i=0 ; i<32 ; i++) {
820 if (i<sleng) {
821 printf("%c",dispchar(lbuff[i]));
822 } else {
823 printf(" ");
824 }
825 }
826 printf("|\n");
827 }
828 return 0;
829 }
830
fs_load_pre17(FILE * fd)831 int fs_load_pre17(FILE *fd) {
832 uint32_t maxnodeid,nextsessionid;
833 uint64_t version;
834 uint8_t hdr[16];
835 const uint8_t *ptr;
836 if (fread(hdr,1,16,fd)!=16) {
837 return -1;
838 }
839 ptr = hdr;
840 maxnodeid = get32bit(&ptr);
841 version = get64bit(&ptr);
842 nextsessionid = get32bit(&ptr);
843
844 printf("# maxnodeid: %"PRIu32" ; version: %"PRIu64" ; nextsessionid: %"PRIu32"\n",maxnodeid,version,nextsessionid);
845
846 printf("# -------------------------------------------------------------------\n");
847 if (fs_loadnodes(fd,0x15,0x10)<0) {
848 printf("error reading metadata (node)\n");
849 return -1;
850 }
851 printf("# -------------------------------------------------------------------\n");
852 if (fs_loadedges(fd,0x10)<0) {
853 printf("error reading metadata (edge)\n");
854 return -1;
855 }
856 printf("# -------------------------------------------------------------------\n");
857 if (fs_loadfree(fd,0x10)<0) {
858 printf("error reading metadata (free)\n");
859 return -1;
860 }
861 printf("# -------------------------------------------------------------------\n");
862 return 0;
863 }
864
fs_load(FILE * fd,uint8_t fver)865 int fs_load(FILE *fd,uint8_t fver) {
866 uint32_t maxnodeid,nextsessionid;
867 uint64_t sleng;
868 off_t offbegin;
869 uint64_t version,fileid;
870 uint8_t hdr[16];
871 const uint8_t *ptr;
872 uint8_t mver;
873 if (fread(hdr,1,16,fd)!=16) {
874 return -1;
875 }
876 ptr = hdr;
877
878 if (fver<0x20) {
879 maxnodeid = get32bit(&ptr);
880 version = get64bit(&ptr);
881 nextsessionid = get32bit(&ptr);
882
883 printf("# maxnodeid: %"PRIu32" ; version: %"PRIu64" ; nextsessionid: %"PRIu32"\n",maxnodeid,version,nextsessionid);
884 } else {
885 version = get64bit(&ptr);
886 fileid = get64bit(&ptr);
887
888 printf("# version: %"PRIu64" ; fileid: 0x%"PRIX64"\n",version,fileid);
889 }
890
891 while (1) {
892 if (fread(hdr,1,16,fd)!=16) {
893 printf("can't read section header\n");
894 return -1;
895 }
896 if (memcmp(hdr,"[MFS EOF MARKER]",16)==0) {
897 printf("# -------------------------------------------------------------------\n");
898 printf("# MFS END OF FILE MARKER\n");
899 printf("# -------------------------------------------------------------------\n");
900 return 0;
901 }
902 ptr = hdr+8;
903 sleng = get64bit(&ptr);
904 offbegin = ftello(fd);
905 printf("# -------------------------------------------------------------------\n");
906 printf("# section header: %c%c%c%c%c%c%c%c (%02X%02X%02X%02X%02X%02X%02X%02X) ; length: %"PRIu64"\n",dispchar(hdr[0]),dispchar(hdr[1]),dispchar(hdr[2]),dispchar(hdr[3]),dispchar(hdr[4]),dispchar(hdr[5]),dispchar(hdr[6]),dispchar(hdr[7]),hdr[0],hdr[1],hdr[2],hdr[3],hdr[4],hdr[5],hdr[6],hdr[7],sleng);
907 mver = (((hdr[5]-'0')&0xF)<<4)+(hdr[7]&0xF);
908 printf("# section type: %c%c%c%c ; version: 0x%02"PRIX8"\n",dispchar(hdr[0]),dispchar(hdr[1]),dispchar(hdr[2]),dispchar(hdr[3]),mver);
909 if (memcmp(hdr,"NODE",4)==0) {
910 if (fs_loadnodes(fd,fver,mver)<0) {
911 printf("error reading metadata (NODE)\n");
912 return -1;
913 }
914 } else if (memcmp(hdr,"EDGE",4)==0) {
915 if (fs_loadedges(fd,mver)<0) {
916 printf("error reading metadata (EDGE)\n");
917 return -1;
918 }
919 } else if (memcmp(hdr,"FREE",4)==0) {
920 if (fs_loadfree(fd,mver)<0) {
921 printf("error reading metadata (FREE)\n");
922 return -1;
923 }
924 } else if (memcmp(hdr,"QUOT",4)==0) {
925 if (fs_loadquota(fd,mver)<0) {
926 printf("error reading metadata (QUOT)\n");
927 return -1;
928 }
929 } else if (memcmp(hdr,"CHNK",4)==0) {
930 if (chunk_load(fd,mver)<0) {
931 printf("error reading metadata (CHNK)\n");
932 return -1;
933 }
934 } else if (memcmp(hdr,"XATR",4)==0) {
935 if (xattr_load(fd,mver)<0) {
936 printf("error reading metadata (XATR)\n");
937 return -1;
938 }
939 } else if (memcmp(hdr,"PACL",4)==0) {
940 if (posix_acl_load(fd,mver)<0) {
941 printf("error reading metadata (PACL)\n");
942 return -1;
943 }
944 } else if (memcmp(hdr,"SESS",4)==0) {
945 if (sessions_load(fd,mver)<0) {
946 printf("error reading metadata (SESS)\n");
947 return -1;
948 }
949 } else if (memcmp(hdr,"OPEN",4)==0) {
950 if (of_load(fd,mver)<0) {
951 printf("error reading metadata (OPEN)\n");
952 return -1;
953 }
954 } else if (memcmp(hdr,"CSDB",4)==0) {
955 if (csdb_load(fd,mver)<0) {
956 printf("error reading metadata (CSDB)\n");
957 return -1;
958 }
959 } else {
960 printf("unknown file part\n");
961 if (hexdump(fd,sleng)<0) {
962 return -1;
963 }
964 }
965 if ((off_t)(offbegin+sleng)!=ftello(fd)) {
966 fprintf(stderr,"some data in this section have not been read - file corrupted\n");
967 return -1;
968 }
969 }
970 return 0;
971 }
972
fs_loadall(const char * fname)973 int fs_loadall(const char *fname) {
974 FILE *fd;
975 uint8_t hdr[8];
976 uint8_t fver;
977
978 fd = fopen(fname,"r");
979
980 if (fd==NULL) {
981 printf("can't open metadata file\n");
982 return -1;
983 }
984 if (fread(hdr,1,8,fd)!=8) {
985 printf("can't read metadata header\n");
986 fclose(fd);
987 return -1;
988 }
989 printf("# header: %c%c%c%c%c%c%c%c (%02X%02X%02X%02X%02X%02X%02X%02X)\n",dispchar(hdr[0]),dispchar(hdr[1]),dispchar(hdr[2]),dispchar(hdr[3]),dispchar(hdr[4]),dispchar(hdr[5]),dispchar(hdr[6]),dispchar(hdr[7]),hdr[0],hdr[1],hdr[2],hdr[3],hdr[4],hdr[5],hdr[6],hdr[7]);
990 if (memcmp(hdr,"MFSM NEW",8)==0) {
991 printf("empty file\n");
992 } else if (memcmp(hdr,MFSSIGNATURE "M ",5)==0 && hdr[5]>='1' && hdr[5]<='9' && hdr[6]=='.' && hdr[7]>='0' && hdr[7]<='9') {
993 fver = ((hdr[5]-'0')<<4)+(hdr[7]-'0');
994 if (fver<0x17) {
995 if (fs_load_pre17(fd)<0) {
996 printf("error reading metadata (structure)\n");
997 fclose(fd);
998 return -1;
999 }
1000 if (chunk_load(fd,0x10)<0) {
1001 printf("error reading metadata (chunks)\n");
1002 fclose(fd);
1003 return -1;
1004 }
1005 } else {
1006 if (fs_load(fd,fver)<0) {
1007 fclose(fd);
1008 return -1;
1009 }
1010 }
1011 } else {
1012 printf("wrong metadata header (old version ?)\n");
1013 fclose(fd);
1014 return -1;
1015 }
1016 if (ferror(fd)!=0) {
1017 printf("error reading metadata\n");
1018 fclose(fd);
1019 return -1;
1020 }
1021 fclose(fd);
1022 return 0;
1023 }
1024
main(int argc,char ** argv)1025 int main(int argc,char **argv) {
1026 if (argc!=2) {
1027 printf("usage: %s metadata_file\n",argv[0]);
1028 return 1;
1029 }
1030 return (fs_loadall(argv[1])<0)?1:0;
1031 }
1032