xref: /freebsd/tools/test/stress2/tools/zapsb.c (revision 1323ec57)
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
25 usage(void)
26 {
27 	(void)fprintf(stderr, "usage: zapsb special_device\n");
28 	exit(1);
29 }
30 
31 int
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