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