Whamcloud - gitweb
Makefile.in:
[tools/e2fsprogs.git] / misc / findsuper.c
1 /* Well, here's my linux version of findsuper.
2  * I'm sure you coulda done it faster.  :)
3  * IMHO there isn't as much interesting data to print in the
4  * linux superblock as there is in the SunOS superblock--disk geometry is
5  * not there...and linux seems to update the dates in all the superblocks.
6  * SunOS doesn't ever touch the backup superblocks after the fs is created,
7  * as far as I can tell, so the date is more interesting IMHO and certainly
8  * marks which superblocks are backup ones.
9  *
10  * This still doesn't handle disks >2G.
11  *
12  * I wanted to add msdos support, but I couldn't make heads or tails
13  * of the kernel include files to find anything I could look for in msdos.
14  * 
15  * Reading every block of a Sun partition is fairly quick.  Doing the
16  * same under linux (slower hardware I suppose) just isn't the same.
17  * It might be more useful to default to reading the first (second?) block
18  * on each cyl; however, if the disk geometry is wrong, this is useless.
19  * But ya could still get the cyl size to print the numbers as cyls instead
20  * of blocks...
21  *
22  * run this as (for example)
23  *   findsuper /dev/hda
24  *   findsuper /dev/hda 437760 1024   (my disk has cyls of 855*512)
25  *
26  * I suppose the next step is to figgure out a way to determine if
27  * the block found is the first superblock somehow, and if so, build
28  * a partition table from the superblocks found... but this is still
29  * useful as is.
30  *
31  *              Steve
32  * ssd@nevets.oau.org
33  * ssd@mae.engr.ucf.edu
34  * 
35  */
36
37 /*
38  * Documentation addendum added by Andreas dwguest@win.tue.nl/aeb@cwi.nl
39  * 
40  * The program findsuper is a utility that scans a disk and finds
41  * copies of ext2 superblocks (by checking for the ext2 signature; it
42  * will occasionally find other blocks that by coincidence have this
43  * signature - often these can be recognised by their ridiculous
44  * dates).
45  * 
46  * For each superblock found, it prints the offset in bytes, the
47  * offset in 1024-byte blocks, the size of ext2 partition in 1024-byte
48  * blocks, the filesystem blocksize (given as log(blocksize)-10, so
49  * that 0 means 1024), the block group number (0 for older ext2
50  * systems), and a timestamp (s_mtime).
51  * 
52  * This program can be used to retrieve partitions that have been
53  * lost.  The superblock for block group 0 is found 1 block (2
54  * sectors) after the partition start.
55  * 
56  * For new systems that have a block group number in the superblock it
57  * is immediately clear which superblock is the first of a partition.
58  * For old systems where no group numbers are given, the first
59  * superblock can be recognised by the timestamp: all superblock
60  * copies have the creation time in s_mtime, except the first, which
61  * has the last time e2fsck or tune2fs wrote to the filesystem.
62  * 
63  */
64
65
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <time.h>
69
70 #include <linux/ext2_fs.h>
71
72
73 main(int argc, char *argv[])
74 {
75         int i;
76         int skiprate=512;               /* one sector */
77         long sk=0;                      /* limited to 2G filesystems!! */
78         FILE *f;
79         char *s;
80         time_t tm;
81
82         struct ext2_super_block ext2;
83         /* interesting fields: EXT2_SUPER_MAGIC
84          *      s_blocks_count s_log_block_size s_mtime s_magic s_lastcheck */
85   
86         if (argc<2) {
87                 fprintf(stderr,
88                         "Usage:  findsuper device [skiprate [start]]\n");
89                 exit(1);
90         }
91         if (argc>2)
92                 skiprate=atoi(argv[2]);
93         if (skiprate<512) {
94                 fprintf(stderr,
95                         "Do you really want to skip less than a sector??\n");
96                 exit(2);
97         }
98         if (argc>3)
99                 sk=atol(argv[3]);
100         if (sk<0) {
101                 fprintf(stderr,"Have to start at 0 or greater,not %ld\n",sk);
102                 exit(1);
103         }
104         f=fopen(argv[1],"r");
105         if (!f) {
106                 perror(argv[1]);
107                 exit(1);
108         }
109  
110         /* Now, go looking for the superblock ! */
111         printf("  thisoff     block fs_blk_sz  blksz grp last_mount\n");
112         for (;!feof(f) &&  (i=fseek(f,sk,SEEK_SET))!= -1; sk+=skiprate){
113                 if (i=fread(&ext2,sizeof(ext2),1, f)!=1) {
114                         perror("read failed");
115                 }
116                 if (ext2.s_magic != EXT2_SUPER_MAGIC)
117                         continue;
118                 
119                 tm = ext2.s_mtime;
120                 s=ctime(&tm);
121                 s[24]=0;
122                 printf("%9ld %9ld %9ld %5ld %4d %s\n", sk,
123                        sk/1024, ext2.s_blocks_count,
124                        ext2.s_log_block_size,
125                        ext2.s_block_group_nr, s);
126         }
127         printf("Failed on %d at %ld\n", i, sk);
128         fclose(f);
129 }