blob: 4cca6cfc26c8af5523d91de5946f92ba0b54eacc [file] [log] [blame]
Theodore Ts'o7f88b041997-04-26 14:48:50 +00001/* 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
Theodore Ts'oe2423cc1999-06-18 00:51:31 +000034 *
Theodore Ts'o7f88b041997-04-26 14:48:50 +000035 */
36
Theodore Ts'oe2423cc1999-06-18 00:51:31 +000037/*
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
Theodore Ts'o7f88b041997-04-26 14:48:50 +000066#include <stdio.h>
67#include <stdlib.h>
68#include <time.h>
69
70#include <linux/ext2_fs.h>
Theodore Ts'od9c56d32000-02-08 00:47:55 +000071#include "nls-enable.h"
Theodore Ts'o7f88b041997-04-26 14:48:50 +000072
73
74main(int argc, char *argv[])
75{
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000076 int i;
77 int skiprate=512; /* one sector */
78 long sk=0; /* limited to 2G filesystems!! */
79 FILE *f;
80 char *s;
81 time_t tm;
Theodore Ts'o7f88b041997-04-26 14:48:50 +000082
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000083 struct ext2_super_block ext2;
84 /* interesting fields: EXT2_SUPER_MAGIC
85 * s_blocks_count s_log_block_size s_mtime s_magic s_lastcheck */
Theodore Ts'od9c56d32000-02-08 00:47:55 +000086
87#ifdef ENABLE_NLS
88 setlocale(LC_MESSAGES, "");
89 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
90 textdomain(NLS_CAT_NAME);
91#endif
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000092 if (argc<2) {
93 fprintf(stderr,
Theodore Ts'od9c56d32000-02-08 00:47:55 +000094 _("Usage: findsuper device [skiprate [start]]\n"));
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000095 exit(1);
96 }
97 if (argc>2)
98 skiprate=atoi(argv[2]);
99 if (skiprate<512) {
100 fprintf(stderr,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000101 _("Do you really want to skip less than a sector??\n"));
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000102 exit(2);
103 }
104 if (argc>3)
105 sk=atol(argv[3]);
106 if (sk<0) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000107 fprintf(stderr,_("Have to start at 0 or greater,not %ld\n"),sk);
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000108 exit(1);
109 }
110 f=fopen(argv[1],"r");
111 if (!f) {
112 perror(argv[1]);
113 exit(1);
114 }
Theodore Ts'o7f88b041997-04-26 14:48:50 +0000115
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000116 /* Now, go looking for the superblock ! */
Theodore Ts'oeb5ab741998-07-04 17:47:52 +0000117 printf(" thisoff block fs_blk_sz blksz grp last_mount\n");
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000118 for (;!feof(f) && (i=fseek(f,sk,SEEK_SET))!= -1; sk+=skiprate){
119 if (i=fread(&ext2,sizeof(ext2),1, f)!=1) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000120 perror(_("read failed"));
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000121 }
Theodore Ts'oe2423cc1999-06-18 00:51:31 +0000122 if (ext2.s_magic != EXT2_SUPER_MAGIC)
123 continue;
124
125 tm = ext2.s_mtime;
126 s=ctime(&tm);
127 s[24]=0;
128 printf("%9ld %9ld %9ld %5ld %4d %s\n", sk,
129 sk/1024, ext2.s_blocks_count,
130 ext2.s_log_block_size,
131 ext2.s_block_group_nr, s);
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000132 }
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000133 printf(_("Failed on %d at %ld\n"), i, sk);
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000134 fclose(f);
Theodore Ts'o7f88b041997-04-26 14:48:50 +0000135}