1 /*
2 * Copyright (C) 2021 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 <unistd.h>
29 #include <sys/types.h>
30 #include <inttypes.h>
31
32 #include "MFSCommunication.h"
33 #include "datapack.h"
34 #include "idstr.h"
35
36 #define MAX_INDEX 0x7FFFFFFF
37 #define MAX_CHUNKS_PER_FILE (MAX_INDEX+1)
38
39 #define MAXSCLASSNLENG 256
40
41 static int hide_nonprintable = 0;
42
dispchar(uint8_t c)43 static inline char dispchar(uint8_t c) {
44 if (hide_nonprintable) {
45 return (c>=32 && c<=126)?c:'.';
46 } else {
47 return c;
48 }
49 }
50
makestrip(char strip[16],uint32_t ip)51 static inline void makestrip(char strip[16],uint32_t ip) {
52 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);
53 strip[15]=0;
54 }
55
print_name(FILE * in,uint32_t nleng)56 void print_name(FILE *in,uint32_t nleng) {
57 uint8_t buff[1024];
58 uint32_t x,y,i;
59 size_t happy;
60 while (nleng>0) {
61 y = (nleng>1024)?1024:nleng;
62 x = fread(buff,1,y,in);
63 if (hide_nonprintable) {
64 for (i=0 ; i<x ; i++) {
65 if (buff[i]<32 || buff[i]>127) {
66 buff[i]='.';
67 }
68 }
69 }
70 happy = fwrite(buff,1,x,stdout);
71 (void)happy;
72 if (x!=y) {
73 return;
74 }
75 nleng -= x;
76 }
77 }
78
print_hex(FILE * in,uint32_t vleng)79 void print_hex(FILE *in,uint32_t vleng) {
80 uint8_t buff[1024];
81 uint32_t x,y,i;
82 while (vleng>0) {
83 y = (vleng>1024)?1024:vleng;
84 x = fread(buff,1,y,in);
85 for (i=0 ; i<x ; i++) {
86 printf("%02"PRIX8,buff[i]);
87 }
88 if (x!=y) {
89 return;
90 }
91 vleng -= x;
92 }
93 }
94
chunk_load(FILE * fd,uint8_t mver)95 int chunk_load(FILE *fd,uint8_t mver) {
96 uint8_t hdr[8];
97 uint8_t loadbuff[17];
98 const uint8_t *ptr;
99 int32_t r,recsize;
100 uint64_t chunkid,nextchunkid;
101 uint32_t version,lockedto;
102 uint8_t archflag;
103
104 if (mver>0x11) {
105 fprintf(stderr,"loading chunks: unsupported format\n");
106 return -1;
107 }
108
109 if (fread(hdr,1,8,fd)!=8) {
110 return -1;
111 }
112 ptr = hdr;
113 nextchunkid = get64bit(&ptr);
114 recsize = (mver==0x10)?16:17;
115 printf("# nextchunkid: %016"PRIX64"\n",nextchunkid);
116 for (;;) {
117 r = fread(loadbuff,1,recsize,fd);
118 (void)r;
119 ptr = loadbuff;
120 chunkid = get64bit(&ptr);
121 version = get32bit(&ptr);
122 lockedto = get32bit(&ptr);
123 if (mver==0x10) {
124 archflag = 0;
125 } else {
126 archflag = get8bit(&ptr);
127 }
128 if (chunkid==0 && version==0 && lockedto==0) {
129 return 0;
130 }
131 printf("CHUNK|i:0x%016"PRIX64"|v:0x%08"PRIX32"|t:%10"PRIu32"|a:%"PRIu8"\n",chunkid,version,lockedto,archflag);
132 }
133 }
134
fs_loadedge(FILE * fd,uint8_t mver)135 int fs_loadedge(FILE *fd,uint8_t mver) {
136 uint8_t uedgebuff[4+4+8+2];
137 const uint8_t *ptr;
138 uint32_t parent_id;
139 uint32_t child_id;
140 uint64_t edge_id;
141 uint16_t nleng;
142
143 ptr = uedgebuff;
144 if (mver<=0x10) {
145 if (fread(uedgebuff,1,4+4+2,fd)!=4+4+2) {
146 fprintf(stderr,"loading edge: read error\n");
147 return -1;
148 }
149 parent_id = get32bit(&ptr);
150 child_id = get32bit(&ptr);
151 edge_id = 0;
152 nleng = get16bit(&ptr);
153 } else {
154 if (fread(uedgebuff,1,4+4+8+2,fd)!=4+4+8+2) {
155 fprintf(stderr,"loading edge: read error\n");
156 return -1;
157 }
158 parent_id = get32bit(&ptr);
159 child_id = get32bit(&ptr);
160 edge_id = get64bit(&ptr);
161 nleng = get16bit(&ptr);
162 }
163 if (parent_id==0 && child_id==0) { // last edge
164 return 1;
165 }
166
167 if (parent_id==0) {
168 printf("EDGE|p: NULL|c:%10"PRIu32"|i:0x%016"PRIX64"|n:",child_id,edge_id);
169 } else {
170 printf("EDGE|p:%10"PRIu32"|c:%10"PRIu32"|i:0x%016"PRIX64"|n:",parent_id,child_id,edge_id);
171 }
172 print_name(fd,nleng);
173 printf("\n");
174 return 0;
175 }
176
fsnodes_type_convert(uint8_t type)177 static inline uint8_t fsnodes_type_convert(uint8_t type) {
178 switch (type) {
179 case DISP_TYPE_FILE:
180 return TYPE_FILE;
181 case DISP_TYPE_DIRECTORY:
182 return TYPE_DIRECTORY;
183 case DISP_TYPE_SYMLINK:
184 return TYPE_SYMLINK;
185 case DISP_TYPE_FIFO:
186 return TYPE_FIFO;
187 case DISP_TYPE_BLOCKDEV:
188 return TYPE_BLOCKDEV;
189 case DISP_TYPE_CHARDEV:
190 return TYPE_CHARDEV;
191 case DISP_TYPE_SOCKET:
192 return TYPE_SOCKET;
193 case DISP_TYPE_TRASH:
194 return TYPE_TRASH;
195 case DISP_TYPE_SUSTAINED:
196 return TYPE_SUSTAINED;
197 }
198 return 0;
199 }
200
fs_loadnode(FILE * fd,uint8_t mver)201 int fs_loadnode(FILE *fd,uint8_t mver) {
202 uint8_t unodebuff[4+1+1+1+2+4+4+4+4+4+4+8+4+2+8*65536+4*65536+4];
203 const uint8_t *ptr,*chptr;
204 uint8_t type,goal,flags,winattr;
205 uint32_t nodeid,uid,gid,atimestamp,mtimestamp,ctimestamp,trashtime;
206 uint16_t mode;
207 uint32_t hdrsize;
208 char c;
209
210 type = fgetc(fd);
211 if (type==0) { // last node
212 return 1;
213 }
214 if (mver<=0x11) {
215 hdrsize = 4+1+2+6*4;
216 } else if (mver<=0x13) {
217 hdrsize = 4+1+1+2+6*4;
218 } else {
219 hdrsize = 4+1+1+1+2+5*4+2;
220 }
221 if (mver<=0x12) {
222 type = fsnodes_type_convert(type);
223 }
224 switch (type) {
225 case TYPE_DIRECTORY:
226 case TYPE_FIFO:
227 case TYPE_SOCKET:
228 if (fread(unodebuff,1,hdrsize,fd)!=hdrsize) {
229 fprintf(stderr,"loading node: read error\n");
230 return -1;
231 }
232 break;
233 case TYPE_BLOCKDEV:
234 case TYPE_CHARDEV:
235 case TYPE_SYMLINK:
236 if (fread(unodebuff,1,hdrsize+4,fd)!=hdrsize+4) {
237 fprintf(stderr,"loading node: read error\n");
238 return -1;
239 }
240 break;
241 case TYPE_FILE:
242 case TYPE_TRASH:
243 case TYPE_SUSTAINED:
244 if (mver<=0x13) {
245 if (fread(unodebuff,1,hdrsize+8+4+2,fd)!=hdrsize+8+4+2) {
246 fprintf(stderr,"loading node: read error\n");
247 return -1;
248 }
249 } else {
250 if (fread(unodebuff,1,hdrsize+8+4,fd)!=hdrsize+8+4) {
251 fprintf(stderr,"loading node: read error\n");
252 return -1;
253 }
254 }
255 break;
256 default:
257 fprintf(stderr,"loading node: unrecognized node type: %c\n",type);
258 return -1;
259 }
260 c='?';
261 switch (type) {
262 case TYPE_DIRECTORY:
263 c='D';
264 break;
265 case TYPE_SOCKET:
266 c='S';
267 break;
268 case TYPE_FIFO:
269 c='F';
270 break;
271 case TYPE_BLOCKDEV:
272 c='B';
273 break;
274 case TYPE_CHARDEV:
275 c='C';
276 break;
277 case TYPE_SYMLINK:
278 c='L';
279 break;
280 case TYPE_FILE:
281 c='-';
282 break;
283 case TYPE_TRASH:
284 c='T';
285 break;
286 case TYPE_SUSTAINED:
287 c='R';
288 break;
289 }
290 ptr = unodebuff;
291 nodeid = get32bit(&ptr);
292 goal = get8bit(&ptr);
293 if (mver<=0x11) {
294 uint16_t flagsmode = get16bit(&ptr);
295 flags = flagsmode >> 12;
296 mode = flagsmode & 0xFFF;
297 winattr = 0;
298 } else {
299 flags = get8bit(&ptr);
300 if (mver>=0x14) {
301 winattr = get8bit(&ptr);
302 } else {
303 winattr = 0;
304 }
305 mode = get16bit(&ptr);
306 }
307 uid = get32bit(&ptr);
308 gid = get32bit(&ptr);
309 atimestamp = get32bit(&ptr);
310 mtimestamp = get32bit(&ptr);
311 ctimestamp = get32bit(&ptr);
312 if (mver>=0x14) {
313 trashtime = get16bit(&ptr);
314 printf("NODE|k:%c|i:%10"PRIu32"|#:%"PRIu8"|e:0x%02"PRIX8"|w:0x%1"PRIX8"|m:0%04"PRIo16"|u:%10"PRIu32"|g:%10"PRIu32"|a:%10"PRIu32",m:%10"PRIu32",c:%10"PRIu32"|t:%5"PRIu32"h",c,nodeid,goal,flags,winattr,mode,uid,gid,atimestamp,mtimestamp,ctimestamp,trashtime);
315 } else {
316 trashtime = get32bit(&ptr);
317 printf("NODE|k:%c|i:%10"PRIu32"|#:%"PRIu8"|e:0x%02"PRIX8"|m:0%04"PRIo16"|u:%10"PRIu32"|g:%10"PRIu32"|a:%10"PRIu32",m:%10"PRIu32",c:%10"PRIu32"|t:%10"PRIu32"s",c,nodeid,goal,flags,mode,uid,gid,atimestamp,mtimestamp,ctimestamp,trashtime);
318 }
319
320 if (type==TYPE_BLOCKDEV || type==TYPE_CHARDEV) {
321 uint32_t rdev;
322 rdev = get32bit(&ptr);
323 printf("|d:%5"PRIu32",%5"PRIu32"\n",rdev>>16,rdev&0xFFFF);
324 } else if (type==TYPE_SYMLINK) {
325 uint32_t pleng;
326 pleng = get32bit(&ptr);
327 printf("|p:");
328 print_name(fd,pleng);
329 printf("\n");
330 } else if (type==TYPE_FILE || type==TYPE_TRASH || type==TYPE_SUSTAINED) {
331 uint64_t length,chunkid;
332 uint32_t ci,ch,sessionid;
333 uint16_t sessionids;
334
335 length = get64bit(&ptr);
336 ch = get32bit(&ptr);
337 if (mver<=0x13) {
338 sessionids = get16bit(&ptr);
339 } else {
340 sessionids = 0;
341 }
342
343 printf("|l:%20"PRIu64"|c:(",length);
344 while (ch>65536) {
345 chptr = ptr;
346 if (fread((uint8_t*)ptr,1,8*65536,fd)!=8*65536) {
347 fprintf(stderr,"loading node: read error\n");
348 return -1;
349 }
350 for (ci=0 ; ci<65536 ; ci++) {
351 chunkid = get64bit(&chptr);
352 if (chunkid>0) {
353 printf("%016"PRIX64,chunkid);
354 } else {
355 printf("N");
356 }
357 printf(",");
358 }
359 ch-=65536;
360 }
361
362 if (fread((uint8_t*)ptr,1,8*ch+4*sessionids,fd)!=8*ch+4*sessionids) {
363 fprintf(stderr,"loading node: read error\n");
364 return -1;
365 }
366
367 while (ch>0) {
368 chunkid = get64bit(&ptr);
369 if (chunkid>0) {
370 printf("%016"PRIX64,chunkid);
371 } else {
372 printf("N");
373 }
374 if (ch>1) {
375 printf(",");
376 }
377 ch--;
378 }
379 if (mver<=0x13) {
380 printf(")|r:(");
381 while (sessionids>0) {
382 sessionid = get32bit(&ptr);
383 printf("%"PRIu32,sessionid);
384 if (sessionids>1) {
385 printf(",");
386 }
387 sessionids--;
388 }
389 }
390 printf(")\n");
391 } else {
392 printf("\n");
393 }
394
395 return 0;
396 }
397
fs_loadnodes(FILE * fd,uint8_t fver,uint8_t mver)398 int fs_loadnodes(FILE *fd,uint8_t fver,uint8_t mver) {
399 int s;
400 uint8_t hdr[8];
401 const uint8_t *ptr;
402 uint32_t maxnodeid,hashelements;
403 (void)fver;
404 if (fver>=0x20) {
405 if (mver>0x14) {
406 fprintf(stderr,"loading node: unsupported format\n");
407 return -1;
408 }
409 if (mver<=0x10) {
410 if (fread(hdr,1,4,fd)!=4) {
411 fprintf(stderr,"loading node: read error\n");
412 return -1;
413 }
414 ptr = hdr;
415 maxnodeid = get32bit(&ptr);
416 printf("# maxinode: %"PRIu32"\n",maxnodeid);
417 } else {
418 if (fread(hdr,1,8,fd)!=8) {
419 fprintf(stderr,"loading node: read error\n");
420 return -1;
421 }
422 ptr = hdr;
423 maxnodeid = get32bit(&ptr);
424 hashelements = get32bit(&ptr);
425 printf("# maxinode: %"PRIu32" ; hashelements: %"PRIu32"\n",maxnodeid,hashelements);
426 }
427 }
428 do {
429 s = fs_loadnode(fd,mver);
430 if (s<0) {
431 return -1;
432 }
433 } while (s==0);
434 return 0;
435 }
436
fs_loadedges(FILE * fd,uint8_t mver)437 int fs_loadedges(FILE *fd,uint8_t mver) {
438 uint8_t hdr[8];
439 const uint8_t *ptr;
440 uint64_t nextedgeid;
441 int s;
442 if (mver>0x11) {
443 fprintf(stderr,"loading edge: unsupported format\n");
444 return -1;
445 }
446 if (mver>0x10) {
447 if (fread(hdr,1,8,fd)!=8) {
448 fprintf(stderr,"loading edge: read error\n");
449 return -1;
450 }
451 ptr = hdr;
452 nextedgeid = get64bit(&ptr);
453 printf("# nextedgeid: %016"PRIX64"\n",nextedgeid);
454 }
455 do {
456 s = fs_loadedge(fd,mver);
457 if (s<0) {
458 return -1;
459 }
460 } while (s==0);
461 return 0;
462 }
463
fs_loadfree(FILE * fd,uint8_t mver)464 int fs_loadfree(FILE *fd,uint8_t mver) {
465 uint8_t rbuff[8];
466 const uint8_t *ptr;
467 uint32_t t,nodeid,ftime;
468 if (mver>0x10) {
469 fprintf(stderr,"loading free nodes: unsupported format\n");
470 return -1;
471 }
472 if (fread(rbuff,1,4,fd)!=4) {
473 return -1;
474 }
475 ptr=rbuff;
476 t = get32bit(&ptr);
477 printf("# free nodes: %"PRIu32"\n",t);
478 while (t>0) {
479 if (fread(rbuff,1,8,fd)!=8) {
480 return -1;
481 }
482 ptr = rbuff;
483 nodeid = get32bit(&ptr);
484 ftime = get32bit(&ptr);
485 printf("FREEID|i:%10"PRIu32"|f:%10"PRIu32"\n",nodeid,ftime);
486 t--;
487 }
488 return 0;
489 }
490
fs_loadquota(FILE * fd,uint8_t mver)491 int fs_loadquota(FILE *fd,uint8_t mver) {
492 uint8_t rbuff[70];
493 const uint8_t *ptr;
494 uint8_t exceeded,flags;
495 uint32_t t,graceperiod,nodeid,stimestamp,sinodes,hinodes;
496 uint64_t slength,hlength,ssize,hsize,srealsize,hrealsize;
497 size_t rsize;
498
499 if (mver>0x11) {
500 fprintf(stderr,"loading quota: unsupported format\n");
501 return -1;
502 }
503 rsize = (mver==0x10)?66:70;
504 if (fread(rbuff,1,4,fd)!=4) {
505 return -1;
506 }
507 ptr=rbuff;
508 t = get32bit(&ptr);
509 printf("# quota nodes: %"PRIu32"\n",t);
510 while (t>0) {
511 if (fread(rbuff,1,rsize,fd)!=rsize) {
512 return -1;
513 }
514 ptr = rbuff;
515 nodeid = get32bit(&ptr);
516 if (mver>=0x11) {
517 graceperiod = get32bit(&ptr);
518 } else {
519 graceperiod = 7*86400;
520 }
521 exceeded = get8bit(&ptr);
522 flags = get8bit(&ptr);
523 stimestamp = get32bit(&ptr);
524 sinodes = get32bit(&ptr);
525 hinodes = get32bit(&ptr);
526 slength = get64bit(&ptr);
527 hlength = get64bit(&ptr);
528 ssize = get64bit(&ptr);
529 hsize = get64bit(&ptr);
530 srealsize = get64bit(&ptr);
531 hrealsize = get64bit(&ptr);
532 printf("QUOTA|i:%10"PRIu32"|g:%"PRIu32"|e:%c|f:0x%02"PRIX8"|s:%10"PRIu32,nodeid,graceperiod,(exceeded)?'1':'0',flags,stimestamp);
533 if (flags"A_FLAG_SINODES) {
534 printf("|si:%10"PRIu32,sinodes);
535 } else {
536 printf("|si: -");
537 }
538 if (flags"A_FLAG_HINODES) {
539 printf("|hi:%10"PRIu32,hinodes);
540 } else {
541 printf("|hi: -");
542 }
543 if (flags"A_FLAG_SLENGTH) {
544 printf("|sl:%20"PRIu64,slength);
545 } else {
546 printf("|sl: -");
547 }
548 if (flags"A_FLAG_HLENGTH) {
549 printf("|hl:%20"PRIu64,hlength);
550 } else {
551 printf("|hl: -");
552 }
553 if (flags"A_FLAG_SSIZE) {
554 printf("|ss:%20"PRIu64,ssize);
555 } else {
556 printf("|ss: -");
557 }
558 if (flags"A_FLAG_HSIZE) {
559 printf("|hs:%20"PRIu64,hsize);
560 } else {
561 printf("|hs: -");
562 }
563 if (flags"A_FLAG_SREALSIZE) {
564 printf("|sr:%20"PRIu64,srealsize);
565 } else {
566 printf("|sr: -");
567 }
568 if (flags"A_FLAG_HREALSIZE) {
569 printf("|hr:%20"PRIu64,hrealsize);
570 } else {
571 printf("|hr: -");
572 }
573 printf("\n");
574 t--;
575 }
576 return 0;
577 }
578
xattr_load(FILE * fd,uint8_t mver)579 int xattr_load(FILE *fd,uint8_t mver) {
580 uint8_t hdrbuff[4+1+4];
581 const uint8_t *ptr;
582 uint32_t inode;
583 uint8_t anleng;
584 uint32_t avleng;
585
586 if (mver>0x10) {
587 fprintf(stderr,"loading xattr: unsupported format\n");
588 return -1;
589 }
590
591 while (1) {
592 if (fread(hdrbuff,1,4+1+4,fd)!=4+1+4) {
593 fprintf(stderr,"loading xattr: read error");
594 return -1;
595 }
596 ptr = hdrbuff;
597 inode = get32bit(&ptr);
598 anleng = get8bit(&ptr);
599 avleng = get32bit(&ptr);
600 if (inode==0) {
601 return 0;
602 }
603 if (anleng==0) {
604 fprintf(stderr,"loading xattr: empty name");
605 fseek(fd,anleng+avleng,SEEK_CUR);
606 continue;
607 }
608 printf("XATTR|i:%10"PRIu32"|n:",inode);
609 print_name(fd,anleng);
610 printf("|v:");
611 print_hex(fd,avleng);
612 printf("\n");
613 }
614 }
615
posix_acl_load(FILE * fd,uint8_t mver)616 int posix_acl_load(FILE *fd,uint8_t mver) {
617 uint8_t hdrbuff[4+1+2*6];
618 uint8_t aclbuff[6*100];
619 const uint8_t *ptr;
620 uint32_t inode;
621 uint8_t acltype;
622 uint16_t userperm;
623 uint16_t groupperm;
624 uint16_t otherperm;
625 uint16_t mask;
626 uint16_t namedusers;
627 uint16_t namedgroups;
628 uint32_t aclid;
629 uint16_t aclperm;
630 uint32_t acls,acbcnt;
631
632 if (mver>0x11) {
633 fprintf(stderr,"loading posix_acl: unsupported format\n");
634 return -1;
635 }
636
637 while (1) {
638 if (fread(hdrbuff,1,4+1+2*6,fd)!=4+1+2*6) {
639 fprintf(stderr,"loading posix_acl: read error");
640 return -1;
641 }
642 ptr = hdrbuff;
643 inode = get32bit(&ptr);
644 if (inode==0) {
645 return 0;
646 }
647 acltype = get8bit(&ptr);
648 userperm = get16bit(&ptr);
649 groupperm = get16bit(&ptr);
650 otherperm = get16bit(&ptr);
651 mask = get16bit(&ptr);
652 namedusers = get16bit(&ptr);
653 namedgroups = get16bit(&ptr);
654 printf("POSIXACL|i:%10"PRIu32"|t:%"PRIu8"|u:0%05"PRIo16"|g:0%05"PRIo16"|o:0%05"PRIo16"|m:0%05"PRIo16"|n:(",inode,acltype,userperm,groupperm,otherperm,mask);
655 acls = namedusers+namedgroups;
656 acbcnt = 0;
657 while (acls>0) {
658 if (acbcnt==0) {
659 if (acls>100) {
660 acbcnt=100;
661 } else {
662 acbcnt=acls;
663 }
664 if (fread(aclbuff,6,acbcnt,fd)!=acbcnt) {
665 fprintf(stderr,"loading posix_acl: read error");
666 return -1;
667 }
668 ptr = aclbuff;
669 }
670 aclid = get32bit(&ptr);
671 aclperm = get16bit(&ptr);
672 acls--;
673 acbcnt--;
674 if (acls>=namedgroups) {
675 printf("u(%"PRIu32"):0%05"PRIo16,aclid,aclperm);
676 } else {
677 printf("g(%"PRIu32"):0%05"PRIo16,aclid,aclperm);
678 }
679 if (acls>0) {
680 printf(",");
681 }
682 }
683 printf(")\n");
684 }
685 }
686
sessions_load(FILE * fd,uint8_t mver)687 int sessions_load(FILE *fd,uint8_t mver) {
688 uint8_t hdr[8];
689 uint8_t *fsesrecord;
690 const uint8_t *ptr;
691 uint16_t dver,statsinfile;
692 uint32_t recsize;
693 uint32_t i,nextsessionid,sessionid;
694 uint32_t ileng,peerip,rootinode,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid,disconnected;
695 uint32_t disables;
696 uint16_t umaskval;
697 uint64_t exportscsum;
698 uint8_t sesflags,mingoal,maxgoal;
699 char strip[16];
700
701 if (mver>0x15) {
702 fprintf(stderr,"loading sessions: unsupported format\n");
703 return -1;
704 }
705
706 if (mver<=0x11) {
707 if (fread(hdr,1,8,fd)!=8) {
708 fprintf(stderr,"loading sessions: read error");
709 return -1;
710 }
711
712 ptr = hdr;
713 dver = get16bit(&ptr);
714 if (dver==1) {
715 mver = 0x10;
716 } else if (dver==2) {
717 mver = 0x11;
718 }
719 } else {
720 dver = 0; // makes old gcc happy
721 if (fread(hdr,1,6,fd)!=6) {
722 fprintf(stderr,"loading sessions: read error");
723 return -1;
724 }
725 ptr = hdr;
726 }
727 nextsessionid = get32bit(&ptr);
728 statsinfile = get16bit(&ptr);
729
730 if (mver<=0x11) {
731 printf("# dver: %"PRIu16" ; nextsessionid: %"PRIu32" ; statscount: %"PRIu16"\n",dver,nextsessionid,statsinfile);
732 } else {
733 printf("# nextsessionid: %"PRIu32" ; statscount: %"PRIu16"\n",nextsessionid,statsinfile);
734 }
735 if (mver<0x11) {
736 recsize = 43+statsinfile*8;
737 } else if (mver<0x13) {
738 recsize = 47+statsinfile*8;
739 } else if (mver<0x14) {
740 recsize = 55+statsinfile*8;
741 } else if (mver<0x15) {
742 recsize = 57+statsinfile*8;
743 } else {
744 recsize = 61+statsinfile*8;
745 }
746 fsesrecord = malloc(recsize);
747 if (fsesrecord==NULL) {
748 fprintf(stderr,"loading sessions: out of memory\n");
749 return -1;
750 }
751
752 while (1) {
753 if (fread(fsesrecord,1,recsize,fd)!=(size_t)(recsize)) {
754 free(fsesrecord);
755 fprintf(stderr,"loading sessions: read error\n");
756 return -1;
757 }
758 ptr = fsesrecord;
759 sessionid = get32bit(&ptr);
760 if (sessionid==0) {
761 free(fsesrecord);
762 return 0;
763 }
764 if (mver>=0x13) {
765 exportscsum = get64bit(&ptr);
766 } else {
767 exportscsum = 0;
768 }
769 ileng = get32bit(&ptr);
770 peerip = get32bit(&ptr);
771 rootinode = get32bit(&ptr);
772 sesflags = get8bit(&ptr);
773 if (mver>=0x14) {
774 umaskval = get16bit(&ptr);
775 } else {
776 umaskval = 0;
777 }
778 mingoal = get8bit(&ptr);
779 maxgoal = get8bit(&ptr);
780 mintrashtime = get32bit(&ptr);
781 maxtrashtime = get32bit(&ptr);
782 rootuid = get32bit(&ptr);
783 rootgid = get32bit(&ptr);
784 mapalluid = get32bit(&ptr);
785 mapallgid = get32bit(&ptr);
786 if (mver>=0x15) {
787 disables = get32bit(&ptr);
788 } else {
789 disables = 0;
790 }
791 makestrip(strip,peerip);
792 if (mver>=0x11) {
793 disconnected = get32bit(&ptr);
794 } else {
795 disconnected = 0;
796 }
797 if (mver>=0x15) {
798 printf("SESSION|s:%10"PRIu32"|e:#%"PRIu64"|p:%s|r:%10"PRIu32"|f:0x%02"PRIX8"|u:0%03"PRIo16"|g:%"PRIu8"-%"PRIu8"|t:%10"PRIu32"-%10"PRIu32"|m:%10"PRIu32",%10"PRIu32",%10"PRIu32",%10"PRIu32"|x:0x%08"PRIX32"|d:%10"PRIu32"|c:",sessionid,exportscsum,strip,rootinode,sesflags,umaskval,mingoal,maxgoal,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid,disables,disconnected);
799 } else if (mver>=0x14) {
800 printf("SESSION|s:%10"PRIu32"|e:#%"PRIu64"|p:%s|r:%10"PRIu32"|f:0x%02"PRIX8"|u:0%03"PRIo16"|g:%"PRIu8"-%"PRIu8"|t:%10"PRIu32"-%10"PRIu32"|m:%10"PRIu32",%10"PRIu32",%10"PRIu32",%10"PRIu32"|d:%10"PRIu32"|c:",sessionid,exportscsum,strip,rootinode,sesflags,umaskval,mingoal,maxgoal,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid,disconnected);
801 } else if (mver>=0x13) {
802 printf("SESSION|s:%10"PRIu32"|e:#%"PRIu64"|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,exportscsum,strip,rootinode,sesflags,mingoal,maxgoal,mintrashtime,maxtrashtime,rootuid,rootgid,mapalluid,mapallgid,disconnected);
803 } else if (mver>=0x11) {
804 printf("SESSION|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);
805 } else {
806 printf("SESSION|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);
807 }
808 if (statsinfile==0) {
809 printf("[]|l:[]|i:");
810 } else {
811 for (i=0 ; i<statsinfile ; i++) {
812 printf("%c%"PRIu32,(i==0)?'[':',',get32bit(&ptr));
813 }
814 printf("]|l:");
815 for (i=0 ; i<statsinfile ; i++) {
816 printf("%c%"PRIu32,(i==0)?'[':',',get32bit(&ptr));
817 }
818 printf("]|i:");
819 }
820 print_name(fd,ileng);
821 printf("\n");
822 }
823 }
824
csdb_load(FILE * fd,uint8_t mver)825 int csdb_load(FILE *fd,uint8_t mver) {
826 uint8_t csdbbuff[13];
827 const uint8_t *ptr;
828 uint32_t t;
829 uint32_t ip;
830 uint16_t port;
831 uint16_t csid;
832 uint8_t maintenance;
833 uint32_t maintenance_to;
834 size_t bsize;
835 char strip[16];
836
837 if (mver>0x13) {
838 fprintf(stderr,"loading chunk servers: unsupported format\n");
839 return -1;
840 }
841 if (mver<=0x10) {
842 bsize = 6;
843 } else if (mver<=0x11) {
844 bsize = 8;
845 } else if (mver<=0x12) {
846 bsize = 9;
847 } else {
848 bsize = 13;
849 }
850
851 if (fread(csdbbuff,1,4,fd)!=4) {
852 return -1;
853 }
854 ptr = csdbbuff;
855 t = get32bit(&ptr);
856 printf("# chunk servers: %"PRIu32"\n",t);
857 while (t>0) {
858 if (fread(csdbbuff,1,bsize,fd)!=bsize) {
859 fprintf(stderr,"loading chunk servers: read error\n");
860 return -1;
861 }
862 ptr = csdbbuff;
863 if (mver<=0x10) {
864 ip = get32bit(&ptr);
865 port = get16bit(&ptr);
866 makestrip(strip,ip);
867 printf("CHUNKSERVER|i:%s|p:%5"PRIu16"\n",strip,port);
868 } else if (mver<=0x11) {
869 ip = get32bit(&ptr);
870 port = get16bit(&ptr);
871 csid = get16bit(&ptr);
872 makestrip(strip,ip);
873 printf("CHUNKSERVER|i:%s|p:%5"PRIu16"|#:%5"PRIu16"\n",strip,port,csid);
874 } else if (mver<=0x12) {
875 ip = get32bit(&ptr);
876 port = get16bit(&ptr);
877 csid = get16bit(&ptr);
878 maintenance = get8bit(&ptr);
879 makestrip(strip,ip);
880 printf("CHUNKSERVER|i:%s|p:%5"PRIu16"|#:%5"PRIu16"|m:%u\n",strip,port,csid,(maintenance)?1:0);
881 } else {
882 ip = get32bit(&ptr);
883 port = get16bit(&ptr);
884 csid = get16bit(&ptr);
885 maintenance = get8bit(&ptr);
886 maintenance_to = get32bit(&ptr);
887 makestrip(strip,ip);
888 printf("CHUNKSERVER|i:%s|p:%5"PRIu16"|#:%5"PRIu16"|m:%4s|t:%10"PRIu32"\n",strip,port,csid,(maintenance==0)?"off":(maintenance==1)?"on":(maintenance==2)?"temp":"???",maintenance_to);
889 }
890 t--;
891 }
892 return 0;
893 }
894
of_load(FILE * fd,uint8_t mver)895 int of_load(FILE *fd,uint8_t mver) {
896 uint8_t loadbuff[8];
897 const uint8_t *ptr;
898 uint32_t sessionid,inode;
899
900 if (mver>0x10) {
901 fprintf(stderr,"loading open files: unsupported format\n");
902 return -1;
903 }
904
905 for (;;) {
906 if (fread(loadbuff,1,8,fd)!=8) {
907 fprintf(stderr,"loading open files: read error\n");
908 return -1;
909 }
910 ptr = loadbuff;
911 sessionid = get32bit(&ptr);
912 inode = get32bit(&ptr);
913 if (sessionid>0 && inode>0) {
914 printf("OPENFILE|s:%10"PRIu32"|i:%10"PRIu32"\n",sessionid,inode);
915 } else {
916 return 0;
917 }
918 }
919 return 0; // unreachable
920 }
921
flock_load(FILE * fd,uint8_t mver)922 int flock_load(FILE *fd,uint8_t mver) {
923 uint8_t loadbuff[17];
924 const uint8_t *ptr;
925 uint32_t sessionid,inode;
926 uint64_t owner;
927 uint8_t ltype;
928
929 if (mver>0x10) {
930 fprintf(stderr,"loading flock locks: unsupported format\n");
931 return -1;
932 }
933
934 for (;;) {
935 if (fread(loadbuff,1,17,fd)!=17) {
936 fprintf(stderr,"loading flock locks: read error\n");
937 return -1;
938 }
939 ptr = loadbuff;
940 inode = get32bit(&ptr);
941 sessionid = get32bit(&ptr);
942 owner = get64bit(&ptr);
943 ltype = get8bit(&ptr);
944 if (inode==0 && owner==0 && sessionid==0) {
945 return 0;
946 }
947 printf("FLOCK|i:%10"PRIu32"|s:%10"PRIu32"|o:%016"PRIX64"|t:%c\n",inode,sessionid,owner,ltype?'W':'R');
948 }
949 return 0; // unreachable
950 }
951
posix_lock_load(FILE * fd,uint8_t mver)952 int posix_lock_load(FILE *fd,uint8_t mver) {
953 uint8_t loadbuff[37];
954 const uint8_t *ptr;
955 uint32_t sessionid,inode,pid;
956 uint64_t owner,start,end;
957 uint8_t type;
958
959 if (mver>0x10) {
960 fprintf(stderr,"loading posix locks: unsupported format\n");
961 return -1;
962 }
963
964 for (;;) {
965 if (fread(loadbuff,1,37,fd)!=37) {
966 fprintf(stderr,"loading posix locks: read error\n");
967 return -1;
968 }
969 ptr = loadbuff;
970 inode = get32bit(&ptr);
971 owner = get64bit(&ptr);
972 sessionid = get32bit(&ptr);
973 pid = get32bit(&ptr);
974 start = get64bit(&ptr);
975 end = get64bit(&ptr);
976 type = get8bit(&ptr);
977 if (inode==0 && owner==0 && sessionid==0) {
978 return 0;
979 }
980 printf("POSIXLOCK|i:%10"PRIu32"|s:%10"PRIu32"|o:0x%016"PRIX64"|p:%10"PRIu32"|r:<%20"PRIu64",%20"PRIu64")|t:%c\n",inode,sessionid,owner,pid,start,end,(type==POSIX_LOCK_RDLCK)?'R':(type==POSIX_LOCK_WRLCK)?'W':'?');
981 }
982 return 0; // unreachable
983 }
984
print_labels(const uint8_t ** rptr,uint8_t cnt,uint8_t orgroup)985 static void print_labels(const uint8_t **rptr,uint8_t cnt,uint8_t orgroup) {
986 uint8_t i,j,k;
987 uint8_t p;
988 uint32_t mask;
989 for (i=0 ; i<cnt ; i++) {
990 if (i>0) {
991 printf(":");
992 }
993 p = 1;
994 for (j=0 ; j<orgroup ; j++) {
995 mask = get32bit(rptr);
996 if (j==0 && mask==0) {
997 printf("*");
998 }
999 if (mask==0) {
1000 p = 0;
1001 }
1002 if (p) {
1003 if (j>0) {
1004 printf("+");
1005 }
1006 for (k=0 ; k<26 ; k++) {
1007 if (mask & (1<<k)) {
1008 printf("%c",'A'+k);
1009 }
1010 }
1011 }
1012 }
1013 }
1014 }
1015
labelset_load(FILE * fd,uint8_t mver)1016 int labelset_load(FILE *fd,uint8_t mver) {
1017 uint8_t *databuff = NULL;
1018 const uint8_t *ptr;
1019 uint32_t chunkcount;
1020 uint16_t sclassid;
1021 uint16_t arch_delay;
1022 uint8_t mode;
1023 uint8_t admin_only;
1024 uint8_t nleng;
1025 uint8_t name[MAXSCLASSNLENG];
1026 uint8_t create_labelscnt;
1027 uint8_t keep_labelscnt;
1028 uint8_t arch_labelscnt;
1029 uint8_t descrleng;
1030 uint8_t i;
1031 uint8_t orgroup;
1032 uint8_t hdrleng;
1033
1034 if (mver>0x16) {
1035 fprintf(stderr,"loading labelset: unsupported format\n");
1036 return -1;
1037 }
1038
1039 if (mver<0x15) {
1040 for (i=0 ; i<26 ; i++) {
1041 if (fread(&descrleng,1,1,fd)!=1) {
1042 fprintf(stderr,"loading labelset: read error\n");
1043 return -1;
1044 }
1045 if (descrleng>128) {
1046 fprintf(stderr,"loading labelset: description too long\n");
1047 return -1;
1048 }
1049 printf("LABELDESC|l:%c|n:",i+'A');
1050 print_name(fd,descrleng);
1051 printf("\n");
1052 }
1053 }
1054
1055 if (mver==0x10) {
1056 orgroup = 1;
1057 } else {
1058 if (fread(&orgroup,1,1,fd)!=1) {
1059 fprintf(stderr,"loading labelset: read error\n");
1060 return -1;
1061 }
1062 }
1063 if (orgroup<1) {
1064 fprintf(stderr,"loading labelset: zero or-groups !!!\n");
1065 return -1;
1066 }
1067 databuff = malloc(3U*9U*4U*(uint32_t)orgroup);
1068 hdrleng = (mver==0x12)?11:(mver<=0x13)?3:(mver<=0x14)?5:(mver<=0x15)?8:10;
1069
1070 while (1) {
1071 if (fread(databuff,1,hdrleng,fd)!=hdrleng) {
1072 fprintf(stderr,"loading labelset: read error\n");
1073 return -1;
1074 }
1075 ptr = databuff;
1076 sclassid = get16bit(&ptr);
1077 if (mver>0x15) {
1078 nleng = get8bit(&ptr);
1079 admin_only = get8bit(&ptr);
1080 mode = get8bit(&ptr);
1081 arch_delay = get16bit(&ptr);
1082 create_labelscnt = get8bit(&ptr);
1083 keep_labelscnt = get8bit(&ptr);
1084 arch_labelscnt = get8bit(&ptr);
1085 chunkcount = 0;
1086 } else if (mver>0x14) {
1087 nleng = 0;
1088 admin_only = 0;
1089 mode = get8bit(&ptr);
1090 arch_delay = get16bit(&ptr);
1091 create_labelscnt = get8bit(&ptr);
1092 keep_labelscnt = get8bit(&ptr);
1093 arch_labelscnt = get8bit(&ptr);
1094 chunkcount = 0;
1095 } else if (mver>0x13) {
1096 nleng = 0;
1097 admin_only = 0;
1098 mode = get8bit(&ptr);
1099 create_labelscnt = get8bit(&ptr);
1100 keep_labelscnt = get8bit(&ptr);
1101 arch_labelscnt = keep_labelscnt;
1102 arch_delay = 0;
1103 chunkcount = 0;
1104 } else {
1105 nleng = 0;
1106 admin_only = 0;
1107 create_labelscnt = get8bit(&ptr);
1108 keep_labelscnt = create_labelscnt;
1109 arch_labelscnt = create_labelscnt;
1110 mode = SCLASS_MODE_STD;
1111 arch_delay = 0;
1112 if (mver==0x12) {
1113 chunkcount = get32bit(&ptr);
1114 ptr+=4;
1115 } else {
1116 chunkcount = 0;
1117 }
1118 }
1119 if (nleng>0) {
1120 if (fread(name,1,nleng,fd)!=nleng) {
1121 fprintf(stderr,"loading labelset: read error\n");
1122 return -1;
1123 }
1124 }
1125 name[nleng] = 0;
1126 if (sclassid==0 && create_labelscnt==0 && keep_labelscnt==0 && arch_labelscnt==0 && chunkcount==0 && arch_delay==0) {
1127 break;
1128 }
1129 if (create_labelscnt==0 || create_labelscnt>9 || keep_labelscnt==0 || keep_labelscnt>9 || arch_labelscnt==0 || arch_labelscnt>9) {
1130 fprintf(stderr,"loading labelset: data format error (sclassid: %"PRIu16" ; mode: %"PRIu8" ; create_labelscnt: %"PRIu8" ; keep_labelscnt: %"PRIu8" ; arch_labelscnt: %"PRIu8" ; arch_delay: %"PRIu16")\n",sclassid,mode,create_labelscnt,keep_labelscnt,arch_labelscnt,arch_delay);
1131 free(databuff);
1132 databuff=NULL;
1133 return -1;
1134 }
1135 if (mver>0x14) {
1136 if (fread(databuff,1,(create_labelscnt+keep_labelscnt+arch_labelscnt)*4*orgroup,fd)!=(size_t)((create_labelscnt+keep_labelscnt+arch_labelscnt)*4*orgroup)) {
1137 fprintf(stderr,"loading labelset: read error\n");
1138 free(databuff);
1139 databuff=NULL;
1140 return -1;
1141 }
1142 } else if (mver>0x13) {
1143 if (fread(databuff,1,(create_labelscnt+keep_labelscnt)*4*orgroup,fd)!=(size_t)((create_labelscnt+keep_labelscnt)*4*orgroup)) {
1144 fprintf(stderr,"loading labelset: read error\n");
1145 free(databuff);
1146 databuff=NULL;
1147 return -1;
1148 }
1149 } else {
1150 if (fread(databuff,1,create_labelscnt*4*orgroup,fd)!=(size_t)(create_labelscnt*4*orgroup)) {
1151 fprintf(stderr,"loading labelset: read error\n");
1152 free(databuff);
1153 databuff=NULL;
1154 return -1;
1155 }
1156 }
1157 if (chunkcount>0) {
1158 fseek(fd,chunkcount*8,SEEK_CUR);
1159 }
1160 ptr = databuff;
1161 printf("SCLASS|#:%5"PRIu16"|x:%u|m:%u|d:%5"PRIu16,sclassid,admin_only,mode,arch_delay);
1162 if (mver<=0x13) {
1163 printf("|c+k+a: ");
1164 } else {
1165 printf("|c: ");
1166 }
1167 print_labels(&ptr,create_labelscnt,orgroup);
1168 if (mver>0x13) {
1169 if (mver<=0x14) {
1170 printf(" |k+a: ");
1171 } else {
1172 printf(" |k: ");
1173 }
1174 print_labels(&ptr,keep_labelscnt,orgroup);
1175 if (mver>0x14) {
1176 printf(" |a: ");
1177 print_labels(&ptr,arch_labelscnt,orgroup);
1178 }
1179 }
1180 if (nleng>0) {
1181 printf(" |n:%s",name);
1182 }
1183 printf("\n");
1184 }
1185 free(databuff);
1186 databuff=NULL;
1187 return 0;
1188 }
1189
hexdump(FILE * fd,uint64_t sleng)1190 int hexdump(FILE *fd,uint64_t sleng) {
1191 uint8_t lbuff[32];
1192 uint32_t i;
1193 while (sleng>32) {
1194 if (fread(lbuff,1,32,fd)!=32) {
1195 return -1;
1196 }
1197 for (i=0 ; i<32 ; i++) {
1198 printf("%02"PRIX8" ",lbuff[i]);
1199 }
1200 printf(" |");
1201 for (i=0 ; i<32 ; i++) {
1202 printf("%c",dispchar(lbuff[i]));
1203 }
1204 printf("|\n");
1205 sleng-=32;
1206 }
1207 if (sleng>0) {
1208 if (fread(lbuff,1,sleng,fd)!=(size_t)sleng) {
1209 return -1;
1210 }
1211 for (i=0 ; i<32 ; i++) {
1212 if (i<sleng) {
1213 printf("%02"PRIX8" ",lbuff[i]);
1214 } else {
1215 printf(" ");
1216 }
1217 }
1218 printf(" |");
1219 for (i=0 ; i<32 ; i++) {
1220 if (i<sleng) {
1221 printf("%c",dispchar(lbuff[i]));
1222 } else {
1223 printf(" ");
1224 }
1225 }
1226 printf("|\n");
1227 }
1228 return 0;
1229 }
1230
fs_load_pre17(FILE * fd)1231 int fs_load_pre17(FILE *fd) {
1232 uint32_t maxnodeid,nextsessionid;
1233 uint64_t version;
1234 uint8_t hdr[16];
1235 const uint8_t *ptr;
1236 if (fread(hdr,1,16,fd)!=16) {
1237 return -1;
1238 }
1239 ptr = hdr;
1240 maxnodeid = get32bit(&ptr);
1241 version = get64bit(&ptr);
1242 nextsessionid = get32bit(&ptr);
1243
1244 printf("# maxnodeid: %"PRIu32" ; version: %"PRIu64" ; nextsessionid: %"PRIu32"\n",maxnodeid,version,nextsessionid);
1245
1246 printf("# -------------------------------------------------------------------\n");
1247 if (fs_loadnodes(fd,0x15,0x10)<0) {
1248 printf("error reading metadata (node)\n");
1249 return -1;
1250 }
1251 printf("# -------------------------------------------------------------------\n");
1252 if (fs_loadedges(fd,0x10)<0) {
1253 printf("error reading metadata (edge)\n");
1254 return -1;
1255 }
1256 printf("# -------------------------------------------------------------------\n");
1257 if (fs_loadfree(fd,0x10)<0) {
1258 printf("error reading metadata (free)\n");
1259 return -1;
1260 }
1261 printf("# -------------------------------------------------------------------\n");
1262 return 0;
1263 }
1264
fs_load(FILE * fd,uint8_t fver,const char section[4])1265 int fs_load(FILE *fd,uint8_t fver,const char section[4]) {
1266 uint32_t maxnodeid,nextsessionid;
1267 uint64_t sleng;
1268 off_t offbegin;
1269 uint64_t version,fileid;
1270 uint8_t hdr[16];
1271 const uint8_t *ptr;
1272 uint8_t mver;
1273 if (fread(hdr,1,16,fd)!=16) {
1274 return -1;
1275 }
1276 ptr = hdr;
1277
1278 if (fver<0x20) {
1279 maxnodeid = get32bit(&ptr);
1280 version = get64bit(&ptr);
1281 nextsessionid = get32bit(&ptr);
1282
1283 if (section[0]==0 || memcmp(section,"HEAD",4)==0) {
1284 printf("# maxnodeid: %"PRIu32" ; version: %"PRIu64" ; nextsessionid: %"PRIu32"\n",maxnodeid,version,nextsessionid);
1285 }
1286 } else {
1287 version = get64bit(&ptr);
1288 fileid = get64bit(&ptr);
1289
1290 if (section[0]==0 || memcmp(section,"HEAD",4)==0) {
1291 printf("# version: %"PRIu64" ; fileid: 0x%"PRIX64"\n",version,fileid);
1292 }
1293 }
1294
1295 while (1) {
1296 if (fread(hdr,1,16,fd)!=16) {
1297 printf("can't read section header\n");
1298 return -1;
1299 }
1300 if (memcmp(hdr,"[MFS EOF MARKER]",16)==0) {
1301 if (section[0]==0) {
1302 printf("# -------------------------------------------------------------------\n");
1303 printf("# MFS END OF FILE MARKER\n");
1304 printf("# -------------------------------------------------------------------\n");
1305 }
1306 return 0;
1307 }
1308 ptr = hdr+8;
1309 sleng = get64bit(&ptr);
1310 offbegin = ftello(fd);
1311 if (section[0]==0 || memcmp(hdr,section,4)==0) {
1312 printf("# -------------------------------------------------------------------\n");
1313 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);
1314 mver = (((hdr[5]-'0')&0xF)<<4)+(hdr[7]&0xF);
1315 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);
1316 if (memcmp(hdr,"SESS",4)==0) {
1317 if (sessions_load(fd,mver)<0) {
1318 printf("error reading metadata (SESS)\n");
1319 return -1;
1320 }
1321 } else if (memcmp(hdr,"LABS",4)==0) {
1322 if (labelset_load(fd,mver)<0) {
1323 printf("error reading metadata (LABS)\n");
1324 return -1;
1325 }
1326 } else if (memcmp(hdr,"SCLA",4)==0) {
1327 if (labelset_load(fd,mver)<0) {
1328 printf("error reading metadata (SCLA)\n");
1329 return -1;
1330 }
1331 } else if (memcmp(hdr,"NODE",4)==0) {
1332 if (fs_loadnodes(fd,fver,mver)<0) {
1333 printf("error reading metadata (NODE)\n");
1334 return -1;
1335 }
1336 } else if (memcmp(hdr,"EDGE",4)==0) {
1337 if (fs_loadedges(fd,mver)<0) {
1338 printf("error reading metadata (EDGE)\n");
1339 return -1;
1340 }
1341 } else if (memcmp(hdr,"FREE",4)==0) {
1342 if (fs_loadfree(fd,mver)<0) {
1343 printf("error reading metadata (FREE)\n");
1344 return -1;
1345 }
1346 } else if (memcmp(hdr,"QUOT",4)==0) {
1347 if (fs_loadquota(fd,mver)<0) {
1348 printf("error reading metadata (QUOT)\n");
1349 return -1;
1350 }
1351 } else if (memcmp(hdr,"XATR",4)==0) {
1352 if (xattr_load(fd,mver)<0) {
1353 printf("error reading metadata (XATR)\n");
1354 return -1;
1355 }
1356 } else if (memcmp(hdr,"PACL",4)==0) {
1357 if (posix_acl_load(fd,mver)<0) {
1358 printf("error reading metadata (PACL)\n");
1359 return -1;
1360 }
1361 } else if (memcmp(hdr,"FLCK",4)==0) {
1362 if (flock_load(fd,mver)<0) {
1363 printf("error reading metadata (FLCK)\n");
1364 return -1;
1365 }
1366 } else if (memcmp(hdr,"PLCK",4)==0) {
1367 if (posix_lock_load(fd,mver)<0) {
1368 printf("error reading metadata (PLCK)\n");
1369 return -1;
1370 }
1371 } else if (memcmp(hdr,"OPEN",4)==0) {
1372 if (of_load(fd,mver)<0) {
1373 printf("error reading metadata (OPEN)\n");
1374 return -1;
1375 }
1376 } else if (memcmp(hdr,"CSDB",4)==0) {
1377 if (csdb_load(fd,mver)<0) {
1378 printf("error reading metadata (CSDB)\n");
1379 return -1;
1380 }
1381 } else if (memcmp(hdr,"CHNK",4)==0) {
1382 if (chunk_load(fd,mver)<0) {
1383 printf("error reading metadata (CHNK)\n");
1384 return -1;
1385 }
1386 } else {
1387 printf("unknown file part\n");
1388 if (hexdump(fd,sleng)<0) {
1389 return -1;
1390 }
1391 }
1392 if ((off_t)(offbegin+sleng)!=ftello(fd)) {
1393 fprintf(stderr,"some data in this section have not been read - file corrupted\n");
1394 return -1;
1395 }
1396 } else {
1397 fseeko(fd,sleng,SEEK_CUR);
1398 }
1399 }
1400 return 0;
1401 }
1402
fs_loadall(const char * fname,const char section[4])1403 int fs_loadall(const char *fname,const char section[4]) {
1404 FILE *fd;
1405 uint8_t hdr[8];
1406 uint8_t fver;
1407
1408 fd = fopen(fname,"r");
1409
1410 if (fd==NULL) {
1411 printf("can't open metadata file\n");
1412 return -1;
1413 }
1414 if (fread(hdr,1,8,fd)!=8) {
1415 printf("can't read metadata header\n");
1416 fclose(fd);
1417 return -1;
1418 }
1419 if (memcmp(section,"HEAD",4)==0 || section[0]==0) {
1420 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]);
1421 }
1422 if (memcmp(hdr,"MFSM NEW",8)==0) {
1423 printf("empty file\n");
1424 } else if (memcmp(hdr,MFSSIGNATURE "M ",5)==0 && hdr[5]>='1' && hdr[5]<='9' && hdr[6]=='.' && hdr[7]>='0' && hdr[7]<='9') {
1425 fver = ((hdr[5]-'0')<<4)+(hdr[7]-'0');
1426 if (fver<0x17) {
1427 if (section[0]!=0) {
1428 printf("old format detected - can't dump sections separatelly");
1429 fclose(fd);
1430 return -1;
1431 }
1432 if (fs_load_pre17(fd)<0) {
1433 printf("error reading metadata (structure)\n");
1434 fclose(fd);
1435 return -1;
1436 }
1437 if (chunk_load(fd,0x10)<0) {
1438 printf("error reading metadata (chunks)\n");
1439 fclose(fd);
1440 return -1;
1441 }
1442 } else {
1443 if (fs_load(fd,fver,section)<0) {
1444 fclose(fd);
1445 return -1;
1446 }
1447 }
1448 } else {
1449 printf("wrong metadata header (old version ?)\n");
1450 fclose(fd);
1451 return -1;
1452 }
1453 if (ferror(fd)!=0) {
1454 printf("error reading metadata\n");
1455 fclose(fd);
1456 return -1;
1457 }
1458 fclose(fd);
1459 return 0;
1460 }
1461
usage(const char * appname)1462 void usage(const char *appname) {
1463 // printf("usage: %s [-f J|C[separator]] [-o outputfile] [-a sum_name] metadata.mfs PATH ...\n",appname);
1464 printf("usage: %s [-d] [-s section to dump] metadata.mfs\n",appname);
1465 printf("options:\n");
1466 printf("\td: print dot instead of non printable characters\n");
1467 printf("\ts: dump only given section\n");
1468 printf("section names:\n");
1469 printf("\tHEAD - header info\n");
1470 printf("\tSESS - client sessions\n");
1471 printf("\tLABS - labels (not used)\n");
1472 printf("\tSCLA - storage classes\n");
1473 printf("\tNODE - tree nodes (i-nodes)\n");
1474 printf("\tEDGE - tree edges (file names)\n");
1475 printf("\tFREE - free nodes (deleted i-nodes)\n");
1476 printf("\tQUOT - quota definitions\n");
1477 printf("\tXATR - xattr data\n");
1478 printf("\tPACL - posix acl data\n");
1479 printf("\tOPEN - open files\n");
1480 printf("\tFLCK - flock data\n");
1481 printf("\tPLCK - posix locks (lockf,ioctl) data\n");
1482 printf("\tCSDB - active chunkservers\n");
1483 printf("\tCHNK - chunks\n");
1484 exit(1);
1485 }
1486
main(int argc,char * argv[])1487 int main(int argc,char *argv[]) {
1488 int ch;
1489 char *appname;
1490 char section[4];
1491
1492 appname = argv[0];
1493 memset(section,0,4);
1494
1495 while ((ch=getopt(argc,argv,"s:d"))>=0) {
1496 switch(ch) {
1497 case 's':
1498 if (strlen(optarg)!=4) {
1499 printf("wrong section name\n");
1500 usage(appname);
1501 }
1502 memcpy(section,optarg,4);
1503 break;
1504 case 'd':
1505 hide_nonprintable = 1;
1506 break;
1507 default:
1508 usage(appname);
1509 return 1;
1510 }
1511 }
1512 argc -= optind;
1513 argv += optind;
1514
1515 if (argc<1) {
1516 usage(appname);
1517 return 1;
1518 }
1519
1520 // if (argc!=2) {
1521 // printf("usage: %s metadata_file\n",argv[0]);
1522 // return 1;
1523 // }
1524 return (fs_loadall(argv[0],section)<0)?1:0;
1525 }
1526