1 #include "clusterautoconfig.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <ctype.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <inttypes.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <curses.h>
15 #include <term.h>
16 #include <sys/ioctl.h>
17 #include <limits.h>
18 #include <sys/time.h>
19 #include <zlib.h>
20 #include <bzlib.h>
21 #include <time.h>
22
23 #include <logging.h>
24 #include "osi_list.h"
25 #include "gfs2hex.h"
26 #include "hexedit.h"
27 #include "libgfs2.h"
28
29 #define DFT_SAVE_FILE "/tmp/gfsmeta.XXXXXX"
30 #define MAX_JOURNALS_SAVED 256
31
32 /* Header for the savemeta output file */
33 struct savemeta_header {
34 #define SAVEMETA_MAGIC (0x01171970)
35 __be32 sh_magic;
36 #define SAVEMETA_FORMAT (1)
37 __be32 sh_format; /* In case we want to change the layout */
38 __be64 sh_time; /* When savemeta was run */
39 __be64 sh_fs_bytes; /* Size of the fs */
40 uint8_t __reserved[104];
41 };
42
43 struct savemeta {
44 time_t sm_time;
45 unsigned sm_format;
46 uint64_t sm_fs_bytes;
47 };
48
49 struct saved_metablock {
50 __be64 blk;
51 __be16 siglen; /* significant data length */
52 /* This needs to be packed because old versions of gfs2_edit read and write the
53 individual fields separately, so the hole after siglen must be eradicated
54 before the struct reflects what's on disk. */
55 } __attribute__((__packed__));
56
57 struct metafd {
58 int fd;
59 gzFile gzfd;
60 BZFILE *bzfd;
61 const char *filename;
62 int gziplevel;
63 int eof;
64 int (*read)(struct metafd *mfd, void *buf, unsigned len);
65 void (*close)(struct metafd *mfd);
66 const char* (*strerr)(struct metafd *mfd);
67 };
68
69 static char *restore_buf;
70 static ssize_t restore_left;
71 static off_t restore_off;
72 #define RESTORE_BUF_SIZE (2 * 1024 * 1024)
73
74 static char *restore_buf_next(struct metafd *mfd, size_t required_len)
75 {
76 if (restore_left < required_len) {
77 char *tail = restore_buf + restore_off;
78 int ret;
79
80 memmove(restore_buf, tail, restore_left);
81 ret = mfd->read(mfd, restore_buf + restore_left, RESTORE_BUF_SIZE - restore_left);
82 if (ret < (int)required_len - restore_left)
83 return NULL;
84 restore_left += ret;
85 restore_off = 0;
86 }
87 restore_left -= required_len;
88 restore_off += required_len;
89 return &restore_buf[restore_off - required_len];
90 }
91
92 /* gzip compression method */
93
94 static const char *gz_strerr(struct metafd *mfd)
95 {
96 int err;
97 const char *errstr = gzerror(mfd->gzfd, &err);
98
99 if (err == Z_ERRNO)
100 return strerror(errno);
101 return errstr;
102 }
103
104 static int gz_read(struct metafd *mfd, void *buf, unsigned len)
105 {
106 int ret = gzread(mfd->gzfd, buf, len);
107 if (ret < len && gzeof(mfd->gzfd))
108 mfd->eof = 1;
109 return ret;
110 }
111
112 static void gz_close(struct metafd *mfd)
113 {
114 gzclose(mfd->gzfd);
115 }
116
117 /* This should be tried last because gzip doesn't distinguish between
118 decompressing a gzip file and reading an uncompressed file */
119 static int restore_try_gzip(struct metafd *mfd)
120 {
121 mfd->read = gz_read;
122 mfd->close = gz_close;
123 mfd->strerr = gz_strerr;
124 lseek(mfd->fd, 0, SEEK_SET);
125 mfd->gzfd = gzdopen(mfd->fd, "rb");
126 if (!mfd->gzfd)
127 return 1;
128 gzbuffer(mfd->gzfd, (1<<20)); /* Increase zlib's buffers to 1MB */
129 restore_left = mfd->read(mfd, restore_buf, RESTORE_BUF_SIZE);
130 if (restore_left < 512)
131 return -1;
132 return 0;
133 }
134
135 /* bzip2 compression method */
136
137 static const char *bz_strerr(struct metafd *mfd)
138 {
139 int err;
140 const char *errstr = BZ2_bzerror(mfd->bzfd, &err);
141
142 if (err == BZ_IO_ERROR)
143 return strerror(errno);
144 return errstr;
145 }
146
147 static int bz_read(struct metafd *mfd, void *buf, unsigned len)
148 {
149 int bzerr = BZ_OK;
150 int ret;
151
152 ret = BZ2_bzRead(&bzerr, mfd->bzfd, buf, len);
153 if (bzerr == BZ_OK)
154 return ret;
155 if (bzerr == BZ_STREAM_END) {
156 mfd->eof = 1;
157 return ret;
158 }
159 return -1;
160 }
161
162 static void bz_close(struct metafd *mfd)
163 {
164 BZ2_bzclose(mfd->bzfd);
165 }
166
167 static int restore_try_bzip(struct metafd *mfd)
168 {
169 int bzerr;
170 FILE *f;
171
172 f = fdopen(mfd->fd, "r");
173 if (f == NULL)
174 return 1;
175
176 mfd->read = bz_read;
177 mfd->close = bz_close;
178 mfd->strerr = bz_strerr;
179 mfd->bzfd = BZ2_bzReadOpen(&bzerr, f, 0, 0, NULL, 0);
180 if (!mfd->bzfd)
181 return 1;
182 restore_left = mfd->read(mfd, restore_buf, RESTORE_BUF_SIZE);
183 if (restore_left < 512)
184 return -1;
185 return 0;
186 }
187
188 static uint64_t blks_saved;
189 static uint64_t journal_blocks[MAX_JOURNALS_SAVED];
190 static int journals_found = 0;
191 int print_level = MSG_NOTICE;
192
193 static int block_is_a_journal(uint64_t blk)
194 {
195 int j;
196
197 for (j = 0; j < journals_found; j++)
198 if (blk == journal_blocks[j])
199 return TRUE;
200 return FALSE;
201 }
202
203 static struct osi_root per_node_tree;
204 struct per_node_node {
205 struct osi_node node;
206 uint64_t block;
207 };
208
209 static void destroy_per_node_lookup(void)
210 {
211 struct osi_node *n;
212 struct per_node_node *pnp;
213
214 while ((n = osi_first(&per_node_tree))) {
215 pnp = (struct per_node_node *)n;
216 osi_erase(n, &per_node_tree);
217 free(pnp);
218 }
219 }
220
221 static int block_is_in_per_node(uint64_t blk)
222 {
223 struct per_node_node *pnp = (struct per_node_node *)per_node_tree.osi_node;
224
225 while (pnp) {
226 if (blk < pnp->block)
227 pnp = (struct per_node_node *)pnp->node.osi_left;
228 else if (blk > pnp->block)
229 pnp = (struct per_node_node *)pnp->node.osi_right;
230 else
231 return 1;
232 }
233
234 return 0;
235 }
236
237 static int insert_per_node_lookup(uint64_t blk)
238 {
239 struct osi_node **newn = &per_node_tree.osi_node, *parent = NULL;
240 struct per_node_node *pnp;
241
242 while (*newn) {
243 struct per_node_node *cur = (struct per_node_node *)*newn;
244
245 parent = *newn;
246 if (blk < cur->block)
247 newn = &((*newn)->osi_left);
248 else if (blk > cur->block)
249 newn = &((*newn)->osi_right);
250 else
251 return 0;
252 }
253
254 pnp = calloc(1, sizeof(struct per_node_node));
255 if (pnp == NULL) {
256 perror("Failed to insert per_node lookup entry");
257 return 1;
258 }
259 pnp->block = blk;
260 osi_link_node(&pnp->node, parent, newn);
261 osi_insert_color(&pnp->node, &per_node_tree);
262 return 0;
263 }
264
265 static int init_per_node_lookup(void)
266 {
267 int i;
268 struct lgfs2_inode *per_node_di;
269
270 per_node_di = lgfs2_inode_read(&sbd, masterblock("per_node"));
271 if (per_node_di == NULL) {
272 fprintf(stderr, "Failed to read per_node: %s\n", strerror(errno));
273 return 1;
274 }
275
276 do_dinode_extended(per_node_di->i_bh->b_data);
277 lgfs2_inode_put(&per_node_di);
278
279 for (i = 0; i < indirect_blocks; i++) {
280 int d;
281 for (d = 0; d < indirect->ii[i].dirents; d++) {
282 int ret = insert_per_node_lookup(indirect->ii[i].dirent[d].inum.in_addr);
283 if (ret != 0)
284 return ret;
285 }
286 }
287 return 0;
288 }
289
290 static int block_is_systemfile(uint64_t blk)
291 {
292 return block_is_inum_file(blk) ||
293 block_is_statfs_file(blk) ||
294 block_is_quota_file(blk) ||
295 block_is_rindex(blk) ||
296 block_is_a_journal(blk) ||
297 block_is_per_node(blk) ||
298 block_is_in_per_node(blk);
299 }
300
301 static size_t di_save_len(const char *buf, uint64_t owner)
302 {
303 const struct gfs2_dinode *dn;
304 uint16_t di_height;
305 uint32_t di_mode;
306
307 dn = (void *)buf;
308 di_mode = be32_to_cpu(dn->di_mode);
309 di_height = be16_to_cpu(dn->di_height);
310
311 /* Do not save (user) data from the inode block unless they are
312 indirect pointers, dirents, symlinks or fs internal data */
313 if (di_height > 0 || S_ISDIR(di_mode) || S_ISLNK(di_mode) ||
314 block_is_systemfile(owner))
315 return sbd.sd_bsize;
316 return sizeof(struct gfs2_dinode);
317 }
318
319 /*
320 * get_struct_info - get block type and structure length
321 *
322 * @buf - The block buffer to examine
323 * @owner - The block address of the parent structure
324 * @block_type - pointer to integer to hold the block type
325 * @gstruct_len - pointer to integer to hold the structure length
326 *
327 * returns: 0 if successful
328 * -1 if this isn't gfs2 metadata.
329 */
330 static int get_struct_info(const char *buf, uint64_t owner, unsigned *block_type,
331 unsigned *gstruct_len)
332 {
333 struct gfs2_meta_header *mh = (struct gfs2_meta_header *)buf;
334
335 if (block_type != NULL)
336 *block_type = 0;
337
338 if (gstruct_len != NULL)
339 *gstruct_len = sbd.sd_bsize;
340
341 if (be32_to_cpu(mh->mh_magic) != GFS2_MAGIC)
342 return -1;
343
344 if (block_type != NULL)
345 *block_type = be32_to_cpu(mh->mh_type);
346
347 if (gstruct_len == NULL)
348 return 0;
349
350 switch (be32_to_cpu(mh->mh_type)) {
351 case GFS2_METATYPE_SB: /* 1 (superblock) */
352 *gstruct_len = sizeof(struct gfs2_sb);
353 break;
354 case GFS2_METATYPE_RG: /* 2 (rsrc grp hdr) */
355 *gstruct_len = sbd.sd_bsize; /*sizeof(struct gfs_rgrp);*/
356 break;
357 case GFS2_METATYPE_RB: /* 3 (rsrc grp bitblk) */
358 *gstruct_len = sbd.sd_bsize;
359 break;
360 case GFS2_METATYPE_DI: /* 4 (disk inode) */
361 *gstruct_len = di_save_len(buf, owner);
362 break;
363 case GFS2_METATYPE_IN: /* 5 (indir inode blklst) */
364 *gstruct_len = sbd.sd_bsize; /*sizeof(struct gfs_indirect);*/
365 break;
366 case GFS2_METATYPE_LF: /* 6 (leaf dinode blklst) */
367 *gstruct_len = sbd.sd_bsize; /*sizeof(struct gfs_leaf);*/
368 break;
369 case GFS2_METATYPE_JD: /* 7 (journal data) */
370 *gstruct_len = sbd.sd_bsize;
371 break;
372 case GFS2_METATYPE_LH: /* 8 (log header) */
373 *gstruct_len = sizeof(struct gfs2_log_header);
374 break;
375 case GFS2_METATYPE_LD: /* 9 (log descriptor) */
376 *gstruct_len = sbd.sd_bsize;
377 break;
378 case GFS2_METATYPE_EA: /* 10 (extended attr hdr) */
379 *gstruct_len = sbd.sd_bsize;
380 break;
381 case GFS2_METATYPE_ED: /* 11 (extended attr data) */
382 *gstruct_len = sbd.sd_bsize;
383 break;
384 default:
385 *gstruct_len = sbd.sd_bsize;
386 break;
387 }
388 return 0;
389 }
390
391 /**
392 * Print a progress message if one second has elapsed since the last time.
393 * pblock: The latest block number processed
394 * force: If this is non-zero, print immediately and add a newline after the
395 * progress message.
396 */
397 static void report_progress(uint64_t pblock, int force)
398 {
399 static struct timeval tv;
400 static uint32_t seconds = 0;
401
402 gettimeofday(&tv, NULL);
403 if (!seconds)
404 seconds = tv.tv_sec;
405 if (force || tv.tv_sec - seconds) {
406 static uint64_t percent;
407
408 seconds = tv.tv_sec;
409 if (sbd.fssize) {
410 printf("\r");
411 percent = (pblock * 100) / sbd.fssize;
412 printf("%"PRIu64" blocks saved (%"PRIu64"%% complete)",
413 blks_saved, percent);
414 if (force)
415 printf("\n");
416 fflush(stdout);
417 }
418 }
419 }
420
421 /**
422 * Open a file and prepare it for writing by savemeta()
423 * out_fn: the path to the file, which will be truncated if it exists
424 * gziplevel: 0 - do not compress the file,
425 * 1-9 - use gzip compression level 1-9
426 * Returns a struct metafd containing the opened file descriptor
427 */
428 static struct metafd savemetaopen(char *out_fn, int gziplevel)
429 {
430 struct metafd mfd = {0};
431 char gzmode[3] = "w9";
432 char dft_fn[] = DFT_SAVE_FILE;
433 mode_t mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
434 struct stat st;
435
436 mfd.gziplevel = gziplevel;
437
438 if (!out_fn) {
439 out_fn = dft_fn;
440 mfd.fd = mkstemp(out_fn);
441 } else {
442 mfd.fd = open(out_fn, O_RDWR | O_CREAT, 0644);
443 }
444 umask(mask);
445 mfd.filename = out_fn;
446
447 if (mfd.fd < 0) {
448 fprintf(stderr, "Can't open %s: %s\n", out_fn, strerror(errno));
449 exit(1);
450 }
451 if (fstat(mfd.fd, &st) == -1) {
452 fprintf(stderr, "Failed to stat %s: %s\n", out_fn, strerror(errno));
453 exit(1);
454 }
455 if (S_ISREG(st.st_mode) && ftruncate(mfd.fd, 0)) {
456 fprintf(stderr, "Can't truncate %s: %s\n", out_fn, strerror(errno));
457 exit(1);
458 }
459
460 if (gziplevel > 0) {
461 gzmode[1] = '0' + gziplevel;
462 mfd.gzfd = gzdopen(mfd.fd, gzmode);
463 if (!mfd.gzfd) {
464 fprintf(stderr, "gzdopen error: %s\n", strerror(errno));
465 exit(1);
466 }
467 gzbuffer(mfd.gzfd, (1<<20)); /* Increase zlib's buffers to 1MB */
468 }
469
470 return mfd;
471 }
472
473 /**
474 * Write nbyte bytes from buf to a file opened with savemetaopen()
475 * mfd: the file descriptor opened using savemetaopen()
476 * buf: the buffer to write data from
477 * nbyte: the number of bytes to write
478 * Returns the number of bytes written from buf or -1 on error
479 */
480 static ssize_t savemetawrite(struct metafd *mfd, const void *buf, size_t nbyte)
481 {
482 ssize_t ret;
483 int gzerr;
484 const char *gzerrmsg;
485
486 if (mfd->gziplevel == 0) {
487 return write(mfd->fd, buf, nbyte);
488 }
489
490 ret = gzwrite(mfd->gzfd, buf, nbyte);
491 if (ret != nbyte) {
492 gzerrmsg = gzerror(mfd->gzfd, &gzerr);
493 if (gzerr != Z_ERRNO) {
494 fprintf(stderr, "Error: zlib: %s\n", gzerrmsg);
495 }
496 }
497 return ret;
498 }
499
500 /**
501 * Closes a file descriptor previously opened using savemetaopen()
502 * mfd: the file descriptor previously opened using savemetaopen()
503 * Returns 0 on success or -1 on error
504 */
505 static int savemetaclose(struct metafd *mfd)
506 {
507 int gzret;
508 if (mfd->gziplevel > 0) {
509 gzret = gzclose(mfd->gzfd);
510 if (gzret == Z_STREAM_ERROR) {
511 fprintf(stderr, "gzclose: file is not valid\n");
512 return -1;
513 } else if (gzret == Z_ERRNO) {
514 return -1;
515 }
516 }
517 return close(mfd->fd);
518 }
519
520 static int save_buf(struct metafd *mfd, const char *buf, uint64_t addr, unsigned blklen)
521 {
522 struct saved_metablock *savedata;
523 size_t outsz;
524
525 /* No need to save trailing zeroes, but leave that for compression to
526 deal with when enabled as this adds a significant overhead */
527 if (mfd->gziplevel == 0)
528 for (; blklen > 0 && buf[blklen - 1] == '\0'; blklen--);
529
530 if (blklen == 0) /* No significant data; skip. */
531 return 0;
532
533 outsz = sizeof(*savedata) + blklen;
534 savedata = calloc(1, outsz);
535 if (savedata == NULL) {
536 perror("Failed to save block");
537 exit(1);
538 }
539 savedata->blk = cpu_to_be64(addr);
540 savedata->siglen = cpu_to_be16(blklen);
541 memcpy(savedata + 1, buf, blklen);
542
543 if (savemetawrite(mfd, savedata, outsz) != outsz) {
544 fprintf(stderr, "write error: %s from %s:%d: block %"PRIu64"\n",
545 strerror(errno), __FUNCTION__, __LINE__, addr);
546 free(savedata);
547 exit(-1);
548 }
549 blks_saved++;
550 free(savedata);
551 return 0;
552 }
553
554 struct block_range {
555 struct block_range *next;
556 uint64_t start;
557 unsigned len;
558 unsigned *blktype;
559 unsigned *blklen;
560 char *buf;
561 };
562
563 static int block_range_prepare(struct block_range *br)
564 {
565 br->buf = calloc(br->len, sbd.sd_bsize + sizeof(*br->blktype) + sizeof(*br->blklen));
566 if (br->buf == NULL) {
567 perror("Failed to allocate block range buffer");
568 return 1;
569 }
570 br->blktype = (unsigned *)(br->buf + (br->len * sbd.sd_bsize));
571 br->blklen = br->blktype + br->len;
572 return 0;
573 }
574
575 static int block_range_check(struct block_range *br)
576 {
577 if (br->start >= LGFS2_SB_ADDR(&sbd) && br->start + br->len <= sbd.fssize)
578 return 0;
579
580 fprintf(stderr, "Warning: bad range 0x%"PRIx64" (%u blocks) ignored.\n",
581 br->start, br->len);
582 free(br->buf);
583 br->buf = NULL;
584 return 1;
585 }
586
587 static void block_range_setinfo(struct block_range *br, uint64_t owner)
588 {
589 for (unsigned i = 0; i < br->len; i++) {
590 char *buf = br->buf + (i * sbd.sd_bsize);
591 uint64_t addr = br->start + i;
592 uint64_t _owner = (owner == 0) ? addr : owner;
593
594 if (get_struct_info(buf, _owner, br->blktype + i, br->blklen + i) &&
595 !block_is_systemfile(_owner)) {
596 br->blklen[i] = 0;
597 }
598 }
599 }
600
601 static void block_range_free(struct block_range **brp)
602 {
603 free((*brp)->buf);
604 free(*brp);
605 *brp = NULL;
606 }
607
608 struct block_range_queue {
609 struct block_range *tail;
610 struct block_range **head;
611 };
612
613 static void block_range_queue_init(struct block_range_queue *q)
614 {
615 q->head = &q->tail;
616 }
617
618 static void block_range_queue_insert(struct block_range_queue *q, struct block_range *br)
619 {
620 *q->head = br;
621 q->head = &br->next;
622 }
623
624 static struct block_range *block_range_queue_pop(struct block_range_queue *q)
625 {
626 struct block_range *br = q->tail;
627
628 q->tail = br->next;
629 br->next = NULL;
630 return br;
631 }
632
633 static int save_range(struct metafd *mfd, struct block_range *br)
634 {
635 for (unsigned i = 0; i < br->len; i++) {
636 int err;
637
638 err = save_buf(mfd, br->buf + (i * sbd.sd_bsize), br->start + i, br->blklen[i]);
639 if (err != 0)
640 return err;
641 }
642 return 0;
643 }
644
645 static int check_read_range(int fd, struct block_range *br, uint64_t owner)
646 {
647 size_t size;
648
|
(1) Event cond_false: |
Condition "block_range_prepare(br) != 0", taking false branch. |
649 if (block_range_prepare(br) != 0)
|
(2) Event if_end: |
End of if statement. |
650 return 1;
651
|
(3) Event cond_false: |
Condition "block_range_check(br) != 0", taking false branch. |
652 if (block_range_check(br) != 0)
|
(4) Event if_end: |
End of if statement. |
653 return 1;
654
655 size = br->len * sbd.sd_bsize;
|
(5) Event tainted_data_argument: |
Calling function "pread" taints parameter "*br->buf". [Note: The source code implementation of the function has been overridden by a builtin model.] |
|
(6) Event cond_false: |
Condition "pread(sbd.device_fd, br->buf, size, sbd.sd_bsize * br->start) != size", taking false branch. |
656 if (pread(sbd.device_fd, br->buf, size, sbd.sd_bsize * br->start) != size) {
657 fprintf(stderr, "Failed to read block range 0x%"PRIx64" (%u blocks): %s\n",
658 br->start, br->len, strerror(errno));
659 free(br->buf);
660 br->buf = NULL;
661 return 1;
|
(7) Event if_end: |
End of if statement. |
662 }
663 block_range_setinfo(br, owner);
664 return 0;
665 }
666
667 static char *check_read_block(int fd, uint64_t blk, uint64_t owner, int *blktype, size_t *blklen)
668 {
669 struct block_range br = {
670 .start = blk,
671 .len = 1
672 };
673
|
(1) Event tainted_data_argument: |
Calling function "check_read_range" taints parameter "*br.buf". [details] |
|
(2) Event cond_false: |
Condition "check_read_range(fd, &br, owner) != 0", taking false branch. |
| Also see events: |
[return_tainted_data] |
674 if (check_read_range(fd, &br, owner) != 0)
|
(3) Event if_end: |
End of if statement. |
675 return NULL;
|
(4) Event cond_true: |
Condition "blklen != NULL", taking true branch. |
676 if (blklen != NULL)
677 *blklen = *br.blklen;
|
(5) Event cond_true: |
Condition "blktype != NULL", taking true branch. |
678 if (blktype != NULL)
679 *blktype = *br.blktype;
680 return br.buf;
681 }
682
683 /*
684 * save_ea_block - save off an extended attribute block
685 */
686 static void save_ea_block(struct metafd *mfd, char *buf, uint64_t owner)
687 {
688 struct gfs2_ea_header *ea;
689 uint32_t rec_len = 0;
690 int e;
691
|
(1) Event cond_true: |
Condition "e < sbd.sd_bsize", taking true branch. |
692 for (e = sizeof(struct gfs2_meta_header); e < sbd.sd_bsize; e += rec_len) {
693 uint64_t blk;
694 int charoff, i;
695 __be64 *b;
696
697 ea = (void *)(buf + e);
698 /* ea_num_ptrs and ea_name_len are u8 so no endianness worries */
|
(3) Event lower_bounds: |
Casting narrower unsigned "ea->ea_num_ptrs" to wider signed type "int" effectively tests its lower bound. |
|
(4) Event loop_bound_upper: |
Using tainted expression "ea->ea_num_ptrs" as a loop boundary. |
| Also see events: |
[var_assign_alias] |
699 for (i = 0; i < ea->ea_num_ptrs; i++) {
700 char *_buf;
701
702 charoff = e + ea->ea_name_len +
703 sizeof(struct gfs2_ea_header) +
704 sizeof(uint64_t) - 1;
705 charoff /= sizeof(uint64_t);
706 b = (__be64 *)buf;
707 b += charoff + i;
708 blk = be64_to_cpu(*b);
709 _buf = check_read_block(sbd.device_fd, blk, owner, NULL, NULL);
710 if (_buf != NULL) {
711 save_buf(mfd, _buf, blk, sbd.sd_bsize);
712 free(_buf);
713 }
714 }
715 rec_len = be32_to_cpu(ea->ea_rec_len);
716 if (rec_len == 0)
717 break;
718 }
719 }
720
721 static void save_indirect_range(struct metafd *mfd, struct block_range **brp, uint64_t owner,
722 struct block_range_queue *q)
723 {
724 struct block_range *br = *brp;
725
726 if (check_read_range(sbd.device_fd, br, owner) != 0)
727 return;
728
729 save_range(mfd, br);
730 for (unsigned i = 0; i < br->len; i++) {
731 if (br->blktype[i] == GFS2_METATYPE_EA)
732 save_ea_block(mfd, br->buf + (i * sbd.sd_bsize), owner);
733 }
734 if (q) {
735 block_range_queue_insert(q, br);
736 *brp = NULL; /* The list now has ownership of it */
737 } else {
738 free(br->buf);
739 br->buf = NULL;
740 }
741 }
742
743 static void save_indirect_blocks(struct metafd *mfd, char *buf, uint64_t owner,
744 struct block_range_queue *q, unsigned headsize)
745 {
746 uint64_t old_block = 0, indir_block;
747 struct block_range *br = NULL;
748 __be64 *ptr;
749
750 for (ptr = (__be64 *)(buf + headsize);
751 (char *)ptr < (buf + sbd.sd_bsize); ptr++) {
752 if (!*ptr)
753 continue;
754
755 indir_block = be64_to_cpu(*ptr);
756 if (indir_block == old_block)
757 continue;
758 old_block = indir_block;
759
760 if (br == NULL) {
761 new_range:
762 br = calloc(1, sizeof(*br));
763 if (br == NULL) {
764 perror("Failed to save indirect blocks");
765 return;
766 }
767 br->start = indir_block;
768 br->len = 1;
769 } else if (indir_block == br->start + br->len) {
770 br->len++;
771 } else {
772 save_indirect_range(mfd, &br, owner, q);
773 if (br == NULL) /* This one was queued up for later */
774 goto new_range;
775 br->start = indir_block;
776 br->len = 1;
777 }
778 }
779 if (br != NULL && br->start != 0)
780 save_indirect_range(mfd, &br, owner, q);
781 free(br);
782 }
783
784 static int save_leaf_chain(struct metafd *mfd, struct lgfs2_sbd *sdp, char *buf)
785 {
786 struct gfs2_leaf *leaf = (struct gfs2_leaf *)buf;
787
788 while (leaf->lf_next != 0) {
789 uint64_t blk = be64_to_cpu(leaf->lf_next);
790 ssize_t r;
791
792 if (lgfs2_check_range(sdp, blk) != 0)
793 return 0;
794
795 r = pread(sdp->device_fd, buf, sdp->sd_bsize, sdp->sd_bsize * blk);
796 if (r != sdp->sd_bsize) {
797 fprintf(stderr, "Failed to read leaf block %"PRIx64": %s\n",
798 blk, strerror(errno));
799 return 1;
800 }
801 report_progress(blk, 0);
802 if (lgfs2_check_meta(buf, GFS2_METATYPE_LF) == 0) {
803 int ret = save_buf(mfd, buf, blk, sdp->sd_bsize);
804 if (ret != 0)
805 return ret;
806 }
807 leaf = (struct gfs2_leaf *)buf;
808 }
809 return 0;
810 }
811
812 static void save_leaf_blocks(struct metafd *mfd, struct block_range_queue *q)
813 {
814 while (q->tail != NULL) {
815 struct block_range *br = q->tail;
816
817 for (unsigned i = 0; i < br->len; i++) {
818 char *buf = br->buf + (i * sbd.sd_bsize);
819
820 save_leaf_chain(mfd, &sbd, buf);
821 }
822 q->tail = br->next;
823 block_range_free(&br);
824 }
825 }
826
827 /*
828 * save_inode_data - save off important data associated with an inode
829 *
830 * mfd - destination file descriptor
831 * buf - buffer containing the inode block
832 * iblk - block number of the inode to save the data for
833 *
834 * For user files, we don't want anything except all the indirect block
835 * pointers that reside on blocks on all but the highest height.
836 *
837 * For system files like statfs and inum, we want everything because they
838 * may contain important clues and no user data.
839 *
840 * For file system journals, the "data" is a mixture of metadata and
841 * journaled data. We want all the metadata and none of the user data.
842 */
843 static void save_inode_data(struct metafd *mfd, char *ibuf, uint64_t iblk)
844 {
845 struct block_range_queue indq[GFS2_MAX_META_HEIGHT] = {{NULL}};
846 struct gfs2_dinode *dip = (struct gfs2_dinode *)ibuf;
847 uint16_t height;
848 int is_exhash;
849
|
(1) Event cond_true: |
Condition "i < 10", taking true branch. |
|
(3) Event loop_begin: |
Jumped back to beginning of loop. |
|
(4) Event cond_true: |
Condition "i < 10", taking true branch. |
|
(6) Event loop_begin: |
Jumped back to beginning of loop. |
|
(7) Event cond_false: |
Condition "i < 10", taking false branch. |
850 for (unsigned i = 0; i < GFS2_MAX_META_HEIGHT; i++)
|
(2) Event loop: |
Jumping back to the beginning of the loop. |
|
(5) Event loop: |
Jumping back to the beginning of the loop. |
|
(8) Event loop_end: |
Reached end of loop. |
851 block_range_queue_init(&indq[i]);
852
853 height = be16_to_cpu(dip->di_height);
854
855 /* If this is a user inode, we don't follow to the file height.
856 We stop one level less. That way we save off the indirect
857 pointer blocks but not the actual file contents. The exception
858 is directories, where the height represents the level at which
859 the hash table exists, and we have to save the directory data. */
860
|
(9) Event cond_true: |
Condition "(__bswap_32((uint32_t)(__be32)dip->di_mode) & 61440) == 16384", taking true branch. |
|
(10) Event cond_true: |
Condition "__bswap_32((uint32_t)(__be32)dip->di_flags) & 2", taking true branch. |
861 is_exhash = S_ISDIR(be32_to_cpu(dip->di_mode)) &&
862 be32_to_cpu(dip->di_flags) & GFS2_DIF_EXHASH;
|
(11) Event cond_true: |
Condition "is_exhash", taking true branch. |
863 if (is_exhash)
|
(12) Event if_fallthrough: |
Falling through to end of if statement. |
864 height++;
865 else if (height > 0 && !(be32_to_cpu(dip->di_flags) & GFS2_DIF_SYSTEM) &&
866 !block_is_systemfile(iblk) && !S_ISDIR(be32_to_cpu(dip->di_mode)))
|
(13) Event if_end: |
End of if statement. |
867 height--;
868
|
(14) Event cond_true: |
Condition "height == 1", taking true branch. |
869 if (height == 1)
|
(15) Event if_fallthrough: |
Falling through to end of if statement. |
870 save_indirect_blocks(mfd, ibuf, iblk, NULL, sizeof(*dip));
871 else if (height > 1)
|
(16) Event if_end: |
End of if statement. |
872 save_indirect_blocks(mfd, ibuf, iblk, &indq[0], sizeof(*dip));
873
|
(17) Event cond_false: |
Condition "i < height", taking false branch. |
874 for (unsigned i = 1; i < height; i++) {
875 struct block_range_queue *nextq = &indq[i];
876
877 if (!is_exhash && i == height - 1)
878 nextq = NULL;
879
880 /* Coverity can't figure out that the tail becomes NULL eventually. */
881 /* coverity[loop_top:SUPPRESS] */
882 while (indq[i - 1].tail != NULL) {
883 struct block_range *q = block_range_queue_pop(&indq[i - 1]);
884
885 for (unsigned j = 0; j < q->len; j++) {
886 char *_buf = q->buf + (j * sbd.sd_bsize);
887
888 save_indirect_blocks(mfd, _buf, iblk, nextq, sizeof(dip->di_header));
889 }
890 report_progress(q->start + q->len, 0);
891 block_range_free(&q);
892 }
|
(18) Event loop_end: |
Reached end of loop. |
893 }
|
(19) Event cond_true: |
Condition "is_exhash", taking true branch. |
894 if (is_exhash)
895 save_leaf_blocks(mfd, &indq[height - 1]);
|
(20) Event cond_true: |
Condition "dip->di_eattr", taking true branch. |
896 if (dip->di_eattr) { /* if this inode has extended attributes */
897 size_t blklen;
898 uint64_t blk;
899 int mhtype;
900 char *buf;
901
902 blk = be64_to_cpu(dip->di_eattr);
|
(21) Event tainted_return_value: |
Function "check_read_block" returns tainted data. [details] |
|
(22) Event var_assign: |
Assigning: "buf" = "check_read_block(sbd.device_fd, blk, iblk, &mhtype, &blklen)", which taints "buf". |
| Also see events: |
[tainted_data][remediation] |
903 buf = check_read_block(sbd.device_fd, blk, iblk, &mhtype, &blklen);
|
(23) Event cond_true: |
Condition "buf != NULL", taking true branch. |
904 if (buf != NULL) {
905 save_buf(mfd, buf, blk, blklen);
|
(24) Event cond_true: |
Condition "mhtype == 10", taking true branch. |
906 if (mhtype == GFS2_METATYPE_EA)
|
(25) Event tainted_data: |
Passing tainted expression "*buf" to "save_ea_block", which uses it as a loop boundary. [details] |
|
(26) Event remediation: |
Ensure that tainted values are properly sanitized, by checking that their values are within a permissible range. |
| Also see events: |
[tainted_return_value][var_assign] |
907 save_ea_block(mfd, buf, iblk);
908 else if (mhtype == GFS2_METATYPE_IN)
909 save_indirect_blocks(mfd, buf, iblk, NULL, sizeof(dip->di_header));
910 free(buf);
911 }
912 }
913 }
914
915 static void get_journal_inode_blocks(void)
916 {
917 int journal;
918
919 journals_found = 0;
920 memset(journal_blocks, 0, sizeof(journal_blocks));
921 /* Save off all the journals--but only the metadata.
922 * This is confusing so I'll explain. The journals contain important
923 * metadata. However, in gfs2 the journals are regular files within
924 * the system directory. Since they're regular files, the blocks
925 * within the journals are considered data, not metadata. Therefore,
926 * they won't have been saved by the code above. We want to dump
927 * these blocks, but we have to be careful. We only care about the
928 * journal blocks that look like metadata, and we need to not save
929 * journaled user data that may exist there as well. */
930 for (journal = 0; ; journal++) { /* while journals exist */
931 uint64_t jblock;
932
933 if (journal + 3 > indirect->ii[0].dirents)
934 break;
935 jblock = indirect->ii[0].dirent[journal + 2].inum.in_addr;
936 journal_blocks[journals_found++] = jblock;
937 }
938 }
939
940 static void save_allocated_range(struct metafd *mfd, struct block_range *br)
941 {
942 if (check_read_range(sbd.device_fd, br, 0) != 0)
943 return;
944
945 save_range(mfd, br);
946 for (unsigned i = 0; i < br->len; i++) {
947 char *buf = br->buf + (i * sbd.sd_bsize);
948
949 if (br->blktype[i] == GFS2_METATYPE_DI)
950 save_inode_data(mfd, buf, br->start + i);
951 }
952 free(br->buf);
953 }
954
955 static int uint64_cmp(const void *_a, const void *_b)
956 {
957 const uint64_t a = *(uint64_t *)_a, b = *(uint64_t *)_b;
958
959 return (a < b) ? -1 : ((a > b) ? 1 : 0);
960 }
961
962 static void save_allocated(struct lgfs2_rgrp_tree *rgd, struct metafd *mfd)
963 {
964 uint64_t blk = 0;
965 unsigned i, j, m, n;
966 uint64_t *ibuf = malloc(sbd.sd_bsize * GFS2_NBBY * sizeof(uint64_t));
967
968 for (i = 0; i < rgd->rt_length; i++) {
969 struct block_range br = {0};
970
971 /* Dump linked as well as unlinked inodes. */
972 m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE);
973 n = lgfs2_bm_scan(rgd, i, ibuf + m, GFS2_BLKST_UNLINKED);
974 if (m && n)
975 qsort(ibuf, m + n, sizeof(*ibuf), uint64_cmp);
976
977 for (j = 0; j < m + n; j++) {
978 blk = ibuf[j];
979 if (br.start == 0) {
980 br.start = blk;
981 br.len = 1;
982 } else if (blk == br.start + br.len) {
983 br.len++;
984 } else {
985 save_allocated_range(mfd, &br);
986 br.start = blk;
987 br.len = 1;
988 }
989 report_progress(blk, 0);
990 }
991 if (br.start != 0)
992 save_allocated_range(mfd, &br);
993 }
994 free(ibuf);
995 }
996
997 static char *rgrp_read(struct lgfs2_sbd *sdp, uint64_t addr, unsigned blocks)
998 {
999 size_t len = blocks * sdp->sd_bsize;
1000 off_t off = addr * sdp->sd_bsize;
1001 char *buf;
1002
1003 if (blocks == 0 || lgfs2_check_range(sdp, addr))
1004 return NULL;
1005
1006 buf = calloc(1, len);
1007 if (buf == NULL)
1008 return NULL;
1009
1010 if (pread(sdp->device_fd, buf, len, off) != len) {
1011 free(buf);
1012 return NULL;
1013 }
1014 return buf;
1015 }
1016
1017 static void save_rgrp(struct lgfs2_sbd *sdp, struct metafd *mfd, struct lgfs2_rgrp_tree *rgd, int withcontents)
1018 {
1019 uint64_t addr = rgd->rt_addr;
1020 char *buf;
1021
1022 buf = rgrp_read(sdp, rgd->rt_addr, rgd->rt_length);
1023 if (buf == NULL)
1024 return;
1025
1026 for (unsigned i = 0; i < rgd->rt_length; i++)
1027 rgd->rt_bits[i].bi_data = buf + (i * sdp->sd_bsize);
1028
1029 log_debug("RG at %"PRIu64" is %"PRIu32" long\n", addr, rgd->rt_length);
1030 /* Save the rg and bitmaps */
1031 for (unsigned i = 0; i < rgd->rt_length; i++) {
1032 report_progress(rgd->rt_addr + i, 0);
1033 save_buf(mfd, buf + (i * sdp->sd_bsize), rgd->rt_addr + i, sdp->sd_bsize);
1034 }
1035 /* Save the other metadata: inodes, etc. if mode is not 'savergs' */
1036 if (withcontents)
1037 save_allocated(rgd, mfd);
1038
1039 free(buf);
1040 for (unsigned i = 0; i < rgd->rt_length; i++)
1041 rgd->rt_bits[i].bi_data = NULL;
1042 }
1043
1044 static int save_header(struct metafd *mfd, uint64_t fsbytes)
1045 {
1046 struct savemeta_header smh = {
1047 .sh_magic = cpu_to_be32(SAVEMETA_MAGIC),
1048 .sh_format = cpu_to_be32(SAVEMETA_FORMAT),
1049 .sh_time = cpu_to_be64(time(NULL)),
1050 .sh_fs_bytes = cpu_to_be64(fsbytes)
1051 };
1052
1053 if (savemetawrite(mfd, (char *)(&smh), sizeof(smh)) != sizeof(smh))
1054 return -1;
1055 return 0;
1056 }
1057
1058 static int parse_header(char *buf, struct savemeta *sm)
1059 {
1060 struct savemeta_header *smh = (void *)buf;
1061
1062 if (be32_to_cpu(smh->sh_magic) != SAVEMETA_MAGIC) {
1063 printf("No valid file header found. Falling back to old format...\n");
1064 return 1;
1065 }
1066 if (be32_to_cpu(smh->sh_format) > SAVEMETA_FORMAT) {
1067 printf("This version of gfs2_edit is too old to restore this metadata format.\n");
1068 return -1;
1069 }
1070 sm->sm_format = be32_to_cpu(smh->sh_format);
1071 sm->sm_time = be64_to_cpu(smh->sh_time);
1072 sm->sm_fs_bytes = be64_to_cpu(smh->sh_fs_bytes);
1073 printf("Metadata saved at %s", ctime(&sm->sm_time)); /* ctime() adds \n */
1074 printf("File system size %.2fGB\n", sm->sm_fs_bytes / ((float)(1 << 30)));
1075 return 0;
1076 }
1077
1078 void savemeta(char *out_fn, int saveoption, int gziplevel)
1079 {
1080 struct metafd mfd;
1081 struct osi_node *n;
1082 uint64_t sb_addr;
1083 int err = 0;
1084 char *buf;
1085
1086 sbd.md.journals = 1;
1087
1088 mfd = savemetaopen(out_fn, gziplevel);
1089
1090 blks_saved = 0;
1091 printf("There are %"PRIu64" blocks of %u bytes in the filesystem.\n",
1092 sbd.fssize, sbd.sd_bsize);
1093
1094 printf("Filesystem size: %.2fGB\n", (sbd.fssize * sbd.sd_bsize) / ((float)(1 << 30)));
1095 get_journal_inode_blocks();
1096
1097 err = init_per_node_lookup();
1098 if (err)
1099 exit(1);
1100
1101 /* Write the savemeta file header */
1102 err = save_header(&mfd, sbd.fssize * sbd.sd_bsize);
1103 if (err) {
1104 perror("Failed to write metadata file header");
1105 exit(1);
1106 }
1107 /* Save off the superblock */
1108 sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sbd.sd_bsize;
1109 buf = check_read_block(sbd.device_fd, sb_addr, 0, NULL, NULL);
1110 if (buf != NULL) {
1111 save_buf(&mfd, buf, sb_addr, sizeof(struct gfs2_sb));
1112 free(buf);
1113 }
1114 /* Walk through the resource groups saving everything within */
1115 for (n = osi_first(&sbd.rgtree); n; n = osi_next(n)) {
1116 struct lgfs2_rgrp_tree *rgd;
1117
1118 rgd = (struct lgfs2_rgrp_tree *)n;
1119 save_rgrp(&sbd, &mfd, rgd, (saveoption != 2));
1120 }
1121 /* Clean up */
1122 /* There may be a gap between end of file system and end of device */
1123 /* so we tell the user that we've processed everything. */
1124 report_progress(sbd.fssize, 1);
1125 printf("\nMetadata saved to file %s ", mfd.filename);
1126 if (mfd.gziplevel) {
1127 printf("(gzipped, level %d).\n", mfd.gziplevel);
1128 } else {
1129 printf("(uncompressed).\n");
1130 }
1131 savemetaclose(&mfd);
1132 close(sbd.device_fd);
1133 destroy_per_node_lookup();
1134 free(indirect);
1135 lgfs2_rgrp_free(&sbd, &sbd.rgtree);
1136 exit(0);
1137 }
1138
1139 static char *restore_block(struct metafd *mfd, uint64_t *blk, uint16_t *siglen)
1140 {
1141 struct saved_metablock *svb;
1142 const char *errstr;
1143 char *buf = NULL;
1144
1145 svb = (struct saved_metablock *)(restore_buf_next(mfd, sizeof(*svb)));
1146 if (svb == NULL)
1147 goto nobuffer;
1148 *blk = be64_to_cpu(svb->blk);
1149 *siglen = be16_to_cpu(svb->siglen);
1150
1151 if (sbd.fssize && *blk >= sbd.fssize) {
1152 fprintf(stderr, "Error: File system is too small to restore this metadata.\n");
1153 fprintf(stderr, "File system is %"PRIu64" blocks. Restore block = %"PRIu64"\n",
1154 sbd.fssize, *blk);
1155 return NULL;
1156 }
1157
1158 if (*siglen > sbd.sd_bsize) {
1159 fprintf(stderr, "Bad record length: %u for block %"PRIu64" (0x%"PRIx64").\n",
1160 *siglen, *blk, *blk);
1161 return NULL;
1162 }
1163
1164 buf = restore_buf_next(mfd, *siglen);
1165 if (buf != NULL) {
1166 return buf;
1167 }
1168 nobuffer:
1169 if (mfd->eof)
1170 return NULL;
1171
1172 errstr = mfd->strerr(mfd);
1173 fprintf(stderr, "Failed to restore block: %s\n", errstr);
1174 return NULL;
1175 }
1176
1177 static int restore_super(struct metafd *mfd, void *buf, int printonly)
1178 {
1179 int ret;
1180
1181 lgfs2_sb_in(&sbd, buf);
1182 ret = lgfs2_check_sb(buf);
1183 if (ret < 0) {
1184 fprintf(stderr, "Error: Invalid superblock in metadata file.\n");
1185 return -1;
1186 }
1187 if ((!printonly) && lgfs2_sb_write(&sbd, sbd.device_fd)) {
1188 fprintf(stderr, "Failed to write superblock\n");
1189 return -1;
1190 }
1191 blks_saved++;
1192 return 0;
1193 }
1194
1195 static int restore_data(int fd, struct metafd *mfd, int printonly)
1196 {
1197 uint64_t writes = 0;
1198 char *buf;
1199
1200 buf = calloc(1, sbd.sd_bsize);
1201 if (buf == NULL) {
1202 perror("Failed to restore data");
1203 exit(1);
1204 }
1205
1206 while (TRUE) {
1207 uint16_t siglen = 0;
1208 uint64_t blk = 0;
1209 char *bp;
1210
1211 bp = restore_block(mfd, &blk, &siglen);
1212 if (bp == NULL && mfd->eof)
1213 break;
1214 if (bp == NULL) {
1215 free(buf);
1216 return -1;
1217 }
1218 if (printonly) {
1219 if (printonly > 1 && printonly == blk) {
1220 display_block_type(bp, blk, TRUE);
1221 display_gfs2(bp);
1222 break;
1223 } else if (printonly == 1) {
1224 print_gfs2("%"PRId64" (l=0x%x): ", blks_saved, siglen);
1225 display_block_type(bp, blk, TRUE);
1226 }
1227 } else {
1228 report_progress(blk, 0);
1229 memcpy(buf, bp, siglen);
1230 memset(buf + siglen, 0, sbd.sd_bsize - siglen);
1231 if (pwrite(fd, buf, sbd.sd_bsize, blk * sbd.sd_bsize) != sbd.sd_bsize) {
1232 fprintf(stderr, "write error: %s from %s:%d: block %"PRIu64" (0x%"PRIx64")\n",
1233 strerror(errno), __FUNCTION__, __LINE__, blk, blk);
1234 free(buf);
1235 return -1;
1236 }
1237 writes++;
1238 if (writes % 1000 == 0)
1239 fsync(fd);
1240 }
1241 blks_saved++;
1242 }
1243 if (!printonly)
1244 report_progress(sbd.fssize, 1);
1245 free(buf);
1246 return 0;
1247 }
1248
1249 static void restoremeta_usage(void)
1250 {
1251 fprintf(stderr, "Usage:\n");
1252 fprintf(stderr, "gfs2_edit restoremeta <metadata_file> <block_device>\n");
1253 }
1254
1255 static int restore_init(const char *path, struct metafd *mfd, struct savemeta *sm, int printonly)
1256 {
1257 struct gfs2_sb rsb;
1258 uint16_t sb_siglen;
1259 char *end;
1260 char *bp;
1261 int ret;
1262
1263 blks_saved = 0;
1264 restore_buf = malloc(RESTORE_BUF_SIZE);
1265 if (restore_buf == NULL) {
1266 perror("Restore failed");
1267 return -1;
1268 }
1269 restore_off = 0;
1270 restore_left = 0;
1271
1272 mfd->filename = path;
1273 mfd->fd = open(path, O_RDONLY|O_CLOEXEC);
1274 if (mfd->fd < 0) {
1275 perror("Could not open metadata file");
1276 return 1;
1277 }
1278 if (restore_try_bzip(mfd) != 0 &&
1279 restore_try_gzip(mfd) != 0) {
1280 fprintf(stderr, "Failed to read metadata file header and superblock\n");
1281 return -1;
1282 }
1283 bp = restore_buf;
1284 ret = parse_header(bp, sm);
1285 if (ret == 0) {
1286 bp = restore_buf + sizeof(struct savemeta_header);
1287 restore_off = sizeof(struct savemeta_header);
1288 } else if (ret == -1) {
1289 return -1;
1290 }
1291 /* Scan for the position of the superblock. Required to support old formats(?). */
1292 end = &restore_buf[256 + sizeof(struct saved_metablock) + sizeof(struct gfs2_meta_header)];
1293 while (bp <= end) {
1294 memcpy(&rsb, bp + sizeof(struct saved_metablock), sizeof(rsb));
1295 sb_siglen = be16_to_cpu(((struct saved_metablock *)bp)->siglen);
1296 if (be32_to_cpu(rsb.sb_header.mh_magic) == GFS2_MAGIC &&
1297 be32_to_cpu(rsb.sb_header.mh_type) == GFS2_METATYPE_SB)
1298 break;
1299 bp++;
1300 }
1301 if (bp > end) {
1302 fprintf(stderr, "No superblock found in metadata file\n");
1303 return -1;
1304 }
1305 bp += sizeof(struct saved_metablock);
1306 ret = restore_super(mfd, &rsb, printonly);
1307 if (ret != 0)
1308 return ret;
1309
1310 if (sm->sm_fs_bytes > 0) {
1311 sbd.fssize = sm->sm_fs_bytes / sbd.sd_bsize;
1312 printf("Saved file system size is %"PRIu64" blocks, %.2fGB\n",
1313 sbd.fssize, sm->sm_fs_bytes / ((float)(1 << 30)));
1314 }
1315 printf("Block size is %uB\n", sbd.sd_bsize);
1316 printf("This is gfs2 metadata.\n");
1317 if (printonly > 1 && printonly == LGFS2_SB_ADDR(&sbd)) {
1318 display_block_type(bp, LGFS2_SB_ADDR(&sbd), TRUE);
1319 display_gfs2(bp);
1320 } else if (printonly == 1) {
1321 print_gfs2("0 (l=0x%x): ", sb_siglen);
1322 display_block_type(bp, LGFS2_SB_ADDR(&sbd), TRUE);
1323 }
1324 bp += sb_siglen;
1325 restore_off = bp - restore_buf;
1326 restore_left -= restore_off;
1327 return 0;
1328 }
1329
1330 void restoremeta(const char *in_fn, const char *out_device, uint64_t printonly)
1331 {
1332 struct metafd mfd = {0};
1333 struct savemeta sm = {0};
1334 struct stat st;
1335 int error;
1336
1337 termlines = 0;
1338 if (in_fn == NULL || in_fn[0] == '\0') {
1339 fprintf(stderr, "No source file specified.");
1340 restoremeta_usage();
1341 exit(1);
1342 }
1343 if (!printonly && (out_device == NULL || out_device[0] == '\0')) {
1344 fprintf(stderr, "No destination file system specified.");
1345 restoremeta_usage();
1346 exit(1);
1347 }
1348 if (!printonly) {
1349 sbd.device_fd = open(out_device, O_RDWR);
1350 if (sbd.device_fd < 0) {
1351 fprintf(stderr, "Failed to open target '%s': %s\n",
1352 out_device, strerror(errno));
1353 exit(1);
1354 }
1355 } else if (out_device) /* for printsavedmeta, the out_device is an
1356 optional block no */
1357 printonly = check_keywords(out_device);
1358
1359 error = restore_init(in_fn, &mfd, &sm, printonly);
1360 if (error != 0)
1361 exit(error);
1362
1363 if (!printonly) {
1364 uint64_t space = lseek(sbd.device_fd, 0, SEEK_END) / sbd.sd_bsize;
1365 printf("There are %"PRIu64" free blocks on the destination device.\n", space);
1366 }
1367
1368 error = restore_data(sbd.device_fd, &mfd, printonly);
1369
1370 /* When there is a metadata header available, truncate to filesystem
1371 size if our device_fd is a regular file */
1372 if (!printonly) {
1373 if (fstat(sbd.device_fd, &st) == -1) {
1374 fprintf(stderr, "Failed to stat %s: %s\n", out_device, strerror(errno));
1375 error = errno;
1376 }
1377
1378 if (sm.sm_fs_bytes > 0 && S_ISREG(st.st_mode)) {
1379 if (ftruncate(sbd.device_fd, sm.sm_fs_bytes) != 0) {
1380 fprintf(stderr, "Failed to truncate: %s, %s\n", out_device, strerror(errno));
1381 error = errno;
1382 }
1383 }
1384 }
1385
1386 printf("File %s %s %s.\n", in_fn,
1387 (printonly ? "print" : "restore"),
1388 (error ? "error" : "successful"));
1389
1390 mfd.close(&mfd);
1391 if (!printonly)
1392 close(sbd.device_fd);
1393 free(indirect);
1394 exit(error);
1395 }
1396