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