1#!/bin/sh 2 3# 4# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org> 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# Variation of the datamove2.sh, using TMPFS 30# Deadlock seen 31# https://people.freebsd.org/~pho/stress/log/datamove4.txt 32 33# panic: elf32_putnote: Note type 10 changed as we read it (2236 > 2220)... 34# https://people.freebsd.org/~pho/stress/log/datamove4-2.txt 35# Fixed by r288944. 36 37[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 38 39. ../default.cfg 40 41here=`pwd` 42cd /tmp 43sed '1,/^EOF/d' < $here/$0 > datamove4.c 44mycc -o datamove4 -Wall -Wextra -O2 -g datamove4.c 45rm -f datamove4.c 46 47mount | grep -q "$mntpoint " && umount $mntpoint 48mount -t tmpfs tmpfs $mntpoint 49chmod 777 $mntpoint 50 51for i in `jot 5`; do 52 su $testuser -c "cd $mntpoint; /tmp/datamove4" 53done 54while mount | grep -q $mntpoint; do 55 umount -f $mntpoint > /dev/null 2>&1 56done 57 58rm -rf /tmp/datamove4 59exit 0 60EOF 61/*- 62 * Copyright (c) 2006, Stephan Uphoff <ups@freebsd.org> 63 * All rights reserved. 64 * 65 * Redistribution and use in source and binary forms, with or without 66 * modification, are permitted provided that the following conditions 67 * are met: 68 * 1. Redistributions of source code must retain the above copyright 69 * notice unmodified, this list of conditions, and the following 70 * disclaimer. 71 * 2. Redistributions in binary form must reproduce the above copyright 72 * notice, this list of conditions and the following disclaimer in the 73 * documentation and/or other materials provided with the distribution. 74 * 75 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 76 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 77 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 78 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 79 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 80 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 81 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 82 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 83 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 84 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 85 */ 86 87#include <err.h> 88#include <fcntl.h> 89#include <stdio.h> 90#include <stdlib.h> 91#include <sys/mman.h> 92#include <sys/stat.h> 93#include <sys/types.h> 94#include <sys/wait.h> 95#include <unistd.h> 96 97int prepareFile(char *filename, int *fdp); 98int mapBuffer (char **bufferp, int fd1, int fd2); 99int startIO (int fd, char *buffer); 100 101int pagesize; 102 103#define FILESIZE (32*1024) 104char wbuffer [FILESIZE]; 105 106/* Create a FILESIZE sized file - then remove file data from the cache */ 107int 108prepareFile(char *filename, int *fdp) 109{ 110 int fd; 111 int len; 112 int status; 113 void *addr; 114 115 fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); 116 if (fd == -1) { 117 perror(filename); 118 return fd; 119 } 120 len = write(fd, wbuffer, FILESIZE); 121 if (len < 0) { 122 perror("Write failed"); 123 return 1; 124 } 125 status = fsync(fd); 126 if (status != 0) { 127 perror("fsync failed"); 128 return 1; 129 } 130 addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 131 if (addr == MAP_FAILED) { 132 perror("Mmap failed"); 133 return 1; 134 } 135 status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC); 136 if (status != 0) { 137 perror("Msync failed"); 138 return 1; 139 } 140 if (munmap(addr, FILESIZE) == -1) { 141 perror("munmap failed"); 142 return 1; 143 } 144 145 *fdp = fd; 146 return 0; 147} 148 149/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ 150int 151mapBuffer(char **bufferp, int fd1, int fd2) 152{ 153 void *addr; 154 char *buffer; 155 156 addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0); 157 if (addr == MAP_FAILED) { 158 perror("Mmap failed"); 159 return 1; 160 } 161 buffer = addr; 162 addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED | 163 MAP_SHARED, fd2, 0); 164 165 if (addr == MAP_FAILED) { 166 perror("Mmap2 failed"); 167 return 1; 168 } 169 *bufferp = buffer; 170 return 0; 171} 172 173void 174unmapBuffer(char *bufferp) 175{ 176 if (munmap(bufferp, pagesize * 2) == -1) 177 err(1, "unmap 1. buffer"); 178 /* 179 The following unmaps something random, which could trigger: 180 Program received signal SIGSEGV, Segmentation fault. 181 free (cp=0x28070000) at /usr/src/libexec/rtld-elf/malloc.c:311 182 */ 183 184#if 0 185 if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1) 186 err(1, "unmap 2. buffer"); 187#endif 188} 189 190int 191startIO(int fd, char *buffer) 192{ 193 ssize_t len; 194 195 len = write(fd, buffer, 2 * pagesize); 196 if (len == -1) { 197 perror("write failed"); 198 return 1; 199 } 200 return 0; 201} 202 203int 204main() 205{ 206 207 int fdA, fdB, fdDelayA, fdDelayB; 208 int status; 209 int i; 210 char *bufferA, *bufferB; 211 pid_t pid; 212 213 pagesize = getpagesize(); 214 215 for (i = 0; i < 1000; i++) { 216 if ((prepareFile("A", &fdA)) 217 || (prepareFile("B", &fdB)) 218 || (prepareFile("DelayA", &fdDelayA)) 219 || (prepareFile("DelayB", &fdDelayB)) 220 || (mapBuffer(&bufferA, fdDelayA, fdB)) 221 || (mapBuffer(&bufferB, fdDelayB, fdA))) 222 exit(1); 223 224 pid = fork(); 225 226 if (pid == 0) { 227 status = startIO(fdA, bufferA); 228 exit(status); 229 } 230 if (pid == -1) { 231 perror("fork"); 232 exit(1); 233 } 234 status = startIO(fdB, bufferB); 235 if (wait(&status) == -1) 236 err(1, "wait"); 237 238 close(fdA); 239 close(fdB); 240 close(fdDelayA); 241 close(fdDelayB); 242 unmapBuffer(bufferA); 243 unmapBuffer(bufferB); 244 unlink("A"); 245 unlink("B"); 246 unlink("DelayA"); 247 unlink("DelayB"); 248 } 249 exit(status); 250 251} 252