xref: /freebsd/tools/test/stress2/misc/zfs18.sh (revision 780f28929782a104eefbc81f031836bf1febb6de)
1#!/bin/sh
2
3# File corruption scenario.
4# Test program obtained from Kyle Evans <kevans@FreeBSD.org>
5
6# "panic: VERIFY3(rc->rc_count == number) failed (4849664 == 0)" seen.
7
8# Page fault seen:
9# https://people.freebsd.org/~pho/stress/log/log0560.txt
10
11[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
12[ `sysctl -n kern.kstack_pages` -lt 4 ] && exit 0
13
14. ../default.cfg
15
16prog=$(basename "$0" .sh)
17cat > /tmp/$prog.c <<EOF
18#include <sys/mman.h>
19#include <sys/stat.h>
20
21#include <assert.h>
22#include <err.h>
23#include <fcntl.h>
24#include <stdio.h>
25#include <unistd.h>
26
27//#define	FILE	"2"
28#define	FILE	"file"
29
30int
31main(void)
32{
33	struct stat sb;
34	ssize_t wsz;
35	size_t bufsz;
36	void *buf, *obuf;
37	int mfd, fd;
38	int done = 0;
39
40	mfd = open(FILE, O_RDONLY);
41	assert(mfd >= 0);
42
43	assert(fstat(mfd, &sb) == 0);
44	bufsz = sb.st_size;
45	buf = obuf = mmap(NULL, bufsz, PROT_READ, MAP_SHARED, mfd, 0);
46	assert(buf != MAP_FAILED);
47
48	/* O_RDWR */
49	fd = open(FILE, O_RDWR);
50	if (fd < 0)
51		err(1, "open");
52	assert(fd >= 0);
53
54again:
55	while (bufsz > 0) {
56		wsz = write(fd, buf, bufsz);
57		if (wsz < 0)
58			err(1, "write");
59		else if (wsz == 0)
60			fprintf(stderr, "Huh?\n");
61		bufsz -= wsz;
62		buf += wsz;
63	}
64
65	bufsz = sb.st_size;
66	buf = obuf;
67
68	if (++done < 2)
69		goto again;
70
71	close(fd);
72	munmap(obuf, sb.st_size);
73	close(mfd);
74	return (0);
75}
76EOF
77mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
78set -u
79kldstat -v | grep -q zfs.ko  || { kldload zfs.ko ||
80    exit 0; loaded=1; }
81
82u1=$mdstart
83u2=$((u1 + 1))
84mp0=/stress2_tank/test		# zfs mount
85
86mdconfig -l | grep -q md$u1 && mdconfig -d -u $u1
87mdconfig -l | grep -q md$u2 && mdconfig -d -u $u2
88
89mdconfig -s 4g -u $u1
90mdconfig -s 4g -u $u2
91
92zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank
93[ -d /stress2_tank ] && rm -rf /stress2_tank
94zpool create stress2_tank raidz md$u1 md$u2
95zfs create ${mp0#/}
96
97here=`pwd`
98cd /stress2_tank
99# Optimized file creation:
100#jot -b 'A' -s '' 875998989 > file
101dd if=/dev/random of=file bs=1m count=$(((875998990/1024/1024)+1)) status=none
102truncate -s 875998990 file
103cat file file > file.post
104mv file file.orig
105
106counter=1
107s=0
108start=`date +%s`
109while [ $((`date +%s` - start)) -lt 300 ]; do
110	cp file.orig file
111	/tmp/$prog
112	if ! cmp file file.post; then
113		echo "Iteration #$counter"
114		od -t x8 file      | head -1000 > /tmp/$prog.file1
115		od -t x8 file.post | head -1000 > /tmp/$prog.file2
116		diff /tmp/$prog.file1 /tmp/$prog.file2 | head -15
117		rm /tmp/$prog.file1 /tmp/$prog.file2
118		s=1
119		break
120	fi
121	counter=$((counter + 1))
122done
123cd $here
124
125zfs umount ${mp0#/}
126zfs destroy -r stress2_tank
127zpool destroy stress2_tank
128
129mdconfig -d -u $u2
130mdconfig -d -u $u1
131set +u
132[ $loaded ] && kldunload zfs.ko
133rm /tmp/$prog /tmp/$prog.c
134exit $s
135