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# Show invalid fts_info value: 30 31# FAULT 32# -rw------- 1 root wheel - 4 13 jan 09:25 ./lockf.0.3676 33# fts_path: ./lockf.0.3676 34# fts_info: 13 FTS_SLNONE 35# fts_errno: 0 No error: 0 36 37[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 38 39. ../default.cfg 40 41cat > /tmp/fts2.c <<EOF 42#include <sys/param.h> 43#include <sys/stat.h> 44#include <sys/types.h> 45#include <sys/wait.h> 46 47#include <err.h> 48#include <errno.h> 49#include <fcntl.h> 50#include <fts.h> 51#include <signal.h> 52#include <stdint.h> 53#include <stdio.h> 54#include <stdlib.h> 55#include <string.h> 56#include <time.h> 57#include <unistd.h> 58 59#define LOOPS 1 60#define PARALLEL 7 61 62pid_t pid; 63time_t start; 64int fd; 65char file[128]; 66 67char *txt[] = { 68 "NULL", 69 "FTS_D", 70 "FTS_DC", 71 "FTS_DEFAULT", 72 "FTS_DNR", 73 "FTS_DOT", 74 "FTS_DP", 75 "FTS_ERR", 76 "FTS_F", 77 "FTS_INIT", 78 "FTS_NS", 79 "FTS_NSOK", 80 "FTS_SL", 81 "FTS_SLNONE", 82 "FTS_W", 83 "15", 84 "16", 85 "17", 86}; 87 88int 89get(void) { 90 int sem; 91 if (lockf(fd, F_LOCK, 0) == -1) 92 err(1, "lockf(%s, F_LOCK)", file); 93 if (read(fd, &sem, sizeof(sem)) != sizeof(sem)) 94 err(1, "get: read(%d)", fd); 95 if (lseek(fd, 0, SEEK_SET) == -1) 96 err(1, "lseek"); 97 if (lockf(fd, F_ULOCK, 0) == -1) 98 err(1, "lockf(%s, F_ULOCK)", file); 99 return (sem); 100} 101 102void 103incr(void) { 104 int sem; 105 if (lockf(fd, F_LOCK, 0) == -1) 106 err(1, "lockf(%s, F_LOCK)", file); 107 if (read(fd, &sem, sizeof(sem)) != sizeof(sem)) 108 err(1, "incr: read(%d)", fd); 109 if (lseek(fd, 0, SEEK_SET) == -1) 110 err(1, "lseek"); 111 sem++; 112 if (write(fd, &sem, sizeof(sem)) != sizeof(sem)) 113 err(1, "incr: read"); 114 if (lseek(fd, 0, SEEK_SET) == -1) 115 err(1, "lseek"); 116 if (lockf(fd, F_ULOCK, 0) == -1) 117 err(1, "lockf(%s, F_ULOCK)", file); 118} 119 120void 121tlockf(void) 122{ 123 int i; 124 int sem = 0; 125 126 usleep(arc4random() % 10000); 127 sprintf(file, "lockf.0.%d", getpid()); 128 if ((fd = open(file,O_CREAT | O_TRUNC | O_RDWR, 0600)) == -1) 129 err(1, "creat(%s)", file); 130 if (write(fd, &sem, sizeof(sem)) != sizeof(sem)) 131 err(1, "write"); 132 if (lseek(fd, 0, SEEK_SET) == -1) 133 err(1, "lseek"); 134 135 pid = fork(); 136 if (pid == -1) { 137 perror("fork"); 138 exit(2); 139 } 140 141 if (pid == 0) { /* child */ 142 for (i = 0; i < 100; i++) { 143 while ((get() & 1) == 0) 144 ; 145 incr(); 146 } 147 exit(0); 148 } else { /* parent */ 149 for (i = 0; i < 100; i++) { 150 while ((get() & 1) == 1) 151 ; 152 incr(); 153 } 154 } 155 close(fd); 156 waitpid(pid, &i, 0); 157 unlink(file); 158} 159 160void 161tmkdir(void) 162{ 163 pid_t pid; 164 int i, j; 165 char name[80]; 166 167 setproctitle(__func__); 168 usleep(arc4random() % 10000); 169 pid = getpid(); 170 for (j = 0; j < LOOPS; j++) { 171 for (i = 0; i < 1000; i++) { 172 snprintf(name, sizeof(name), "dir.%d.%06d", pid, i); 173 if (mkdir(name, 0644) == -1) 174 err(1, "mkdir(%s)", name); 175 } 176 for (i = 0; i < 1000; i++) { 177 snprintf(name, sizeof(name), "dir.%d.%06d", pid, i); 178 if (rmdir(name) == -1) 179 err(1, "unlink(%s)", name); 180 } 181 } 182} 183 184void 185tfts(void) 186{ 187 FTS *fts; 188 FTSENT *p; 189 int ftsoptions, i; 190 char *args[2]; 191 char help[80]; 192 193 usleep(arc4random() % 10000); 194 ftsoptions = FTS_LOGICAL; 195 args[0] = "."; 196 args[1] = 0; 197 198 for (i = 0; i < 10; i++) { 199 if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) 200 err(1, "fts_open"); 201 202 while ((p = fts_read(fts)) != NULL) { 203 if (p->fts_info == FTS_D || /* preorder directory */ 204 p->fts_info == FTS_DNR || /* unreadable directory */ 205 p->fts_info == FTS_DOT || /* dot or dot-dot */ 206 p->fts_info == FTS_DP || /* postorder directory */ 207 p->fts_info == FTS_F || /* regular file */ 208 p->fts_info == FTS_NS) /* stat(2) failed */ 209 continue; 210 fprintf(stderr, "FAULT\n"); 211 sprintf(help, "ls -lo %s", p->fts_path); 212 system(help); 213 fprintf(stderr, "fts_path: %s\n", p->fts_path); 214 fprintf(stderr, "fts_info: %d %s\n", p->fts_info, 215 txt[p->fts_info]); 216 fprintf(stderr, "fts_errno: %d %s\n", p->fts_errno, 217 strerror(p->fts_errno)); 218 } 219 220 if (errno != 0 && errno != ENOENT) 221 err(1, "fts_read"); 222 if (fts_close(fts) == -1) 223 err(1, "fts_close()"); 224 } 225} 226 227void 228test(void) 229{ 230 231 start = time(NULL); 232 if (fork() == 0) { 233 while (time(NULL) - start < 60) 234 tmkdir(); 235 _exit(0); 236 } 237 if (fork() == 0) { 238 while (time(NULL) - start < 60) 239 tlockf(); 240 _exit(0); 241 } 242 if (fork() == 0) { 243 while (time(NULL) - start < 60) 244 tfts(); 245 _exit(0); 246 } 247 248 wait(NULL); 249 wait(NULL); 250 wait(NULL); 251 252 _exit(0); 253} 254 255int 256main(void) 257{ 258 int i; 259 260 for (i = 0; i < PARALLEL; i++) 261 if (fork() == 0) 262 test(); 263 for (i = 0; i < PARALLEL; i++) 264 wait(NULL); 265 266 return (0); 267} 268EOF 269mycc -o /tmp/fts2 -Wall -Wextra -O0 -g /tmp/fts2.c || exit 1 270 271mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint 272[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 273 274mdconfig -a -t swap -s 1g -u $mdstart || exit 1 275newfs md$mdstart > /dev/null 276mount /dev/md$mdstart $mntpoint 277 278(cd $mntpoint; /tmp/fts2) 279 280while mount | grep $mntpoint | grep -q /dev/md; do 281 umount $mntpoint || sleep 1 282done 283mdconfig -d -u $mdstart 284rm /tmp/fts2 /tmp/fts2.c 285