1#!/bin/sh 2 3# Copy of suj30.sh but with SU instead of SUJ 4 5# Rename test scenario by Andrey Zonov <zont@FreeBSD.org> 6 7[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 8 9. ../default.cfg 10 11set -u 12prog=$(basename "$0" .sh) 13here=`pwd` 14log=/tmp/$prog.sh.log 15cd /tmp 16sed '1,/^EOF/d' < $here/$0 > $prog.c 17mycc -o $prog -Wall -Wextra -O2 $prog.c -lpthread 18rm -f $prog.c 19 20mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint 21mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 22 23mdconfig -a -t swap -s 8g -u $mdstart 24newfs -U md$mdstart > /dev/null 25mount /dev/md$mdstart $mntpoint 26chmod 777 $mntpoint 27 28t=`date +%s` 29/tmp/$prog $mntpoint/test-0 100000 30t=$((`date +%s` - t)) 31[ $t -gt 60 ] && n=20000 || n=100000 32 33for i in `jot 10`; do 34 /tmp/$prog $mntpoint/test-$i $n & 35done 36wait 37 38while mount | grep -q $mntpoint; do 39 umount $mntpoint || sleep 1 40done 41fsck -fy /dev/md$mdstart > $log 42grep -q "WAS MODIFIED" $log && s=1 || s=0 43mdconfig -d -u $mdstart 44rm -f /tmp/$prog $log 45exit $s 46EOF 47/* 48 * Andrey Zonov (c) 2012 49 * 50 * compile as `cc -o rename rename.c -lpthread' 51 */ 52 53#include <sys/types.h> 54#include <sys/stat.h> 55#include <sys/time.h> 56#include <sys/queue.h> 57#include <err.h> 58#include <errno.h> 59#include <fcntl.h> 60#include <pthread.h> 61#ifdef __FreeBSD__ 62#include <pthread_np.h> 63#define __NP__ 64#endif 65#include <sched.h> 66#include <stdio.h> 67#include <stdlib.h> 68#include <string.h> 69#include <time.h> 70#include <unistd.h> 71 72#define LOCK(x) pthread_mutex_lock(&x.mtx) 73#define UNLOCK(x) pthread_mutex_unlock(&x.mtx) 74#define SIGNAL(x) pthread_cond_signal(&x.wait) 75#define WAIT(x) pthread_cond_wait(&x.wait, &x.mtx) 76 77int max; 78int exited; 79char *dirname1; 80char *dirname2; 81 82struct file { 83 char *name; 84 STAILQ_ENTRY(file) next; 85}; 86 87struct files { 88 pthread_mutex_t mtx; 89 pthread_cond_t wait; 90 STAILQ_HEAD(, file) list; 91}; 92 93static struct files newfiles; 94static struct files renamedfiles; 95 96void *loop_create(void *arg __unused); 97void *loop_rename(void *arg __unused); 98void *loop_unlink(void *arg __unused); 99 100int 101main(int argc, char **argv) 102{ 103 int i; 104 int rc; 105 pthread_t tid[3]; 106 107 if (argc != 3) 108 errx(1, "usage: pthread_count <dirname> <max>"); 109 110 asprintf(&dirname1, "%s.1", argv[1]); 111 asprintf(&dirname2, "%s.2", argv[1]); 112 if (mkdir(dirname1, 0755) == -1) 113 err(1, "mkdir(%s)", dirname1); 114 if (mkdir(dirname2, 0755) == -1) 115 err(1, "mkdir(%s)", dirname2); 116 max = atoi(argv[2]); 117 118 STAILQ_INIT(&newfiles.list); 119 STAILQ_INIT(&renamedfiles.list); 120 121 rc = pthread_mutex_init(&newfiles.mtx, NULL); 122 if (rc != 0) 123 errc(1, rc, "pthread_mutex_init()"); 124 rc = pthread_cond_init(&newfiles.wait, NULL); 125 if (rc != 0) 126 errc(1, rc, "pthread_cond_init()"); 127 rc = pthread_mutex_init(&renamedfiles.mtx, NULL); 128 if (rc != 0) 129 errc(1, rc, "pthread_mutex_init()"); 130 rc = pthread_cond_init(&renamedfiles.wait, NULL); 131 if (rc != 0) 132 errc(1, rc, "pthread_cond_init()"); 133 134 rc = pthread_create(&tid[0], NULL, loop_create, NULL); 135 if (rc != 0) 136 errc(1, rc, "pthread_create()"); 137 rc = pthread_create(&tid[1], NULL, loop_rename, NULL); 138 if (rc != 0) 139 errc(1, rc, "pthread_create()"); 140 rc = pthread_create(&tid[2], NULL, loop_unlink, NULL); 141 if (rc != 0) 142 errc(1, rc, "pthread_create()"); 143 144 for (i = 0; i < 3; i++) { 145 rc = pthread_join(tid[i], NULL); 146 if (rc != 0) 147 errc(1, rc, "pthread_join(%d)", i); 148 } 149 150 rc = pthread_mutex_destroy(&newfiles.mtx); 151 if (rc != 0) 152 errc(1, rc, "pthread_mutex_destroy(newfiles)"); 153 rc = pthread_cond_destroy(&newfiles.wait); 154 if (rc != 0) 155 errc(1, rc, "pthread_cond_destroy(newfiles)"); 156 rc = pthread_mutex_destroy(&renamedfiles.mtx); 157 if (rc != 0) 158 errc(1, rc, "pthread_mutex_destroy(renamedfiles)"); 159 rc = pthread_cond_destroy(&renamedfiles.wait); 160 if (rc != 0) 161 errc(1, rc, "pthread_cond_destroy(renamedfiles)"); 162 rmdir(dirname1); 163 rmdir(dirname2); 164 free(dirname1); 165 free(dirname2); 166 167 exit(0); 168} 169 170void * 171loop_create(void *arg __unused) 172{ 173 int i; 174 struct file *file; 175 176#ifdef __NP__ 177 pthread_set_name_np(pthread_self(), __func__); 178#endif 179 180 for (i = 0; i < max; i++) { 181 file = malloc(sizeof(*file)); 182 asprintf(&file->name, "%s/filename_too-long:%d", dirname1, i); 183 if (mkdir(file->name, 0666) == -1) { 184 warn("mkdir(%s)", file->name); 185 free(file->name); 186 free(file); 187 break; 188 } 189 LOCK(newfiles); 190 STAILQ_INSERT_TAIL(&newfiles.list, file, next); 191 UNLOCK(newfiles); 192 SIGNAL(newfiles); 193 } 194 exited = 1; 195 SIGNAL(newfiles); 196 pthread_exit(NULL); 197} 198 199void * 200loop_rename(void *arg __unused) 201{ 202 char *filename, *newname; 203 struct file *file; 204 205#ifdef __NP__ 206 pthread_set_name_np(pthread_self(), __func__); 207#endif 208 209 for ( ;; ) { 210 LOCK(newfiles); 211 while (STAILQ_EMPTY(&newfiles.list) && exited < 1) 212 WAIT(newfiles); 213 if (STAILQ_EMPTY(&newfiles.list) && exited == 1) { 214 UNLOCK(newfiles); 215 break; 216 } 217 file = STAILQ_FIRST(&newfiles.list); 218 STAILQ_REMOVE_HEAD(&newfiles.list, next); 219 UNLOCK(newfiles); 220 filename = strrchr(file->name, '/'); 221 asprintf(&newname, "%s/%s", dirname2, filename); 222 if (rename(file->name, newname) == -1) 223 err(1, "rename(%s, %s)", file->name, newname); 224 free(file->name); 225 file->name = newname; 226 LOCK(renamedfiles); 227 STAILQ_INSERT_TAIL(&renamedfiles.list, file, next); 228 UNLOCK(renamedfiles); 229 SIGNAL(renamedfiles); 230 } 231 exited = 2; 232 SIGNAL(renamedfiles); 233 pthread_exit(NULL); 234} 235 236void * 237loop_unlink(void *arg __unused) 238{ 239 struct file *file; 240 241#ifdef __NP__ 242 pthread_set_name_np(pthread_self(), __func__); 243#endif 244 245 for ( ;; ) { 246 LOCK(renamedfiles); 247 while (STAILQ_EMPTY(&renamedfiles.list) && exited < 2) 248 WAIT(renamedfiles); 249 if (STAILQ_EMPTY(&renamedfiles.list) && exited == 2) { 250 UNLOCK(renamedfiles); 251 break; 252 } 253 file = STAILQ_FIRST(&renamedfiles.list); 254 STAILQ_REMOVE_HEAD(&renamedfiles.list, next); 255 UNLOCK(renamedfiles); 256 rmdir(file->name); 257 free(file->name); 258 free(file); 259 } 260 pthread_exit(NULL); 261} 262