xref: /freebsd/tools/test/stress2/misc/mmap28.sh (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1#!/bin/sh
2
3#
4# Copyright (c) 2016 EMC Corp.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# 'panic: vnode_pager_generic_getpages: page 0xc3350b0c offset beyond vp
30# 0xcc187000 size' seen.
31# https://people.freebsd.org/~pho/stress/log/mmap28.txt
32# This was introduced by r292373.
33#
34# A page fault is seen on a non INVARIANTS kernel w/ r292373,
35# whereas this test runs as expected on r292372.
36# https://people.freebsd.org/~pho/stress/log/mmap28-2.txt
37# https://people.freebsd.org/~pho/stress/log/mmap28-3.txt
38# To repeat, run this test with "sysctl vfs.ffs.use_buf_pager=0".
39# Fixed by r307626
40
41# Test scenario refinement by kib@
42
43. ../default.cfg
44
45odir=`pwd`
46cd /tmp
47sed '1,/^EOF/d' < $odir/$0 > mmap28.c
48mycc -o mmap28 -Wall -Wextra -g -O0 mmap28.c || exit 1
49rm -f mmap28.c
50cd $odir
51
52(cd /tmp; ./mmap28)
53
54rm -f /tmp/mmap28 /tmp/mmap28.0* /tmp/mmap28.core
55exit 0
56
57EOF
58#include <sys/param.h>
59#include <sys/mman.h>
60
61#include <err.h>
62#include <errno.h>
63#include <fcntl.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67#include <time.h>
68#include <unistd.h>
69
70#define ADRSPACE  (256 * 1024 * 1024 )
71#define STARTADDR 0x50000000U
72
73static void
74work(void)
75{
76	size_t indx, left, len;
77	int fd, rfd;
78	int i;
79	char *p;
80	char path[128];
81	volatile char val __unused;
82
83	if ((rfd = open("/dev/random", O_RDONLY)) == -1)
84		err(1, "open(/dev/random)");
85
86	snprintf(path, sizeof(path), "/tmp/mmap28.%06d", 0);
87	if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1)
88		err(1,"open(%s)", path);
89
90	p = (void *)STARTADDR + trunc_page(arc4random() % ADRSPACE);
91	left = ADRSPACE - (size_t)p + STARTADDR;
92	len = trunc_page(arc4random() % left) + PAGE_SIZE;
93
94	if (ftruncate(fd, len) == -1)
95		err(1, "ftruncate");
96
97	if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) ==
98			MAP_FAILED) {
99		if (errno == ENOMEM)
100			return;
101		err(1, "mmap()");
102	}
103
104	/*
105	   Truncating the mapped file triggers a panic when accessed beyond
106	   EOF.
107	 */
108	if (ftruncate(fd, len / 2) == -1)
109		err(1, "ftruncate(%s)", path);
110
111	for (i = 0; i < 1000; i++) {
112		if (read(rfd, &indx, sizeof(indx)) != sizeof(indx))
113			err(1, "read(random)");
114		val = p[indx % len];
115	}
116	close(rfd);
117
118	if (munmap(p, len) == -1)
119		err(1, "munmap(%p)", p);
120	close(fd);
121	unlink(path);
122}
123
124int
125main(void)
126{
127
128	work();
129
130	return (0);
131}
132