xref: /freebsd/tools/test/stress2/misc/sendfile14.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm#!/bin/sh
2*8a272653SPeter Holm
3*8a272653SPeter Holm#
4*8a272653SPeter Holm# Copyright (c) 2018 Dell EMC Isilon
5*8a272653SPeter Holm# All rights reserved.
6*8a272653SPeter Holm#
7*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
8*8a272653SPeter Holm# modification, are permitted provided that the following conditions
9*8a272653SPeter Holm# are met:
10*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
11*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
12*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
13*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
14*8a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
15*8a272653SPeter Holm#
16*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*8a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8a272653SPeter Holm# SUCH DAMAGE.
27*8a272653SPeter Holm#
28*8a272653SPeter Holm
29*8a272653SPeter Holm# Regression test scenario attempt for r328914:
30*8a272653SPeter Holm# "Occasional cylinder-group check-hash errors were being reported on
31*8a272653SPeter Holm# systems running with a heavy filesystem load."
32*8a272653SPeter Holm
33*8a272653SPeter Holm# Assert seen in WiP code:
34*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/mmacy016.txt
35*8a272653SPeter Holm
36*8a272653SPeter Holm. ../default.cfg
37*8a272653SPeter Holm[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
38*8a272653SPeter Holm
39*8a272653SPeter Holmdir=/tmp
40*8a272653SPeter Holmodir=`pwd`
41*8a272653SPeter Holmcd $dir
42*8a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/sendfile14.c
43*8a272653SPeter Holmmycc -o sendfile14 -Wall -Wextra -O0 -g sendfile14.c -lpthread || exit 1
44*8a272653SPeter Holmrm -f sendfile14.c
45*8a272653SPeter Holmcd $odir
46*8a272653SPeter Holm
47*8a272653SPeter Holmset -e
48*8a272653SPeter Holmsize="$((`sysctl -n hw.usermem` / 2 / 1024 / 1024 / 1024))"
49*8a272653SPeter Holmsize="$((size * 8 / 10))g"
50*8a272653SPeter Holm[ "$size" = "0g" ] && exit 0
51*8a272653SPeter Holm[ "$newfs_flags" = "-U" ] || exit 0
52*8a272653SPeter Holmnewfs_flags="-j"
53*8a272653SPeter Holm
54*8a272653SPeter Holmmp1=$mntpoint
55*8a272653SPeter Holmmkdir -p $mp1
56*8a272653SPeter Holmmd1=$mdstart
57*8a272653SPeter Holmmount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
58*8a272653SPeter Holm[ -c /dev/md$md1 ] && mdconfig -d -u $md1
59*8a272653SPeter Holmmdconfig -a -t swap -s $size -u $md1
60*8a272653SPeter Holmbsdlabel -w md$md1 auto
61*8a272653SPeter Holmnewfs $newfs_flags -n md${md1}$part > /dev/null 2>&1
62*8a272653SPeter Holmmount /dev/md${md1}$part $mp1
63*8a272653SPeter Holm
64*8a272653SPeter Holmmd2=$((mdstart + 1))
65*8a272653SPeter Holmmp2=${mntpoint}$md2
66*8a272653SPeter Holmmkdir -p $mp2
67*8a272653SPeter Holmmount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2
68*8a272653SPeter Holm[ -c /dev/md$md2 ] && mdconfig -d -u $md2
69*8a272653SPeter Holmmdconfig -a -t swap -s $size -u $md2
70*8a272653SPeter Holmbsdlabel -w md$md2 auto
71*8a272653SPeter Holmnewfs $newfs_flags -n md${md2}$part > /dev/null 2>&1
72*8a272653SPeter Holmmount /dev/md${md2}$part $mp2
73*8a272653SPeter Holmset +e
74*8a272653SPeter Holm
75*8a272653SPeter Holmfree=`df $mp1 | tail -1 | awk '{print $4}'`
76*8a272653SPeter Holm$dir/sendfile14 5432 $mp1 $mp2 $((free / 2)) &
77*8a272653SPeter Holm$dir/sendfile14 5433 $mp2 $mp1 $((free / 2)) &
78*8a272653SPeter Holmcd $odir
79*8a272653SPeter Holmwait
80*8a272653SPeter Holms=0
81*8a272653SPeter Holm[ -f sendfile14.core -a $s -eq 0 ] &&
82*8a272653SPeter Holm    { ls -l sendfile14.core; mv sendfile14.core /tmp; s=1; }
83*8a272653SPeter Holmpkill sendfile14
84*8a272653SPeter Holmcd $odir
85*8a272653SPeter Holm
86*8a272653SPeter Holmfor i in `jot 6`; do
87*8a272653SPeter Holm	mount | grep -q "on $mp1 " || break
88*8a272653SPeter Holm	umount $mp1 && break || sleep 10
89*8a272653SPeter Holm	[ $i -eq 6 ] &&
90*8a272653SPeter Holm	    { echo FATAL; fstat -mf $mp1; exit 1; }
91*8a272653SPeter Holmdone
92*8a272653SPeter Holmfor i in `jot 6`; do
93*8a272653SPeter Holm	mount | grep -q "on $mp2 " || break
94*8a272653SPeter Holm	umount $mp2 && break || sleep 10
95*8a272653SPeter Holm	[ $i -eq 6 ] &&
96*8a272653SPeter Holm	    { echo FATAL; fstat -mf $mp2; exit 1; }
97*8a272653SPeter Holmdone
98*8a272653SPeter Holmcheckfs /dev/md${md1}$part || s=1
99*8a272653SPeter Holmcheckfs /dev/md${md2}$part || s=1
100*8a272653SPeter Holmmdconfig -d -u $md1 || s=1
101*8a272653SPeter Holmmdconfig -d -u $md2 || s=1
102*8a272653SPeter Holm
103*8a272653SPeter Holmrm -rf $dir/sendfile14
104*8a272653SPeter Holmexit $s
105*8a272653SPeter Holm
106*8a272653SPeter HolmEOF
107*8a272653SPeter Holm#include <sys/param.h>
108*8a272653SPeter Holm#include <sys/mman.h>
109*8a272653SPeter Holm#include <sys/socket.h>
110*8a272653SPeter Holm#include <sys/stat.h>
111*8a272653SPeter Holm#include <sys/wait.h>
112*8a272653SPeter Holm
113*8a272653SPeter Holm#include <netinet/in.h>
114*8a272653SPeter Holm
115*8a272653SPeter Holm#include <err.h>
116*8a272653SPeter Holm#include <fcntl.h>
117*8a272653SPeter Holm#include <netdb.h>
118*8a272653SPeter Holm#include <pthread.h>
119*8a272653SPeter Holm#include <signal.h>
120*8a272653SPeter Holm#include <stdio.h>
121*8a272653SPeter Holm#include <stdlib.h>
122*8a272653SPeter Holm#include <string.h>
123*8a272653SPeter Holm#include <time.h>
124*8a272653SPeter Holm#include <unistd.h>
125*8a272653SPeter Holm
126*8a272653SPeter Holm#define BUFSIZE 8192
127*8a272653SPeter Holm#define MAXTHREADS 5
128*8a272653SPeter Holm
129*8a272653SPeter Holmstatic volatile int active;
130*8a272653SPeter Holmstatic volatile u_int *share;
131*8a272653SPeter Holmstatic int files, port;
132*8a272653SPeter Holmstatic char *fromdir, *todir;
133*8a272653SPeter Holm
134*8a272653SPeter Holmvoid
135*8a272653SPeter Holmcreate(char *path, size_t size)
136*8a272653SPeter Holm{
137*8a272653SPeter Holm	size_t s;
138*8a272653SPeter Holm	int fd, i, ifd;
139*8a272653SPeter Holm	char *cp, file[128], help[128];
140*8a272653SPeter Holm
141*8a272653SPeter Holm	setproctitle("%s", __func__);
142*8a272653SPeter Holm	i = 0;
143*8a272653SPeter Holm	while (size > 0) {
144*8a272653SPeter Holm		do {
145*8a272653SPeter Holm			s =arc4random() % size + 1;
146*8a272653SPeter Holm		} while (s > 1024 * 1024 * 1024);
147*8a272653SPeter Holm		size -= s;
148*8a272653SPeter Holm		sprintf(file, "%s/f%06d.%06d", path, getpid(), i++);
149*8a272653SPeter Holm		if ((ifd = open("/dev/zero", O_RDONLY)) == -1)
150*8a272653SPeter Holm			err(1, "open(/dev/zero)");
151*8a272653SPeter Holm		if ((cp = mmap(0, s, PROT_READ, MAP_SHARED, ifd, 0)) ==
152*8a272653SPeter Holm			(caddr_t) - 1)
153*8a272653SPeter Holm			err(1, "mmap error for input");
154*8a272653SPeter Holm		if ((fd = open(file, O_WRONLY | O_CREAT, 0640)) == -1)
155*8a272653SPeter Holm			err(1, "create(%s)", file);
156*8a272653SPeter Holm		if (write(fd, cp, s) != (ssize_t)s)
157*8a272653SPeter Holm			err(1, "write(%s)", file);
158*8a272653SPeter Holm		munmap(cp, s);
159*8a272653SPeter Holm		close(fd);
160*8a272653SPeter Holm		close(ifd);
161*8a272653SPeter Holm		files++;
162*8a272653SPeter Holm	}
163*8a272653SPeter Holm	snprintf(help, sizeof(help),
164*8a272653SPeter Holm	    "umount %s 2>&1 | grep -v 'Device busy'", path);
165*8a272653SPeter Holm	system(help);
166*8a272653SPeter Holm#if defined(DEBUG)
167*8a272653SPeter Holm	fprintf(stderr, "%d files created\n", files);
168*8a272653SPeter Holm#endif
169*8a272653SPeter Holm}
170*8a272653SPeter Holm
171*8a272653SPeter Holmvoid
172*8a272653SPeter Holmserver(void)
173*8a272653SPeter Holm{
174*8a272653SPeter Holm	pid_t pid[100];
175*8a272653SPeter Holm        struct sigaction sa;
176*8a272653SPeter Holm	struct sockaddr_in inetaddr, inetpeer;
177*8a272653SPeter Holm	socklen_t len;
178*8a272653SPeter Holm	int tcpsock, msgsock;
179*8a272653SPeter Holm	int *buf, fd, idx, n, on, t;
180*8a272653SPeter Holm	char ofile[128], nfile[128];
181*8a272653SPeter Holm
182*8a272653SPeter Holm	setproctitle("%s", __func__);
183*8a272653SPeter Holm        sa.sa_handler = SIG_IGN;
184*8a272653SPeter Holm        sigemptyset(&sa.sa_mask);
185*8a272653SPeter Holm        sa.sa_flags = 0;
186*8a272653SPeter Holm        if (sigaction(SIGCHLD, &sa, 0) == -1)
187*8a272653SPeter Holm                err(1, "sigaction");
188*8a272653SPeter Holm
189*8a272653SPeter Holm	on = 1;
190*8a272653SPeter Holm	if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
191*8a272653SPeter Holm		err(1, "socket(), %s:%d", __FILE__, __LINE__);
192*8a272653SPeter Holm
193*8a272653SPeter Holm	if (setsockopt(tcpsock,
194*8a272653SPeter Holm	    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
195*8a272653SPeter Holm		err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
196*8a272653SPeter Holm
197*8a272653SPeter Holm	inetaddr.sin_family = AF_INET;
198*8a272653SPeter Holm	inetaddr.sin_addr.s_addr = INADDR_ANY;
199*8a272653SPeter Holm	inetaddr.sin_port = htons(port);
200*8a272653SPeter Holm	inetaddr.sin_len = sizeof(inetaddr);
201*8a272653SPeter Holm
202*8a272653SPeter Holm	if (bind(tcpsock,
203*8a272653SPeter Holm	    (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0)
204*8a272653SPeter Holm		err(1, "bind(), %s:%d", __FILE__, __LINE__);
205*8a272653SPeter Holm
206*8a272653SPeter Holm	if (listen(tcpsock, 5) < 0)
207*8a272653SPeter Holm		err(1, "listen(), %s:%d", __FILE__, __LINE__);
208*8a272653SPeter Holm
209*8a272653SPeter Holm	idx = 0;
210*8a272653SPeter Holm	len = sizeof(inetpeer);
211*8a272653SPeter Holm	for (;;) {
212*8a272653SPeter Holm		alarm(600);
213*8a272653SPeter Holm		if ((msgsock = accept(tcpsock,
214*8a272653SPeter Holm		    (struct sockaddr *)&inetpeer, &len)) < 0)
215*8a272653SPeter Holm			err(1, "accept(), %s:%d", __FILE__, __LINE__);
216*8a272653SPeter Holm
217*8a272653SPeter Holm		if ((pid[idx] = fork()) == 0) {
218*8a272653SPeter Holm			t = 0;
219*8a272653SPeter Holm			if ((buf = malloc(BUFSIZE)) == NULL)
220*8a272653SPeter Holm				err(1, "malloc(%d), %s:%d", BUFSIZE,
221*8a272653SPeter Holm				    __FILE__, __LINE__);
222*8a272653SPeter Holm
223*8a272653SPeter Holm			sprintf(ofile, "%s/g%06d.%06d", todir, getpid(), idx);
224*8a272653SPeter Holm			sprintf(nfile, "%s/n%06d.%06d", todir, getpid(), idx);
225*8a272653SPeter Holm			if ((fd = open(ofile, O_RDWR | O_CREAT | O_TRUNC,
226*8a272653SPeter Holm			    0640)) == -1)
227*8a272653SPeter Holm				err(1, "open(%s)", ofile);
228*8a272653SPeter Holm
229*8a272653SPeter Holm			for (;;) {
230*8a272653SPeter Holm				if ((n = read(msgsock, buf, BUFSIZE)) < 0)
231*8a272653SPeter Holm					err(1, "read(), %s:%d", __FILE__,
232*8a272653SPeter Holm					    __LINE__);
233*8a272653SPeter Holm				t += n;
234*8a272653SPeter Holm				if (n == 0) break;
235*8a272653SPeter Holm
236*8a272653SPeter Holm				if ((write(fd, buf, n)) != n)
237*8a272653SPeter Holm					err(1, "write");
238*8a272653SPeter Holm			}
239*8a272653SPeter Holm			close(msgsock);
240*8a272653SPeter Holm			close(fd);
241*8a272653SPeter Holm			if (rename(ofile, nfile) != 0)
242*8a272653SPeter Holm				err(1, "rename(%s, %s)", ofile, nfile);
243*8a272653SPeter Holm			_exit(0);
244*8a272653SPeter Holm		}
245*8a272653SPeter Holm		close(msgsock);
246*8a272653SPeter Holm		if (++idx == files)
247*8a272653SPeter Holm			break;
248*8a272653SPeter Holm		if (idx == nitems(pid))
249*8a272653SPeter Holm			errx(1, "pid overflow");
250*8a272653SPeter Holm	}
251*8a272653SPeter Holm	for (n = 0; n < idx; n++)
252*8a272653SPeter Holm		if (waitpid(pid[n], NULL, 0) != pid[n])
253*8a272653SPeter Holm			err(1, "waitpid(%d)", pid[n]);
254*8a272653SPeter Holm
255*8a272653SPeter Holm	_exit(0);
256*8a272653SPeter Holm}
257*8a272653SPeter Holm
258*8a272653SPeter Holmstatic void
259*8a272653SPeter Holmwriter(char *inputFile) {
260*8a272653SPeter Holm	struct sockaddr_in inetaddr;
261*8a272653SPeter Holm	struct hostent *hostent;
262*8a272653SPeter Holm	struct stat statb;
263*8a272653SPeter Holm	off_t off = 0;
264*8a272653SPeter Holm	size_t size;
265*8a272653SPeter Holm	int i, fd, on, r, tcpsock;
266*8a272653SPeter Holm
267*8a272653SPeter Holm	on = 1;
268*8a272653SPeter Holm	for (i = 1; i < 5; i++) {
269*8a272653SPeter Holm		if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
270*8a272653SPeter Holm			err(1, "socket(), %s:%d", __FILE__, __LINE__);
271*8a272653SPeter Holm
272*8a272653SPeter Holm		if (setsockopt(tcpsock,
273*8a272653SPeter Holm		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
274*8a272653SPeter Holm			err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
275*8a272653SPeter Holm
276*8a272653SPeter Holm		size = getpagesize();
277*8a272653SPeter Holm		if (setsockopt(tcpsock,
278*8a272653SPeter Holm		    SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)) < 0)
279*8a272653SPeter Holm			err(1, "setsockopt(SO_SNDBUF), %s:%d", __FILE__,
280*8a272653SPeter Holm			    __LINE__);
281*8a272653SPeter Holm
282*8a272653SPeter Holm		hostent = gethostbyname ("localhost");
283*8a272653SPeter Holm		memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr,
284*8a272653SPeter Holm			sizeof (struct in_addr));
285*8a272653SPeter Holm
286*8a272653SPeter Holm		inetaddr.sin_family = AF_INET;
287*8a272653SPeter Holm		inetaddr.sin_port = htons(port);
288*8a272653SPeter Holm		inetaddr.sin_len = sizeof(inetaddr);
289*8a272653SPeter Holm
290*8a272653SPeter Holm		r = connect(tcpsock, (struct sockaddr *) &inetaddr,
291*8a272653SPeter Holm			sizeof(inetaddr));
292*8a272653SPeter Holm		if (r == 0)
293*8a272653SPeter Holm			break;
294*8a272653SPeter Holm		sleep(1);
295*8a272653SPeter Holm		close(tcpsock);
296*8a272653SPeter Holm	}
297*8a272653SPeter Holm	if (r < 0)
298*8a272653SPeter Holm		err(1, "connect(), %s:%d", __FILE__, __LINE__);
299*8a272653SPeter Holm
300*8a272653SPeter Holm        if (stat(inputFile, &statb) != 0)
301*8a272653SPeter Holm                err(1, "stat(%s)", inputFile);
302*8a272653SPeter Holm
303*8a272653SPeter Holm	if ((fd = open(inputFile, O_RDWR)) == -1)
304*8a272653SPeter Holm		err(1, "open(%s)", inputFile);
305*8a272653SPeter Holm
306*8a272653SPeter Holm	if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off,
307*8a272653SPeter Holm	    SF_NOCACHE) == -1)
308*8a272653SPeter Holm		err(1, "sendfile");
309*8a272653SPeter Holm	close(fd);
310*8a272653SPeter Holm
311*8a272653SPeter Holm	return;
312*8a272653SPeter Holm}
313*8a272653SPeter Holm
314*8a272653SPeter Holmvoid *
315*8a272653SPeter Holmmove(void *arg)
316*8a272653SPeter Holm{
317*8a272653SPeter Holm	int num;
318*8a272653SPeter Holm	char ifile[128];
319*8a272653SPeter Holm
320*8a272653SPeter Holm	setproctitle("%s", __func__);
321*8a272653SPeter Holm	while (active >= MAXTHREADS)
322*8a272653SPeter Holm		usleep(100000);
323*8a272653SPeter Holm	active++;
324*8a272653SPeter Holm	num = (int)(long)arg;
325*8a272653SPeter Holm
326*8a272653SPeter Holm	sprintf(ifile, "%s/f%06d.%06d", fromdir, getpid(), num);
327*8a272653SPeter Holm	writer(ifile);
328*8a272653SPeter Holm
329*8a272653SPeter Holm	if (unlink(ifile) != 0)
330*8a272653SPeter Holm		err(1, "unlink(%s)", ifile);
331*8a272653SPeter Holm	active--;
332*8a272653SPeter Holm
333*8a272653SPeter Holm	return (NULL);
334*8a272653SPeter Holm}
335*8a272653SPeter Holm
336*8a272653SPeter Holmint
337*8a272653SPeter Holmmain(int argc, char *argv[])
338*8a272653SPeter Holm{
339*8a272653SPeter Holm	pid_t spid;
340*8a272653SPeter Holm	pthread_t *cp;
341*8a272653SPeter Holm	size_t len, size;
342*8a272653SPeter Holm	void *vp;
343*8a272653SPeter Holm	int e, i;
344*8a272653SPeter Holm
345*8a272653SPeter Holm	setproctitle("%s", __func__);
346*8a272653SPeter Holm	if (argc != 5) {
347*8a272653SPeter Holm		fprintf(stderr,
348*8a272653SPeter Holm		    "Usage %s <port> <from dir> <to dir> <size in k>",
349*8a272653SPeter Holm		    argv[0]);
350*8a272653SPeter Holm		exit(1);
351*8a272653SPeter Holm	}
352*8a272653SPeter Holm	port = atoi(argv[1]);
353*8a272653SPeter Holm	fromdir = argv[2];
354*8a272653SPeter Holm	if (chdir(fromdir) == -1)
355*8a272653SPeter Holm		err(1, "chdir(%s)", fromdir);
356*8a272653SPeter Holm	todir = argv[3];
357*8a272653SPeter Holm	e = 0;
358*8a272653SPeter Holm	len = PAGE_SIZE;
359*8a272653SPeter Holm	if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
360*8a272653SPeter Holm	    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
361*8a272653SPeter Holm		err(1, "mmap");
362*8a272653SPeter Holm	sscanf(argv[4], "%zd", &size);
363*8a272653SPeter Holm	size = size * 1024;
364*8a272653SPeter Holm	create(fromdir, size);
365*8a272653SPeter Holm
366*8a272653SPeter Holm	if ((spid = fork()) == 0)
367*8a272653SPeter Holm		server();
368*8a272653SPeter Holm
369*8a272653SPeter Holm	cp = malloc(files * sizeof(pthread_t));
370*8a272653SPeter Holm	for (i = 0; i < files; i++) {
371*8a272653SPeter Holm		vp = (void *)(long)i;
372*8a272653SPeter Holm		if (pthread_create(&cp[i], NULL, move, vp) != 0)
373*8a272653SPeter Holm			perror("pthread_create");
374*8a272653SPeter Holm	}
375*8a272653SPeter Holm	for (i = 0; i < files; i++) {
376*8a272653SPeter Holm		pthread_join(cp[i], NULL);
377*8a272653SPeter Holm	}
378*8a272653SPeter Holm	if (waitpid(spid, NULL, 0) != spid)
379*8a272653SPeter Holm		err(1, "waitpid");
380*8a272653SPeter Holm
381*8a272653SPeter Holm	return (e);
382*8a272653SPeter Holm}
383