blob: 75aa144d63e4782789bd0a11884c1f62cf4ea7f2 [file] [log] [blame]
robbiew24e30ab2003-01-07 20:53:21 +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
robbiew24e30ab2003-01-07 20:53:21 +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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew24e30ab2003-01-07 20:53:21 +000019 */
20
21/*
22 * NAME
23 * ftest03.c -- test file I/O with readv and writev (ported from SPIE section2/filesuite/ftest4.c, by Airong Zhang)
24 *
25 * CALLS
26 * lseek, readv, writev,
27 * truncate, ftruncate, fsync, sync, fstat
28 *
29 * ALGORITHM
30 * A bitmap is used to map pieces of a file.
31 * Loop: pick a random piece of the file
32 * if we haven't seen it before make sure it is zero,
33 * write pattern
34 * if we have seen it before make sure correct pattern.
35 *
36 * This was originally written by rbk - was program tfio.c
37 * Modified by dale to integrate with test suites.
38 * Modified by G. Stevens to use readv and writev.
39 * Modofied by K. Hakim to integrate with SPIES.
40 *
41 * RESTRICTIONS
42 * 1. Runs a long time with default args - can take others on input
43 * line. Use with "term mode".
44 * If run on vax the ftruncate will not be random - will always go to
45 * start of file. NOTE: produces a very high load average!!
46 *
47 * 2. The "csize" argument must be evenly divisible by MAXIOVCNT.
48 *
49 * CAUTION!!
50 * If a file is supplied to this program with the "-f" option
51 * it will be removed with a system("rm -rf filename") call.
subrata_modakbdbaec52009-02-26 12:14:51 +000052 *
robbiew24e30ab2003-01-07 20:53:21 +000053 */
54
55#define _XOPEN_SOURCE 500
56#include <sys/types.h>
57#include <sys/param.h>
58#include <sys/wait.h>
59#include <sys/stat.h>
vapierf81795e2006-02-15 06:28:58 +000060#include <errno.h>
robbiew24e30ab2003-01-07 20:53:21 +000061#include <sys/uio.h>
62#include <fcntl.h>
subrata_modakf17ac842009-09-07 09:06:31 +000063#include <signal.h>
64#include <stdio.h>
65#include <inttypes.h>
robbiew24e30ab2003-01-07 20:53:21 +000066#include "test.h"
subrata_modak04f47a12009-09-18 17:44:08 +000067#include "libftest.h"
robbiew24e30ab2003-01-07 20:53:21 +000068
69char *TCID = "ftest03";
70int TST_TOTAL = 1;
robbiew24e30ab2003-01-07 20:53:21 +000071
72#define PASSED 1
73#define FAILED 0
74
subrata_modakf17ac842009-09-07 09:06:31 +000075static void setup(void);
76static void runtest(void);
77static void dotest(int, int, int);
Wanlong Gao354ebb42012-12-07 10:10:04 +080078static void domisc(int, int, char *);
subrata_modakf17ac842009-09-07 09:06:31 +000079static void term(int sig);
robbiew24e30ab2003-01-07 20:53:21 +000080
subrata_modak04f47a12009-09-18 17:44:08 +000081#define MAXCHILD 25
robbiew24e30ab2003-01-07 20:53:21 +000082#define K_1 1024
83#define K_2 2048
84#define K_4 4096
85#define MAXIOVCNT 16
86
Wanlong Gao354ebb42012-12-07 10:10:04 +080087static int csize; /* chunk size */
88static int iterations; /* # total iterations */
89static int max_size; /* max file size */
90static int misc_intvl; /* for doing misc things; 0 ==> no */
91static int nchild; /* how many children */
92static int fd; /* file descriptor used by child */
subrata_modak04f47a12009-09-18 17:44:08 +000093static int parent_pid;
94static int pidlist[MAXCHILD];
Wanlong Gao354ebb42012-12-07 10:10:04 +080095static char test_name[2]; /* childs test directory name */
robbiew24e30ab2003-01-07 20:53:21 +000096
Wanlong Gao354ebb42012-12-07 10:10:04 +080097static char fuss[MAXPATHLEN]; /* directory to do this in */
98static char homedir[MAXPATHLEN]; /* where we started */
robbiew24e30ab2003-01-07 20:53:21 +000099
subrata_modak04f47a12009-09-18 17:44:08 +0000100static int local_flag;
subrata_modakf17ac842009-09-07 09:06:31 +0000101
Wanlong Gao354ebb42012-12-07 10:10:04 +0800102int main(int ac, char *av[])
robbiew24e30ab2003-01-07 20:53:21 +0000103{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800104 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200105 const char *msg;
robbiew24e30ab2003-01-07 20:53:21 +0000106
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200107 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800108 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiew24e30ab2003-01-07 20:53:21 +0000109
110 setup();
subrata_modakbdbaec52009-02-26 12:14:51 +0000111
robbiew24e30ab2003-01-07 20:53:21 +0000112 for (lc = 0; TEST_LOOPING(lc); lc++) {
113
114 local_flag = PASSED;
115
Wanlong Gao354ebb42012-12-07 10:10:04 +0800116 runtest();
robbiew24e30ab2003-01-07 20:53:21 +0000117
118 if (local_flag == PASSED) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800119 tst_resm(TPASS, "Test passed.");
120 } else {
121 tst_resm(TFAIL, "Test failed.");
122 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000123
robbiew24e30ab2003-01-07 20:53:21 +0000124 tst_rmdir();
subrata_modakf17ac842009-09-07 09:06:31 +0000125 /* ??? so we are doing only one loop here ??? */
robbiew24e30ab2003-01-07 20:53:21 +0000126 tst_exit();
subrata_modakf17ac842009-09-07 09:06:31 +0000127 }
128
Garrett Cooper2c282152010-12-16 00:55:50 -0800129 tst_exit();
robbiew24e30ab2003-01-07 20:53:21 +0000130}
robbiew24e30ab2003-01-07 20:53:21 +0000131
subrata_modakf17ac842009-09-07 09:06:31 +0000132static void setup(void)
robbiew24e30ab2003-01-07 20:53:21 +0000133{
subrata_modakf17ac842009-09-07 09:06:31 +0000134 char wdbuf[MAXPATHLEN];
robbiew24e30ab2003-01-07 20:53:21 +0000135
136 /*
137 * Make a directory to do this in; ignore error if already exists.
138 * Save starting directory.
139 */
140 tst_tmpdir();
subrata_modakf17ac842009-09-07 09:06:31 +0000141
142 if (getcwd(homedir, sizeof(homedir)) == NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143 tst_brkm(TBROK | TERRNO, NULL, "getcwd() failed");
robbiew24e30ab2003-01-07 20:53:21 +0000144 }
145
146 parent_pid = getpid();
147
148 if (!fuss[0])
Wanlong Gao354ebb42012-12-07 10:10:04 +0800149 sprintf(fuss, "%s/ftest03.%d", getcwd(wdbuf, sizeof(wdbuf)),
150 getpid());
robbiew24e30ab2003-01-07 20:53:21 +0000151
152 mkdir(fuss, 0755);
153
154 if (chdir(fuss) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100155 tst_brkm(TBROK, NULL, "\tCan't chdir(%s), error %d.", fuss,
156 errno);
robbiew24e30ab2003-01-07 20:53:21 +0000157 }
158
robbiew24e30ab2003-01-07 20:53:21 +0000159 /*
160 * Default values for run conditions.
161 */
robbiew24e30ab2003-01-07 20:53:21 +0000162 iterations = 10;
163 nchild = 5;
164 csize = K_2; /* should run with 1, 2, and 4 K sizes */
165 max_size = K_1 * K_1;
166 misc_intvl = 10;
167
subrata_modakf17ac842009-09-07 09:06:31 +0000168 if (sigset(SIGTERM, term) == SIG_ERR) {
robbiew24e30ab2003-01-07 20:53:21 +0000169 perror("sigset failed");
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100170 tst_brkm(TBROK, NULL, " sigset failed: signo = 15");
robbiew24e30ab2003-01-07 20:53:21 +0000171 }
robbiew24e30ab2003-01-07 20:53:21 +0000172}
173
subrata_modakf17ac842009-09-07 09:06:31 +0000174static void runtest(void)
robbiew24e30ab2003-01-07 20:53:21 +0000175{
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800176 pid_t pid;
177 int child, count, i, nwait, status;
178
179 nwait = 0;
robbiew24e30ab2003-01-07 20:53:21 +0000180
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800181 for (i = 0; i < nchild; i++) {
subrata_modakf17ac842009-09-07 09:06:31 +0000182
robbiew24e30ab2003-01-07 20:53:21 +0000183 test_name[0] = 'a' + i;
184 test_name[1] = '\0';
subrata_modakf17ac842009-09-07 09:06:31 +0000185
Wanlong Gao354ebb42012-12-07 10:10:04 +0800186 fd = open(test_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
subrata_modakf17ac842009-09-07 09:06:31 +0000187
robbiew24e30ab2003-01-07 20:53:21 +0000188 if (fd < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100189 tst_brkm(TBROK, NULL, "\tError %d creating %s/%s.",
190 errno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800191 fuss, test_name);
robbiew24e30ab2003-01-07 20:53:21 +0000192 }
subrata_modakf17ac842009-09-07 09:06:31 +0000193
194 if ((child = fork()) == 0) {
195 dotest(nchild, i, fd);
196 tst_exit();
robbiew24e30ab2003-01-07 20:53:21 +0000197 }
198
199 close(fd);
200
201 if (child < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800202 tst_brkm(TBROK | TERRNO, NULL, "fork failed");
robbiew24e30ab2003-01-07 20:53:21 +0000203 } else {
204 pidlist[i] = child;
205 nwait++;
206 }
207 }
208
209 /*
210 * Wait for children to finish.
211 */
robbiew24e30ab2003-01-07 20:53:21 +0000212 count = 0;
subrata_modakf17ac842009-09-07 09:06:31 +0000213
214 while (1) {
215 if ((child = wait(&status)) >= 0) {
216 //tst_resm(TINFO, "\tTest{%d} exited status = 0x%x", child, status);
217 if (status) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800218 tst_resm(TFAIL,
219 "\tTest{%d} failed, expected 0 exit.",
220 child);
subrata_modakf17ac842009-09-07 09:06:31 +0000221 local_flag = FAILED;
222 }
223 ++count;
224 } else {
225 if (errno != EINTR)
226 break;
robbiew24e30ab2003-01-07 20:53:21 +0000227 }
robbiew24e30ab2003-01-07 20:53:21 +0000228 }
229
230 /*
231 * Should have collected all children.
232 */
robbiew24e30ab2003-01-07 20:53:21 +0000233 if (count != nwait) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800234 tst_resm(TFAIL, "\tWrong # children waited on, count = %d",
235 count);
robbiew24e30ab2003-01-07 20:53:21 +0000236 local_flag = FAILED;
237 }
238
239 chdir(homedir);
240
241 pid = fork();
subrata_modakf17ac842009-09-07 09:06:31 +0000242
robbiew24e30ab2003-01-07 20:53:21 +0000243 if (pid < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800244 tst_brkm(TBROK | TERRNO, sync, "fork failed");
robbiew24e30ab2003-01-07 20:53:21 +0000245 tst_exit();
246 }
247
248 if (pid == 0) {
robbiew7fdd5142005-02-07 19:39:54 +0000249 execl("/bin/rm", "rm", "-rf", fuss, NULL);
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800250 exit(1);
robbiew24e30ab2003-01-07 20:53:21 +0000251 } else
252 wait(&status);
subrata_modakf17ac842009-09-07 09:06:31 +0000253
robbiew24e30ab2003-01-07 20:53:21 +0000254 if (status) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800255 tst_resm(TINFO, "CAUTION - ftest03, '%s' may not be removed",
256 fuss);
robbiew24e30ab2003-01-07 20:53:21 +0000257 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000258
subrata_modakf17ac842009-09-07 09:06:31 +0000259 sync();
robbiew24e30ab2003-01-07 20:53:21 +0000260}
261
262/*
263 * dotest()
264 * Children execute this.
265 *
266 * Randomly read/mod/write chunks with known pattern and check.
267 * When fill sectors, iterate.
268 */
269
270#define NMISC 4
Wanlong Gao354ebb42012-12-07 10:10:04 +0800271enum m_type { m_fsync, m_trunc, m_fstat };
272char *m_str[] = {
273 "fsync", "trunc", "sync", "fstat"
robbiew24e30ab2003-01-07 20:53:21 +0000274};
275
Wanlong Gao354ebb42012-12-07 10:10:04 +0800276int misc_cnt[NMISC]; /* counts # of each kind of misc */
277int file_max; /* file-max size */
278int nchunks;
279int last_trunc = -1;
280int tr_flag;
281enum m_type type = m_fsync;
robbiew24e30ab2003-01-07 20:53:21 +0000282
283#define CHUNK(i) ((i) * csize)
284#define NEXTMISC ((rand() % misc_intvl) + 5)
285
subrata_modakf17ac842009-09-07 09:06:31 +0000286static void dotest(int testers, int me, int fd)
robbiew24e30ab2003-01-07 20:53:21 +0000287{
subrata_modakf17ac842009-09-07 09:06:31 +0000288 char *bits, *hold_bits;
289 char val;
290 int chunk, whenmisc, xfr, count, collide, i;
robbiew24e30ab2003-01-07 20:53:21 +0000291
292 /* Stuff for the readv call */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800293 struct iovec r_iovec[MAXIOVCNT];
294 int r_ioveclen;
robbiew24e30ab2003-01-07 20:53:21 +0000295
296 /* Stuff for the writev call */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800297 struct iovec val_iovec[MAXIOVCNT];
298 struct iovec zero_iovec[MAXIOVCNT];
299 int w_ioveclen;
robbiew24e30ab2003-01-07 20:53:21 +0000300
301 nchunks = max_size / csize;
Garrett Cooperf01306b2010-11-05 11:14:08 -0700302 whenmisc = 0;
subrata_modakf17ac842009-09-07 09:06:31 +0000303
Wanlong Gao354ebb42012-12-07 10:10:04 +0800304 if ((bits = malloc((nchunks + 7) / 8)) == 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100305 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000306 }
307
Wanlong Gao354ebb42012-12-07 10:10:04 +0800308 if ((hold_bits = malloc((nchunks + 7) / 8)) == 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100309 tst_brkm(TBROK, NULL, "\tmalloc failed");
subrata_modakf17ac842009-09-07 09:06:31 +0000310 }
311
Wanlong Gao354ebb42012-12-07 10:10:04 +0800312 /*Allocate memory for the iovec buffers and init the iovec arrays */
robbiew24e30ab2003-01-07 20:53:21 +0000313 r_ioveclen = w_ioveclen = csize / MAXIOVCNT;
314
subrata_modakf17ac842009-09-07 09:06:31 +0000315 /* Please note that the above statement implies that csize
316 * be evenly divisible by MAXIOVCNT.
317 */
robbiew24e30ab2003-01-07 20:53:21 +0000318 for (i = 0; i < MAXIOVCNT; i++) {
subrata_modakf17ac842009-09-07 09:06:31 +0000319 if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == 0) {
vapieraf64a872006-02-15 06:47:36 +0000320 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000321 /* tst_exit(); */
322 }
323 r_iovec[i].iov_len = r_ioveclen;
324
325 /* Allocate unused memory areas between all the buffers to
326 * make things more diffult for the OS.
327 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800328 if (malloc((i + 1) * 8) == NULL) {
329 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000330 }
subrata_modakf17ac842009-09-07 09:06:31 +0000331
332 if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100333 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000334 }
subrata_modakf17ac842009-09-07 09:06:31 +0000335
robbiew24e30ab2003-01-07 20:53:21 +0000336 val_iovec[i].iov_len = w_ioveclen;
Garrett Cooper2c282152010-12-16 00:55:50 -0800337
Wanlong Gao354ebb42012-12-07 10:10:04 +0800338 if (malloc((i + 1) * 8) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100339 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000340 }
subrata_modakf17ac842009-09-07 09:06:31 +0000341
342 if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100343 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000344 }
subrata_modakf17ac842009-09-07 09:06:31 +0000345
robbiew24e30ab2003-01-07 20:53:21 +0000346 zero_iovec[i].iov_len = w_ioveclen;
347
Wanlong Gao354ebb42012-12-07 10:10:04 +0800348 if (malloc((i + 1) * 8) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100349 tst_brkm(TBROK, NULL, "\tmalloc failed");
robbiew24e30ab2003-01-07 20:53:21 +0000350 }
351 }
352 /*
353 * No init sectors; allow file to be sparse.
354 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800355 val = (64 / testers) * me + 1;
robbiew24e30ab2003-01-07 20:53:21 +0000356
subrata_modak4bb656a2009-02-26 12:02:09 +0000357 /*
358 * For each iteration:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800359 * zap bits array
360 * loop
361 * pick random chunk, read it.
362 * if corresponding bit off {
363 * verify = 0. (sparse file)
364 * ++count;
365 * } else
366 * verify = val.
367 * write "val" on it.
368 * repeat unitl count = nchunks.
369 * ++val.
370 */
robbiew24e30ab2003-01-07 20:53:21 +0000371
subrata_modakf17ac842009-09-07 09:06:31 +0000372 srand(getpid());
373
374 if (misc_intvl)
375 whenmisc = NEXTMISC;
376
377 while (iterations-- > 0) {
378
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800379 for (i = 0; i < NMISC; i++)
robbiew24e30ab2003-01-07 20:53:21 +0000380 misc_cnt[i] = 0;
subrata_modakf17ac842009-09-07 09:06:31 +0000381
Wanlong Gao354ebb42012-12-07 10:10:04 +0800382 ftruncate(fd, 0);
robbiew24e30ab2003-01-07 20:53:21 +0000383 file_max = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800384 memset(bits, 0, (nchunks + 7) / 8);
385 memset(hold_bits, 0, (nchunks + 7) / 8);
robbiew24e30ab2003-01-07 20:53:21 +0000386
387 /* Have to fill the val and zero iov buffers in a different manner
388 */
subrata_modakf17ac842009-09-07 09:06:31 +0000389 for (i = 0; i < MAXIOVCNT; i++) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800390 memset(val_iovec[i].iov_base, val,
391 val_iovec[i].iov_len);
392 memset(zero_iovec[i].iov_base, 0,
393 zero_iovec[i].iov_len);
robbiew24e30ab2003-01-07 20:53:21 +0000394
395 }
subrata_modakf17ac842009-09-07 09:06:31 +0000396
robbiew24e30ab2003-01-07 20:53:21 +0000397 count = 0;
398 collide = 0;
subrata_modakf17ac842009-09-07 09:06:31 +0000399
400 while (count < nchunks) {
robbiew24e30ab2003-01-07 20:53:21 +0000401 chunk = rand() % nchunks;
402 /*
403 * Read it.
404 */
subrata_modakf17ac842009-09-07 09:06:31 +0000405 if (lseek(fd, CHUNK(chunk), 0) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100406 tst_brkm(TFAIL,
407 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800408 "\tTest[%d]: lseek(0) fail at %x, errno = %d.",
409 me, CHUNK(chunk), errno);
robbiew24e30ab2003-01-07 20:53:21 +0000410 }
411 if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100412 tst_brkm(TFAIL,
413 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800414 "\tTest[%d]: readv fail at %x, errno = %d.",
415 me, CHUNK(chunk), errno);
robbiew24e30ab2003-01-07 20:53:21 +0000416 }
417 /*
418 * If chunk beyond EOF just write on it.
419 * Else if bit off, haven't seen it yet.
420 * Else, have. Verify values.
421 */
422 if (CHUNK(chunk) >= file_max) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800423 bits[chunk / 8] |= (1 << (chunk % 8));
robbiew24e30ab2003-01-07 20:53:21 +0000424 ++count;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800425 } else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) {
robbiew24e30ab2003-01-07 20:53:21 +0000426 if (xfr != csize) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100427 tst_brkm(TFAIL,
428 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800429 "\tTest[%d]: xfr=%d != %d, zero read.",
430 me, xfr, csize);
robbiew24e30ab2003-01-07 20:53:21 +0000431 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800432 for (i = 0; i < MAXIOVCNT; i++) {
433 if (memcmp
434 (r_iovec[i].iov_base,
435 zero_iovec[i].iov_base,
436 r_iovec[i].iov_len)) {
robbiew24e30ab2003-01-07 20:53:21 +0000437 tst_resm(TFAIL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800438 "\tTest[%d] bad verify @ 0x%x for val %d count %d xfr %d file_max 0x%x, should be 0.",
439 me, CHUNK(chunk), val,
440 count, xfr, file_max);
441 tst_resm(TINFO,
442 "\tTest[%d]: last_trunc = 0x%x.",
443 me, last_trunc);
robbiew24e30ab2003-01-07 20:53:21 +0000444 sync();
subrata_modak04f47a12009-09-18 17:44:08 +0000445 ft_dumpiov(&r_iovec[i]);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800446 ft_dumpbits(bits,
447 (nchunks + 7) / 8);
448 ft_orbits(hold_bits, bits,
449 (nchunks + 7) / 8);
subrata_modak4bb656a2009-02-26 12:02:09 +0000450 tst_resm(TINFO, "\tHold ");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800451 ft_dumpbits(hold_bits,
452 (nchunks + 7) / 8);
robbiew24e30ab2003-01-07 20:53:21 +0000453 tst_exit();
454 }
455 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800456 bits[chunk / 8] |= (1 << (chunk % 8));
robbiew24e30ab2003-01-07 20:53:21 +0000457 ++count;
458 } else {
459 if (xfr != csize) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100460 tst_brkm(TFAIL,
461 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800462 "\tTest[%d]: xfr=%d != %d, val read.",
463 me, xfr, csize);
robbiew24e30ab2003-01-07 20:53:21 +0000464 }
465 ++collide;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800466 for (i = 0; i < MAXIOVCNT; i++) {
467 if (memcmp
468 (r_iovec[i].iov_base,
469 val_iovec[i].iov_base,
470 r_iovec[i].iov_len)) {
471 tst_resm(TFAIL,
472 "\tTest[%d] bad verify @ 0x%x for val %d count %d xfr %d file_max 0x%x.",
473 me, CHUNK(chunk), val,
474 count, xfr, file_max);
475 tst_resm(TINFO,
476 "\tTest[%d]: last_trunc = 0x%x.",
477 me, last_trunc);
robbiew24e30ab2003-01-07 20:53:21 +0000478 sync();
subrata_modak04f47a12009-09-18 17:44:08 +0000479 ft_dumpiov(&r_iovec[i]);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800480 ft_dumpbits(bits,
481 (nchunks + 7) / 8);
482 ft_orbits(hold_bits, bits,
483 (nchunks + 7) / 8);
subrata_modak4bb656a2009-02-26 12:02:09 +0000484 tst_resm(TINFO, "\tHold ");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800485 ft_dumpbits(hold_bits,
486 (nchunks + 7) / 8);
robbiew24e30ab2003-01-07 20:53:21 +0000487 tst_exit();
488 }
489 }
490 }
491 /*
492 * Writev it.
493 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800494 if (lseek(fd, -xfr, 1) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100495 tst_brkm(TFAIL,
496 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800497 "\tTest[%d]: lseek(1) fail at %x, errno = %d.",
498 me, CHUNK(chunk), errno);
robbiew24e30ab2003-01-07 20:53:21 +0000499 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800500 if ((xfr =
501 writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
robbiew24e30ab2003-01-07 20:53:21 +0000502 if (errno == ENOSPC) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800503 tst_resm(TFAIL,
504 "\tTest[%d]: no space, exiting.",
505 me);
robbiew24e30ab2003-01-07 20:53:21 +0000506 fsync(fd);
507 tst_exit();
508 }
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100509 tst_brkm(TFAIL,
510 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800511 "\tTest[%d]: writev fail at %x xfr %d, errno = %d.",
512 me, CHUNK(chunk), xfr, errno);
robbiew24e30ab2003-01-07 20:53:21 +0000513 }
514 if (CHUNK(chunk) + csize > file_max)
515 file_max = CHUNK(chunk) + csize;
516 /*
517 * If hit "misc" interval, do it.
518 */
519 if (misc_intvl && --whenmisc <= 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800520 ft_orbits(hold_bits, bits, (nchunks + 7) / 8);
robbiew24e30ab2003-01-07 20:53:21 +0000521 domisc(me, fd, bits);
522 whenmisc = NEXTMISC;
523 }
524 if (count + collide > 2 * nchunks)
525 break;
526 }
527
528 /*
529 * End of iteration, maybe before doing all chunks.
530 */
531
532 fsync(fd);
subrata_modakf17ac842009-09-07 09:06:31 +0000533 ++misc_cnt[m_fsync];
vapieraf64a872006-02-15 06:47:36 +0000534 //tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800535 // me, val, count, collide);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800536 //for (i = 0; i < NMISC; i++)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800537 // tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]);
robbiew24e30ab2003-01-07 20:53:21 +0000538 ++val;
539 }
robbiew24e30ab2003-01-07 20:53:21 +0000540}
541
542/*
robbiew24e30ab2003-01-07 20:53:21 +0000543 * Inject misc syscalls into the thing.
544 */
subrata_modakf17ac842009-09-07 09:06:31 +0000545static void domisc(int me, int fd, char *bits)
robbiew24e30ab2003-01-07 20:53:21 +0000546{
subrata_modakf17ac842009-09-07 09:06:31 +0000547 int chunk;
548 struct stat sb;
robbiew24e30ab2003-01-07 20:53:21 +0000549
subrata_modakf17ac842009-09-07 09:06:31 +0000550 if (type > m_fstat)
robbiew24e30ab2003-01-07 20:53:21 +0000551 type = m_fsync;
subrata_modakf17ac842009-09-07 09:06:31 +0000552
Wanlong Gao354ebb42012-12-07 10:10:04 +0800553 switch (type) {
robbiew24e30ab2003-01-07 20:53:21 +0000554 case m_fsync:
555 if (fsync(fd) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100556 tst_brkm(TFAIL, NULL, "\tTest[%d]: fsync error %d.",
557 me,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800558 errno);
robbiew24e30ab2003-01-07 20:53:21 +0000559 }
560 break;
561 case m_trunc:
562 chunk = rand() % (file_max / csize);
563 file_max = CHUNK(chunk);
564 last_trunc = file_max;
565 if (tr_flag) {
566 if (ftruncate(fd, file_max) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100567 tst_brkm(TFAIL,
568 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800569 "\tTest[%d]: ftruncate error %d @ 0x%x.",
570 me, errno, file_max);
robbiew24e30ab2003-01-07 20:53:21 +0000571 }
572 tr_flag = 0;
573 } else {
574 if (truncate(test_name, file_max) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100575 tst_brkm(TFAIL,
576 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800577 "\tTest[%d]: truncate error %d @ 0x%x.",
578 me, errno, file_max);
robbiew24e30ab2003-01-07 20:53:21 +0000579 }
580 tr_flag = 1;
581 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800582 for (; chunk % 8 != 0; chunk++)
583 bits[chunk / 8] &= ~(1 << (chunk % 8));
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800584 for (; chunk < nchunks; chunk += 8)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800585 bits[chunk / 8] = 0;
robbiew24e30ab2003-01-07 20:53:21 +0000586 break;
587 case m_fstat:
588 if (fstat(fd, &sb) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100589 tst_brkm(TFAIL, NULL, "\tTest[%d]: fstat() error %d.",
590 me,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800591 errno);
robbiew24e30ab2003-01-07 20:53:21 +0000592 }
593 if (sb.st_size != file_max) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100594 tst_brkm(TFAIL,
595 NULL, "\tTest[%d]: fstat() mismatch; st_size=%"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800596 PRIx64 ",file_max=%x.", me,
597 (int64_t) sb.st_size, file_max);
robbiew24e30ab2003-01-07 20:53:21 +0000598 }
599 break;
600 }
subrata_modakf17ac842009-09-07 09:06:31 +0000601
602 ++misc_cnt[type];
603 ++type;
robbiew24e30ab2003-01-07 20:53:21 +0000604}
605
subrata_modakf17ac842009-09-07 09:06:31 +0000606/*
607 * SIGTERM signal handler.
robbiew24e30ab2003-01-07 20:53:21 +0000608 */
subrata_modak04f47a12009-09-18 17:44:08 +0000609static void term(int sig LTP_ATTRIBUTE_UNUSED)
robbiew24e30ab2003-01-07 20:53:21 +0000610{
subrata_modakf17ac842009-09-07 09:06:31 +0000611 int i;
robbiew24e30ab2003-01-07 20:53:21 +0000612
vapieraf64a872006-02-15 06:47:36 +0000613 tst_resm(TINFO, "\tterm -[%d]- got sig term.", getpid());
robbiew24e30ab2003-01-07 20:53:21 +0000614
615 /*
616 * If run by hand we like to have the parent send the signal to
617 * the child processes. This makes life easy.
618 */
robbiew24e30ab2003-01-07 20:53:21 +0000619 if (parent_pid == getpid()) {
subrata_modakf17ac842009-09-07 09:06:31 +0000620 for (i = 0; i < nchild; i++)
621 if (pidlist[i])
robbiew24e30ab2003-01-07 20:53:21 +0000622 kill(pidlist[i], SIGTERM);
subrata_modakf17ac842009-09-07 09:06:31 +0000623 return;
robbiew24e30ab2003-01-07 20:53:21 +0000624 }
625
vapieraf64a872006-02-15 06:47:36 +0000626 tst_resm(TINFO, "\tunlinking '%s'", test_name);
robbiew24e30ab2003-01-07 20:53:21 +0000627
628 close(fd);
subrata_modakf17ac842009-09-07 09:06:31 +0000629
robbiew24e30ab2003-01-07 20:53:21 +0000630 if (unlink(test_name))
vapieraf64a872006-02-15 06:47:36 +0000631 tst_resm(TBROK, "Unlink of '%s' failed, errno = %d.",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800632 test_name, errno);
robbiew24e30ab2003-01-07 20:53:21 +0000633 else
vapieraf64a872006-02-15 06:47:36 +0000634 tst_resm(TBROK, "Unlink of '%s' successful.", test_name);
subrata_modakf17ac842009-09-07 09:06:31 +0000635
robbiew24e30ab2003-01-07 20:53:21 +0000636 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700637}