blob: 657d8d8af2375d6708a38a0f4ca577b8ae7557c9 [file] [log] [blame]
robbiew176cb5c2003-01-07 20:55:22 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
subrata_modak04f47a12009-09-18 17:44:08 +00004 * Copyright (c) Cyril Hrubis chrubis@suse.cz 2009
robbiew176cb5c2003-01-07 20:55:22 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * NAME
subrata_modak4bb656a2009-02-26 12:02:09 +000023 * ftest07.c -- test file I/O with readv and writev (ported from SPIE,
robbiew176cb5c2003-01-07 20:55:22 +000024 * section2/filesuite/ftest9.c
25 *
26 * this is the same as ftest4, except that it uses lseek64
27 *
28 * CALLS
29 * lseek64, readv, writev,
30 * truncate, ftruncate, fsync, sync, fstat
31 *
32 * ALGORITHM
33 * A bitmap is used to map pieces of a file.
34 * Loop: pick a random piece of the file
35 * if we haven't seen it before make sure it is zero,
36 * write pattern
37 * if we have seen it before make sure correct pattern.
38 *
39 * This was originally written by rbk - was program tfio.c
40 * Modified by dale to integrate with test suites.
41 * Modified by G. Stevens to use readv and writev.
42 * Modofied by K. Hakim to integrate with SPIES.
43 *
44 * RESTRICTIONS
45 * 1. Runs a long time with default args - can take others on input
46 * line. Use with "term mode".
47 * If run on vax the ftruncate will not be random - will always go to
48 * start of file. NOTE: produces a very high load average!!
49 *
50 * 2. The "csize" argument must be evenly divisible by MAXIOVCNT.
51 *
52 * CAUTION!!
53 * If a file is supplied to this program with the "-f" option
54 * it will be removed with a system("rm -rf filename") call.
subrata_modakbdbaec52009-02-26 12:14:51 +000055 *
robbiew176cb5c2003-01-07 20:55:22 +000056 *
57 */
58
59#define _XOPEN_SOURCE 500
subrata_modak04f47a12009-09-18 17:44:08 +000060#define _LARGEFILE64_SOURCE 1
robbiew176cb5c2003-01-07 20:55:22 +000061#include <sys/types.h>
62#include <sys/param.h>
63#include <sys/wait.h>
64#include <sys/stat.h>
vapierf81795e2006-02-15 06:28:58 +000065#include <errno.h>
robbiew176cb5c2003-01-07 20:55:22 +000066#include <sys/uio.h>
67#include <fcntl.h>
subrata_modak04f47a12009-09-18 17:44:08 +000068#include <signal.h>
69#include <stdio.h>
robbiew176cb5c2003-01-07 20:55:22 +000070#include <unistd.h>
subrata_modak04f47a12009-09-18 17:44:08 +000071#include <inttypes.h>
robbiew176cb5c2003-01-07 20:55:22 +000072#include "test.h"
73#include "usctest.h"
subrata_modak04f47a12009-09-18 17:44:08 +000074#include "libftest.h"
robbiew176cb5c2003-01-07 20:55:22 +000075
76char *TCID = "ftest07";
77int TST_TOTAL = 1;
robbiew176cb5c2003-01-07 20:55:22 +000078
79#define PASSED 1
80#define FAILED 0
81
subrata_modak04f47a12009-09-18 17:44:08 +000082#define MAXCHILD 25
robbiew176cb5c2003-01-07 20:55:22 +000083#define K_1 1024
84#define K_2 2048
85#define K_4 4096
86#define MAXIOVCNT 16
87
subrata_modak04f47a12009-09-18 17:44:08 +000088static void setup(void);
89static void runtest(void);
90static void dotest(int, int, int);
91static void domisc(int, int, char*);
92static void term(int sig);
robbiew176cb5c2003-01-07 20:55:22 +000093
subrata_modak04f47a12009-09-18 17:44:08 +000094static int csize; /* chunk size */
95static int iterations; /* # total iterations */
96static off64_t max_size; /* max file size */
97static int misc_intvl; /* for doing misc things; 0 ==> no */
98static int nchild; /* how many children */
subrata_modak04f47a12009-09-18 17:44:08 +000099static int fd; /* file descriptor used by child */
100static int parent_pid;
101static int pidlist[MAXCHILD];
102static char test_name[2]; /* childs test directory name */
robbiew176cb5c2003-01-07 20:55:22 +0000103
Garrett Cooperfde57722010-08-16 23:37:16 -0700104static char fuss[MAXPATHLEN]; /* directory to do this in */
105static char homedir[MAXPATHLEN]; /* where we started */
robbiew176cb5c2003-01-07 20:55:22 +0000106
subrata_modak04f47a12009-09-18 17:44:08 +0000107static int local_flag;
robbiew176cb5c2003-01-07 20:55:22 +0000108
subrata_modak04f47a12009-09-18 17:44:08 +0000109int main(int ac, char *av[])
robbiew176cb5c2003-01-07 20:55:22 +0000110{
subrata_modak04f47a12009-09-18 17:44:08 +0000111 int lc;
112 char *msg;
robbiew176cb5c2003-01-07 20:55:22 +0000113
subrata_modak04f47a12009-09-18 17:44:08 +0000114 /*
115 * parse standard options
116 */
117 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
118 tst_resm(TBROK, "OPTION PARSING ERROR - %s", msg);
119 tst_exit();
120 }
robbiew176cb5c2003-01-07 20:55:22 +0000121
subrata_modak04f47a12009-09-18 17:44:08 +0000122 setup();
robbiew176cb5c2003-01-07 20:55:22 +0000123
124 for (lc = 0; TEST_LOOPING(lc); lc++) {
125
126 local_flag = PASSED;
127
subrata_modak04f47a12009-09-18 17:44:08 +0000128 runtest();
robbiew176cb5c2003-01-07 20:55:22 +0000129
subrata_modak04f47a12009-09-18 17:44:08 +0000130 if (local_flag == PASSED)
131 tst_resm(TPASS, "Test passed.");
132 else
133 tst_resm(TFAIL, "Test failed.");
robbiew176cb5c2003-01-07 20:55:22 +0000134
135 tst_rmdir();
136 tst_exit();
137
subrata_modak04f47a12009-09-18 17:44:08 +0000138 }
139
Garrett Cooper2c282152010-12-16 00:55:50 -0800140 tst_exit();
robbiew176cb5c2003-01-07 20:55:22 +0000141}
robbiew176cb5c2003-01-07 20:55:22 +0000142
subrata_modak04f47a12009-09-18 17:44:08 +0000143static void setup(void)
robbiew176cb5c2003-01-07 20:55:22 +0000144{
subrata_modak04f47a12009-09-18 17:44:08 +0000145 char wdbuf[MAXPATHLEN], *cwd;
robbiew176cb5c2003-01-07 20:55:22 +0000146
147 /*
148 * Make a directory to do this in; ignore error if already exists.
149 * Save starting directory.
150 */
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800151 if ((cwd = getcwd(homedir, sizeof (homedir))) == NULL) {
subrata_modak04f47a12009-09-18 17:44:08 +0000152 tst_resm(TBROK,"Failed to get corrent directory") ;
153 tst_exit();
robbiew176cb5c2003-01-07 20:55:22 +0000154 }
155
156 parent_pid = getpid();
157 tst_tmpdir();
158 if (!fuss[0])
159 sprintf(fuss, "%s/ftest07.%d", getcwd(wdbuf, sizeof( wdbuf)), getpid());
160
161 mkdir(fuss, 0755);
162
163 if (chdir(fuss) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000164 tst_resm(TBROK,"\tCan't chdir(%s), error %d.", fuss, errno);
robbiew176cb5c2003-01-07 20:55:22 +0000165 tst_exit() ;
166 }
167
168 /*
169 * Default values for run conditions.
170 */
171
172 iterations = 10;
173 nchild = 5;
174 csize = K_2; /* should run with 1, 2, and 4 K sizes */
175 max_size = K_1 * K_1;
176 misc_intvl = 10;
177
subrata_modak04f47a12009-09-18 17:44:08 +0000178 if (sigset(SIGTERM, term) == SIG_ERR) {
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800179 tst_brkm(TBROK|TERRNO, NULL, "sigset (signo=SIGTERM) failed");
robbiew176cb5c2003-01-07 20:55:22 +0000180 }
181
182}
183
subrata_modak04f47a12009-09-18 17:44:08 +0000184static void runtest(void)
robbiew176cb5c2003-01-07 20:55:22 +0000185{
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800186 pid_t pid;
187 int child, count, i, nwait, status;
188
189 nwait = 0;
robbiew176cb5c2003-01-07 20:55:22 +0000190
subrata_modak04f47a12009-09-18 17:44:08 +0000191 for (i = 0; i < nchild; i++) {
robbiew176cb5c2003-01-07 20:55:22 +0000192 test_name[0] = 'a' + i;
193 test_name[1] = '\0';
194 fd = open(test_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
195 if (fd < 0) {
vapieraf64a872006-02-15 06:47:36 +0000196 tst_resm(TBROK, "\tError %d creating %s/%s.", errno, fuss, test_name);
robbiew176cb5c2003-01-07 20:55:22 +0000197 tst_exit();
198 }
subrata_modak04f47a12009-09-18 17:44:08 +0000199
200 if ((child = fork()) == 0) {
201 dotest(nchild, i, fd);
202 tst_exit();
robbiew176cb5c2003-01-07 20:55:22 +0000203 }
204
205 close(fd);
206
207 if (child < 0) {
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800208 tst_brkm(TBROK|TERRNO, NULL, "fork failed");
robbiew176cb5c2003-01-07 20:55:22 +0000209 } else {
210 pidlist[i] = child;
211 nwait++;
212 }
213 }
214
215 /*
216 * Wait for children to finish.
217 */
robbiew176cb5c2003-01-07 20:55:22 +0000218 count = 0;
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800219 while (1) {
subrata_modak04f47a12009-09-18 17:44:08 +0000220 if ((child = wait(&status)) >= 0) {
221 //tst_resm(TINFO, "\tTest{%d} exited status = 0x%x", child, status);
robbiew176cb5c2003-01-07 20:55:22 +0000222 if (status) {
vapieraf64a872006-02-15 06:47:36 +0000223 tst_resm(TFAIL, "\tTest{%d} failed, expected 0 exit.", child);
robbiew176cb5c2003-01-07 20:55:22 +0000224 local_flag = FAILED;
225 }
subrata_modak04f47a12009-09-18 17:44:08 +0000226 ++count;
227 } else {
228 if (errno != EINTR)
229 break;
230 }
robbiew176cb5c2003-01-07 20:55:22 +0000231 }
232
233 /*
234 * Should have collected all children.
235 */
236
237 if (count != nwait) {
vapieraf64a872006-02-15 06:47:36 +0000238 tst_resm(TFAIL, "\tWrong # children waited on, count = %d", count);
robbiew176cb5c2003-01-07 20:55:22 +0000239 local_flag = FAILED;
240 }
241
242 chdir(homedir);
243
244 pid = fork();
245 if (pid < 0) {
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800246 tst_brkm(TBROK|TERRNO, NULL, "fork failed");
robbiew176cb5c2003-01-07 20:55:22 +0000247 }
248
249 if (pid == 0) {
robbiew7fdd5142005-02-07 19:39:54 +0000250 execl("/bin/rm", "rm", "-rf", fuss, NULL);
robbiew176cb5c2003-01-07 20:55:22 +0000251 exit(1);
252 } else
253 wait(&status);
254 if (status) {
vapieraf64a872006-02-15 06:47:36 +0000255 tst_resm(TINFO, "CAUTION - ftest07, '%s' may not be removed", fuss);
robbiew176cb5c2003-01-07 20:55:22 +0000256 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000257
subrata_modak04f47a12009-09-18 17:44:08 +0000258 sync();
robbiew176cb5c2003-01-07 20:55:22 +0000259}
260
261/*
262 * dotest()
263 * Children execute this.
264 *
265 * Randomly read/mod/write chunks with known pattern and check.
266 * When fill sectors, iterate.
267 */
268
269#define NMISC 4
270enum m_type { m_fsync, m_trunc, m_sync, m_fstat };
subrata_modak04f47a12009-09-18 17:44:08 +0000271char *m_str[] = {"fsync", "trunc", "sync", "fstat"};
robbiew176cb5c2003-01-07 20:55:22 +0000272
273int misc_cnt[NMISC]; /* counts # of each kind of misc */
274int file_max; /* file-max size */
275int nchunks;
276int last_trunc = -1;
277int tr_flag;
278enum m_type type = m_fsync;
279
280#define CHUNK(i) (((off64_t)i) * csize)
281#define NEXTMISC ((rand() % misc_intvl) + 5)
282
subrata_modak04f47a12009-09-18 17:44:08 +0000283static void dotest(int testers, int me, int fd)
robbiew176cb5c2003-01-07 20:55:22 +0000284{
subrata_modak04f47a12009-09-18 17:44:08 +0000285 char *bits, *hold_bits;
286 char val;
287 int count, collide, chunk, whenmisc, xfr, i;
robbiew176cb5c2003-01-07 20:55:22 +0000288
289 /* Stuff for the readv call */
290 struct iovec r_iovec[MAXIOVCNT];
291 int r_ioveclen;
292
293 /* Stuff for the writev call */
294 struct iovec val_iovec[MAXIOVCNT];
295
296 struct iovec zero_iovec[MAXIOVCNT];
297 int w_ioveclen;
298
299 nchunks = max_size / csize;
Garrett Cooperf01306b2010-11-05 11:14:08 -0700300 whenmisc = 0;
301
subrata_modak04f47a12009-09-18 17:44:08 +0000302 if ((bits = malloc((nchunks+7) / 8)) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000303 tst_resm(TBROK, "\tmalloc failed(bits)");
robbiew176cb5c2003-01-07 20:55:22 +0000304 tst_exit();
305 }
subrata_modak04f47a12009-09-18 17:44:08 +0000306 if ((hold_bits = malloc((nchunks+7) / 8)) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000307 tst_resm(TBROK, "\tmalloc failed(hlod_bits)");
robbiew176cb5c2003-01-07 20:55:22 +0000308 tst_exit();
309 }
310
311 /*Allocate memory for the iovec buffers and init the iovec arrays
312 */
313 r_ioveclen = w_ioveclen = csize / MAXIOVCNT;
314
315 /* Please note that the above statement implies that csize
316 * be evenly divisible by MAXIOVCNT.
317 */
318
319 for (i = 0; i < MAXIOVCNT; i++) {
subrata_modak04f47a12009-09-18 17:44:08 +0000320 if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000321 tst_resm(TFAIL, "\tmalloc failed(r_iovec[i].iov_base)");
robbiew176cb5c2003-01-07 20:55:22 +0000322 tst_exit();
323 }
324 r_iovec[i].iov_len = r_ioveclen;
325
326 /* Allocate unused memory areas between all the buffers to
327 * make things more diffult for the OS.
328 */
329
subrata_modak04f47a12009-09-18 17:44:08 +0000330 if (malloc((i+1)*8) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000331 tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
robbiew176cb5c2003-01-07 20:55:22 +0000332 tst_exit();
333 }
subrata_modak04f47a12009-09-18 17:44:08 +0000334 if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000335 tst_resm(TBROK, "\tmalloc failed(val_iovec[i]");
robbiew176cb5c2003-01-07 20:55:22 +0000336 exit(1);
337 }
338 val_iovec[i].iov_len = w_ioveclen;
Garrett Cooper2c282152010-12-16 00:55:50 -0800339
subrata_modak04f47a12009-09-18 17:44:08 +0000340 if (malloc((i+1)*8) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000341 tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
robbiew176cb5c2003-01-07 20:55:22 +0000342 tst_exit();
343 }
subrata_modak04f47a12009-09-18 17:44:08 +0000344 if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000345 tst_resm(TBROK, "\tmalloc failed(zero_iover)");
robbiew176cb5c2003-01-07 20:55:22 +0000346 tst_exit();
347 }
348 zero_iovec[i].iov_len = w_ioveclen;
349
subrata_modak04f47a12009-09-18 17:44:08 +0000350 if (malloc((i+1)*8) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000351 tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
robbiew176cb5c2003-01-07 20:55:22 +0000352 tst_exit();
353 }
354 }
355 /*
356 * No init sectors; allow file to be sparse.
357 */
358 val = (64/testers) * me + 1;
359
subrata_modak4bb656a2009-02-26 12:02:09 +0000360 /*
361 * For each iteration:
362 * zap bits array
363 * loop
Garrett Cooper2c282152010-12-16 00:55:50 -0800364 * pick random chunk, read it.
subrata_modak4bb656a2009-02-26 12:02:09 +0000365 * if corresponding bit off {
robbiew176cb5c2003-01-07 20:55:22 +0000366 * verify = 0. (sparse file)
367 * ++count;
368 * } else
369 * verify = val.
370 * write "val" on it.
371 * repeat unitl count = nchunks.
372 * ++val.
373 */
374
375 srand(getpid());
subrata_modak04f47a12009-09-18 17:44:08 +0000376 if (misc_intvl)
377 whenmisc = NEXTMISC;
378
379 while (iterations-- > 0) {
380 for (i = 0; i < NMISC; i++)
robbiew176cb5c2003-01-07 20:55:22 +0000381 misc_cnt[i] = 0;
382 ftruncate(fd,0);
383 file_max = 0;
subrata_modak04f47a12009-09-18 17:44:08 +0000384 memset(bits, 0, (nchunks+7) / 8);
385 memset(hold_bits, 0, (nchunks+7) / 8);
robbiew176cb5c2003-01-07 20:55:22 +0000386
387 /* Have to fill the val and zero iov buffers in a different manner
388 */
subrata_modak04f47a12009-09-18 17:44:08 +0000389 for (i = 0; i < MAXIOVCNT; i++) {
390 memset(val_iovec[i].iov_base,val,val_iovec[i].iov_len);
391 memset(zero_iovec[i].iov_base,0,zero_iovec[i].iov_len);
robbiew176cb5c2003-01-07 20:55:22 +0000392
393 }
394 count = 0;
395 collide = 0;
subrata_modak04f47a12009-09-18 17:44:08 +0000396 while (count < nchunks) {
robbiew176cb5c2003-01-07 20:55:22 +0000397 chunk = rand() % nchunks;
398 /*
399 * Read it.
400 */
subrata_modak04f47a12009-09-18 17:44:08 +0000401 if (lseek64(fd, CHUNK(chunk), 0) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000402 tst_resm(TFAIL, "\tTest[%d]: lseek64(0) fail at %Lx, errno = %d.",
robbiew176cb5c2003-01-07 20:55:22 +0000403 me, CHUNK(chunk), errno);
404 tst_exit();
405 }
406 if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000407 tst_resm(TFAIL, "\tTest[%d]: readv fail at %Lx, errno = %d.",
robbiew176cb5c2003-01-07 20:55:22 +0000408 me, CHUNK(chunk), errno);
409 tst_exit();
410 }
411 /*
412 * If chunk beyond EOF just write on it.
413 * Else if bit off, haven't seen it yet.
414 * Else, have. Verify values.
415 */
416 if (CHUNK(chunk) >= file_max) {
417 bits[chunk/8] |= (1<<(chunk%8));
418 ++count;
419 } else if ((bits[chunk/8] & (1<<(chunk%8))) == 0) {
420 if (xfr != csize) {
vapieraf64a872006-02-15 06:47:36 +0000421 tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, zero read.",
robbiew176cb5c2003-01-07 20:55:22 +0000422 me, xfr, csize);
423 tst_exit();
424 }
subrata_modak04f47a12009-09-18 17:44:08 +0000425 for (i = 0; i < MAXIOVCNT; i++) {
robbiew176cb5c2003-01-07 20:55:22 +0000426 if (memcmp(r_iovec[i].iov_base, zero_iovec[i].iov_base, r_iovec[i].iov_len)) {
427 tst_resm(TFAIL,
vapieraf64a872006-02-15 06:47:36 +0000428 "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x, should be 0.",
robbiew176cb5c2003-01-07 20:55:22 +0000429 me, CHUNK(chunk), val, count, xfr, file_max);
vapieraf64a872006-02-15 06:47:36 +0000430 tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.",
robbiew176cb5c2003-01-07 20:55:22 +0000431 me, last_trunc);
432 sync();
subrata_modak04f47a12009-09-18 17:44:08 +0000433 ft_dumpiov(&r_iovec[i]);
434 ft_dumpbits(bits, (nchunks+7)/8);
435 ft_orbits(hold_bits, bits, (nchunks+7)/8);
436 tst_resm(TINFO, "\tHold ");
437 ft_dumpbits(hold_bits, (nchunks+7)/8);
robbiew176cb5c2003-01-07 20:55:22 +0000438 tst_exit();
439 }
440 }
441 bits[chunk/8] |= (1<<(chunk%8));
442 ++count;
443 } else {
444 if (xfr != csize) {
vapieraf64a872006-02-15 06:47:36 +0000445 tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, val read.",
robbiew176cb5c2003-01-07 20:55:22 +0000446 me, xfr, csize);
447 tst_exit();
448 }
449 ++collide;
subrata_modak04f47a12009-09-18 17:44:08 +0000450 for (i = 0; i < MAXIOVCNT; i++) {
robbiew176cb5c2003-01-07 20:55:22 +0000451 if (memcmp(r_iovec[i].iov_base, val_iovec[i].iov_base, r_iovec[i].iov_len)) {
vapieraf64a872006-02-15 06:47:36 +0000452 tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x.",
robbiew176cb5c2003-01-07 20:55:22 +0000453 me, CHUNK(chunk), val, count, xfr, file_max);
vapieraf64a872006-02-15 06:47:36 +0000454 tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.",
robbiew176cb5c2003-01-07 20:55:22 +0000455 me, last_trunc);
456 sync();
subrata_modak04f47a12009-09-18 17:44:08 +0000457 ft_dumpiov(&r_iovec[i]);
458 ft_dumpbits(bits, (nchunks+7)/8);
459 ft_orbits(hold_bits, bits, (nchunks+7)/8);
460 tst_resm(TINFO, "\tHold ");
461 ft_dumpbits(hold_bits, (nchunks+7)/8);
robbiew176cb5c2003-01-07 20:55:22 +0000462 tst_exit();
463 }
464 }
465 }
466 /*
467 * Writev it.
468 */
subrata_modak04f47a12009-09-18 17:44:08 +0000469 if (lseek64(fd, -((off64_t)xfr), 1) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000470 tst_resm(TFAIL, "\tTest[%d]: lseek64(1) fail at %Lx, errno = %d.",
robbiew176cb5c2003-01-07 20:55:22 +0000471 me, CHUNK(chunk), errno);
472 tst_exit();
473 }
474 if ((xfr = writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
475 if (errno == ENOSPC) {
vapieraf64a872006-02-15 06:47:36 +0000476 tst_resm(TFAIL, "\tTest[%d]: no space, exiting.", me);
robbiew176cb5c2003-01-07 20:55:22 +0000477 fsync(fd);
478 tst_exit();
479 }
vapieraf64a872006-02-15 06:47:36 +0000480 tst_resm(TFAIL, "\tTest[%d]: writev fail at %Lx xfr %d, errno = %d.",
robbiew176cb5c2003-01-07 20:55:22 +0000481 me, CHUNK(chunk), xfr, errno);
482 tst_exit();
483 }
484 if (CHUNK(chunk) + csize > file_max)
485 file_max = CHUNK(chunk) + csize;
486 /*
487 * If hit "misc" interval, do it.
488 */
489 if (misc_intvl && --whenmisc <= 0) {
subrata_modak04f47a12009-09-18 17:44:08 +0000490 ft_orbits(hold_bits, bits, (nchunks+7)/8);
robbiew176cb5c2003-01-07 20:55:22 +0000491 domisc(me, fd, bits);
492 whenmisc = NEXTMISC;
493 }
494 if (count + collide > 2 * nchunks)
495 break;
496 }
497
498 /*
499 * End of iteration, maybe before doing all chunks.
500 */
robbiew176cb5c2003-01-07 20:55:22 +0000501 fsync(fd);
subrata_modak04f47a12009-09-18 17:44:08 +0000502 ++misc_cnt[m_fsync];
vapieraf64a872006-02-15 06:47:36 +0000503 //tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}",
robbiew176cb5c2003-01-07 20:55:22 +0000504 // me, val, count, collide);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800505 //for (i = 0; i < NMISC; i++)
vapieraf64a872006-02-15 06:47:36 +0000506 // tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]);
robbiew176cb5c2003-01-07 20:55:22 +0000507 ++val;
508 }
robbiew176cb5c2003-01-07 20:55:22 +0000509}
510
511/*
512 * domisc()
513 * Inject misc syscalls into the thing.
514 */
subrata_modak04f47a12009-09-18 17:44:08 +0000515static void domisc(int me, int fd, char *bits)
robbiew176cb5c2003-01-07 20:55:22 +0000516{
subrata_modak04f47a12009-09-18 17:44:08 +0000517 int chunk;
518 struct stat sb;
robbiew176cb5c2003-01-07 20:55:22 +0000519
subrata_modak04f47a12009-09-18 17:44:08 +0000520 if (type > m_fstat)
robbiew176cb5c2003-01-07 20:55:22 +0000521 type = m_fsync;
522 switch(type) {
523 case m_fsync:
524 if (fsync(fd) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000525 tst_resm(TFAIL, "\tTest[%d]: fsync error %d.", me, errno);
robbiew176cb5c2003-01-07 20:55:22 +0000526 tst_exit();
527 }
528 break;
529 case m_trunc:
530 chunk = rand() % (file_max / csize);
531 file_max = CHUNK(chunk);
532 last_trunc = file_max;
533 if (tr_flag) {
534 if (ftruncate(fd, file_max) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000535 tst_resm(TFAIL, "\tTest[%d]: ftruncate error %d @ 0x%x.", me, errno, file_max);
robbiew176cb5c2003-01-07 20:55:22 +0000536 tst_exit();
537 }
538 tr_flag = 0;
539 } else {
540 if (truncate(test_name, file_max) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000541 tst_resm(TFAIL, "\tTest[%d]: truncate error %d @ 0x%x.", me, errno, file_max);
robbiew176cb5c2003-01-07 20:55:22 +0000542 tst_exit();
543 }
544 tr_flag = 1;
545 }
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800546 for (; chunk%8 != 0; chunk++)
robbiew176cb5c2003-01-07 20:55:22 +0000547 bits[chunk/8] &= ~(1<<(chunk%8));
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800548 for (; chunk < nchunks; chunk += 8)
robbiew176cb5c2003-01-07 20:55:22 +0000549 bits[chunk/8] = 0;
550 break;
551 case m_sync:
552 sync();
553 break;
554 case m_fstat:
555 if (fstat(fd, &sb) < 0) {
vapieraf64a872006-02-15 06:47:36 +0000556 tst_resm(TFAIL, "\tTest[%d]: fstat() error %d.", me, errno);
robbiew176cb5c2003-01-07 20:55:22 +0000557 tst_exit();
558 }
559 if (sb.st_size != file_max) {
subrata_modak04f47a12009-09-18 17:44:08 +0000560 tst_resm(TFAIL, "\tTest[%d]: fstat() mismatch; st_size=%"PRIx64",file_max=%x.",
561 me, (int64_t)sb.st_size, file_max);
robbiew176cb5c2003-01-07 20:55:22 +0000562 tst_exit();
563 }
564 break;
565 }
subrata_modak04f47a12009-09-18 17:44:08 +0000566
567 ++misc_cnt[type];
568 ++type;
robbiew176cb5c2003-01-07 20:55:22 +0000569}
570
robbiew176cb5c2003-01-07 20:55:22 +0000571/* term()
572 *
573 * This is called when a SIGTERM signal arrives.
574 */
subrata_modak04f47a12009-09-18 17:44:08 +0000575static void term(int sig LTP_ATTRIBUTE_UNUSED)
robbiew176cb5c2003-01-07 20:55:22 +0000576{
subrata_modak04f47a12009-09-18 17:44:08 +0000577 int i;
robbiew176cb5c2003-01-07 20:55:22 +0000578
vapieraf64a872006-02-15 06:47:36 +0000579 tst_resm(TINFO, "\tterm -[%d]- got sig term.", getpid());
robbiew176cb5c2003-01-07 20:55:22 +0000580
581 /*
582 * If run by hand we like to have the parent send the signal to
583 * the child processes. This makes life easy.
584 */
robbiew176cb5c2003-01-07 20:55:22 +0000585 if (parent_pid == getpid()) {
586 for (i=0; i < nchild; i++)
subrata_modak04f47a12009-09-18 17:44:08 +0000587 if (pidlist[i])
robbiew176cb5c2003-01-07 20:55:22 +0000588 kill(pidlist[i], SIGTERM);
subrata_modak04f47a12009-09-18 17:44:08 +0000589 return;
robbiew176cb5c2003-01-07 20:55:22 +0000590 }
591
vapieraf64a872006-02-15 06:47:36 +0000592 tst_resm(TINFO, "\tunlinking '%s'", test_name);
robbiew176cb5c2003-01-07 20:55:22 +0000593
594 close(fd);
595 if (unlink(test_name))
vapieraf64a872006-02-15 06:47:36 +0000596 tst_resm(TBROK, "Unlink of '%s' failed, errno = %d.",
robbiew176cb5c2003-01-07 20:55:22 +0000597 test_name, errno);
598 else
vapieraf64a872006-02-15 06:47:36 +0000599 tst_resm(TINFO, "Unlink of '%s' successful.", test_name);
robbiew176cb5c2003-01-07 20:55:22 +0000600
subrata_modak04f47a12009-09-18 17:44:08 +0000601 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800602}