1#!/bin/sh 2 3# 4# Copyright (c) 2015 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# lockf(3) test scenario. 30 31[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 32 33. ../default.cfg 34 35odir=`pwd` 36cd /tmp 37sed '1,/^EOF/d' < $odir/$0 > lockf4.c 38rm -f /tmp/lockf4 39mycc -o lockf4 -Wall -Wextra -g -O2 lockf4.c || exit 1 40rm -f lockf4.c 41cd $odir 42 43[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 44mdconfig -a -t swap -s 1g -u $mdstart || exit 1 45newfs $newfs_flags md$mdstart > /dev/null 46mount /dev/md$mdstart $mntpoint 47chmod 777 $mntpoint 48 49su $testuser -c "(cd $mntpoint; /tmp/lockf4)" & 50su $testuser -c "(cd $mntpoint; /tmp/lockf4)" & 51su $testuser -c "(cd $mntpoint; /tmp/lockf4)" & 52wait 53 54while mount | grep "on $mntpoint " | grep -q /dev/md; do 55 umount $mntpoint || sleep 1 56done 57mdconfig -d -u $mdstart 58rm -f /tmp/lockf4 59exit 0 60EOF 61#include <fcntl.h> 62#include <err.h> 63#include <errno.h> 64#include <stdio.h> 65#include <stdlib.h> 66#include <time.h> 67#include <unistd.h> 68 69#define N (5 * 1024 * 1024) /* 40 MB */ 70int fd; 71int idx[N]; 72char file[] = "lockf4.file"; 73 74#define TIMEOUT 600 75 76int64_t 77add(int ix, int val) 78{ 79 int64_t v; 80 off_t offset; 81 time_t start; 82 int r; 83 84 offset = ix * sizeof(v); 85 if (lseek(fd, offset, SEEK_SET) == -1) 86 err(1, "lseek"); 87 start = time(NULL); 88 while (lockf(fd, F_LOCK, sizeof(v)) == -1) { 89 if (errno != EDEADLK) 90 err(1, "lockf(%s, F_LOCK)", file); 91 if (time(NULL) - start > TIMEOUT) 92 errx(1, "lockf timedout"); 93 } 94 v = 0; 95 r = read(fd, &v, sizeof(v)); 96 if (r == 0) 97 v = 0; 98 else 99 if (r == -1) 100 err(1, "read"); 101 v += val; 102 103 if (lseek(fd, offset, SEEK_SET) == -1) 104 err(1, "lseek"); 105 if (write(fd, &v, sizeof(v)) < 0) 106 err(1, "write"); 107 if (lseek(fd, offset, SEEK_SET) == -1) 108 err(1, "lseek"); 109 if (lockf(fd, F_ULOCK, sizeof(v)) == -1) 110 err(1, "lockf(%s, F_ULOCK)", file); 111 112 return (v); 113} 114 115int 116check(void) 117{ 118 int64_t v; 119 int i; 120 121 setproctitle("check"); 122 if (lseek(fd, 0, SEEK_SET) == -1) 123 err(1, "lseek"); 124 for (i = 1; i < N; i++) { 125 if (read(fd, &v, sizeof(v)) < 0) 126 err(1, "read"); 127 if (v != 0) 128 return (1); 129 } 130 131 return (0); 132} 133 134int 135main(void) 136{ 137 int64_t r; 138 int e, i, j, t; 139 char help[80]; 140 141 for (i = 1; i < N; i++) 142 idx[i] = i; 143 144 for (i = 1; i < N; i++) { 145 j = arc4random() % (N - 1) + 1; 146 t = idx[i]; 147 idx[i] = idx[j]; 148 idx[j] = t; 149 } 150 151 if ((fd = open(file, O_RDWR | O_CREAT, 0644)) == -1) 152 err(1, "open(%s)", file); 153 154 add(0, 1); 155 for (i = 1; i < N; i++) { 156 if (i % 500 == 0) { 157 snprintf(help, sizeof(help), "add %d%%", i * 100 / N); 158 setproctitle("%s", help); 159 } 160 add(idx[i], 1); 161 } 162 for (i = 1; i < N; i++) { 163 if (i % 500 == 0) { 164 snprintf(help, sizeof(help), "sub %d%%", i * 100 / N); 165 setproctitle("%s", help); 166 } 167 add(idx[i], -1); 168 } 169 170 e = 0; 171 if ((r = add(0, -1)) == 0) { 172 e = check(); 173 if (e == 0) 174 unlink(file); 175 else 176 fprintf(stderr, "FAIL\n"); 177 } 178 179 close(fd); 180 181 return (e); 182} 183