1 /*
2 * Zero out a superblock check hash.
3 * By Kirk McKusick <mckusick@mckusick.com>
4 */
5
6 #include <sys/param.h>
7 #include <sys/disklabel.h>
8
9 #include <ufs/ufs/dinode.h>
10 #include <ufs/ffs/fs.h>
11
12 #include <err.h>
13 #include <fcntl.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <unistd.h>
18
19 /*
20 * Possible superblock locations ordered from most to least likely.
21 */
22 static int sblock_try[] = SBLOCKSEARCH;
23
24 static void
usage(void)25 usage(void)
26 {
27 (void)fprintf(stderr, "usage: zapsb special_device\n");
28 exit(1);
29 }
30
31 int
main(int argc,char * argv[])32 main(int argc, char *argv[])
33 {
34 char *fs, sblock[SBLOCKSIZE];
35 struct fs *sbp;
36 int i, fd;
37
38 if (argc != 2)
39 usage();
40
41 fs = *++argv;
42
43 /* get the superblock. */
44 if ((fd = open(fs, O_RDWR, 0)) < 0)
45 err(1, "%s", fs);
46 for (i = 0; sblock_try[i] != -1; i++) {
47 if (lseek(fd, (off_t)(sblock_try[i]), SEEK_SET) < 0)
48 err(1, "%s", fs);
49 if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock))
50 errx(1, "%s: can't read superblock", fs);
51 sbp = (struct fs *)sblock;
52 if ((sbp->fs_magic == FS_UFS1_MAGIC ||
53 (sbp->fs_magic == FS_UFS2_MAGIC &&
54 sbp->fs_sblockloc == sblock_try[i])) &&
55 sbp->fs_bsize <= MAXBSIZE &&
56 sbp->fs_bsize >= (int)sizeof(struct fs))
57 break;
58 }
59 if (sblock_try[i] == -1) {
60 fprintf(stderr, "Cannot find file system superblock\n");
61 exit(2);
62 }
63 if ((sbp->fs_metackhash & CK_SUPERBLOCK) == 0) {
64 fprintf(stderr, "file system superblock has no check hash\n");
65 exit(3);
66 }
67 printf("zeroing superblock checksum at location %d\n", sblock_try[i]);
68 sbp->fs_ckhash = 0;
69 if (lseek(fd, (off_t)(sblock_try[i]), SEEK_SET) < 0)
70 err(1, "%s", fs);
71 if (write(fd, sblock, sizeof(sblock)) != sizeof(sblock))
72 errx(1, "%s: can't write superblock", fs);
73 (void)close(fd);
74 exit(0);
75 }
76