blob: 96f48f9ae89c3376f02a62dc07aaeea2051469d0 [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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew176cb5c2003-01-07 20:55:22 +000019 */
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"
subrata_modak04f47a12009-09-18 17:44:08 +000073#include "libftest.h"
robbiew176cb5c2003-01-07 20:55:22 +000074
75char *TCID = "ftest07";
76int TST_TOTAL = 1;
robbiew176cb5c2003-01-07 20:55:22 +000077
78#define PASSED 1
79#define FAILED 0
80
subrata_modak04f47a12009-09-18 17:44:08 +000081#define MAXCHILD 25
robbiew176cb5c2003-01-07 20:55:22 +000082#define K_1 1024
83#define K_2 2048
84#define K_4 4096
85#define MAXIOVCNT 16
86
subrata_modak04f47a12009-09-18 17:44:08 +000087static void setup(void);
88static void runtest(void);
89static void dotest(int, int, int);
Wanlong Gao354ebb42012-12-07 10:10:04 +080090static void domisc(int, int, char *);
subrata_modak04f47a12009-09-18 17:44:08 +000091static void term(int sig);
robbiew176cb5c2003-01-07 20:55:22 +000092
Wanlong Gao354ebb42012-12-07 10:10:04 +080093static int csize; /* chunk size */
94static int iterations; /* # total iterations */
95static off64_t max_size; /* max file size */
96static int misc_intvl; /* for doing misc things; 0 ==> no */
97static int nchild; /* how many children */
98static int fd; /* file descriptor used by child */
subrata_modak04f47a12009-09-18 17:44:08 +000099static int parent_pid;
100static int pidlist[MAXCHILD];
Wanlong Gao354ebb42012-12-07 10:10:04 +0800101static char test_name[2]; /* childs test directory name */
robbiew176cb5c2003-01-07 20:55:22 +0000102
Wanlong Gao354ebb42012-12-07 10:10:04 +0800103static char fuss[MAXPATHLEN]; /* directory to do this in */
104static char homedir[MAXPATHLEN]; /* where we started */
robbiew176cb5c2003-01-07 20:55:22 +0000105
subrata_modak04f47a12009-09-18 17:44:08 +0000106static int local_flag;
robbiew176cb5c2003-01-07 20:55:22 +0000107
subrata_modak04f47a12009-09-18 17:44:08 +0000108int main(int ac, char *av[])
robbiew176cb5c2003-01-07 20:55:22 +0000109{
subrata_modak04f47a12009-09-18 17:44:08 +0000110 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200111 const char *msg;
robbiew176cb5c2003-01-07 20:55:22 +0000112
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200113 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Cyril Hrubisee7667e2014-09-24 13:14:56 +0200114 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiew176cb5c2003-01-07 20:55:22 +0000115
subrata_modak04f47a12009-09-18 17:44:08 +0000116 setup();
robbiew176cb5c2003-01-07 20:55:22 +0000117
Wanlong Gao354ebb42012-12-07 10:10:04 +0800118 for (lc = 0; TEST_LOOPING(lc); lc++) {
robbiew176cb5c2003-01-07 20:55:22 +0000119
120 local_flag = PASSED;
121
subrata_modak04f47a12009-09-18 17:44:08 +0000122 runtest();
robbiew176cb5c2003-01-07 20:55:22 +0000123
subrata_modak04f47a12009-09-18 17:44:08 +0000124 if (local_flag == PASSED)
125 tst_resm(TPASS, "Test passed.");
126 else
127 tst_resm(TFAIL, "Test failed.");
robbiew176cb5c2003-01-07 20:55:22 +0000128
Wanlong Gao354ebb42012-12-07 10:10:04 +0800129 tst_rmdir();
130 tst_exit();
robbiew176cb5c2003-01-07 20:55:22 +0000131
subrata_modak04f47a12009-09-18 17:44:08 +0000132 }
133
Garrett Cooper2c282152010-12-16 00:55:50 -0800134 tst_exit();
robbiew176cb5c2003-01-07 20:55:22 +0000135}
robbiew176cb5c2003-01-07 20:55:22 +0000136
subrata_modak04f47a12009-09-18 17:44:08 +0000137static void setup(void)
robbiew176cb5c2003-01-07 20:55:22 +0000138{
subrata_modak04f47a12009-09-18 17:44:08 +0000139 char wdbuf[MAXPATHLEN], *cwd;
robbiew176cb5c2003-01-07 20:55:22 +0000140
141 /*
142 * Make a directory to do this in; ignore error if already exists.
143 * Save starting directory.
144 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800145 if ((cwd = getcwd(homedir, sizeof(homedir))) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100146 tst_brkm(TBROK, NULL, "Failed to get corrent directory");
robbiew176cb5c2003-01-07 20:55:22 +0000147 }
148
149 parent_pid = getpid();
150 tst_tmpdir();
151 if (!fuss[0])
Wanlong Gao354ebb42012-12-07 10:10:04 +0800152 sprintf(fuss, "%s/ftest07.%d", getcwd(wdbuf, sizeof(wdbuf)),
153 getpid());
robbiew176cb5c2003-01-07 20:55:22 +0000154
155 mkdir(fuss, 0755);
156
157 if (chdir(fuss) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100158 tst_brkm(TBROK, NULL, "\tCan't chdir(%s), error %d.", fuss,
159 errno);
robbiew176cb5c2003-01-07 20:55:22 +0000160 }
161
162 /*
163 * Default values for run conditions.
164 */
165
166 iterations = 10;
167 nchild = 5;
168 csize = K_2; /* should run with 1, 2, and 4 K sizes */
169 max_size = K_1 * K_1;
170 misc_intvl = 10;
171
subrata_modak04f47a12009-09-18 17:44:08 +0000172 if (sigset(SIGTERM, term) == SIG_ERR) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800173 tst_brkm(TBROK | TERRNO, NULL, "sigset (signo=SIGTERM) failed");
robbiew176cb5c2003-01-07 20:55:22 +0000174 }
175
176}
177
subrata_modak04f47a12009-09-18 17:44:08 +0000178static void runtest(void)
robbiew176cb5c2003-01-07 20:55:22 +0000179{
Garrett Cooper7a73eab2010-11-09 22:45:42 -0800180 pid_t pid;
181 int child, count, i, nwait, status;
182
183 nwait = 0;
robbiew176cb5c2003-01-07 20:55:22 +0000184
subrata_modak04f47a12009-09-18 17:44:08 +0000185 for (i = 0; i < nchild; i++) {
robbiew176cb5c2003-01-07 20:55:22 +0000186 test_name[0] = 'a' + i;
187 test_name[1] = '\0';
Wanlong Gao354ebb42012-12-07 10:10:04 +0800188 fd = open(test_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
robbiew176cb5c2003-01-07 20:55:22 +0000189 if (fd < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100190 tst_brkm(TBROK, NULL, "\tError %d creating %s/%s.",
191 errno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800192 fuss, test_name);
robbiew176cb5c2003-01-07 20:55:22 +0000193 }
subrata_modak04f47a12009-09-18 17:44:08 +0000194
195 if ((child = fork()) == 0) {
196 dotest(nchild, i, fd);
197 tst_exit();
robbiew176cb5c2003-01-07 20:55:22 +0000198 }
199
200 close(fd);
201
202 if (child < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800203 tst_brkm(TBROK | TERRNO, NULL, "fork failed");
robbiew176cb5c2003-01-07 20:55:22 +0000204 } else {
205 pidlist[i] = child;
206 nwait++;
207 }
208 }
209
210 /*
211 * Wait for children to finish.
212 */
robbiew176cb5c2003-01-07 20:55:22 +0000213 count = 0;
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800214 while (1) {
subrata_modak04f47a12009-09-18 17:44:08 +0000215 if ((child = wait(&status)) >= 0) {
216 //tst_resm(TINFO, "\tTest{%d} exited status = 0x%x", child, status);
robbiew176cb5c2003-01-07 20:55:22 +0000217 if (status) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800218 tst_resm(TFAIL,
219 "\tTest{%d} failed, expected 0 exit.",
220 child);
robbiew176cb5c2003-01-07 20:55:22 +0000221 local_flag = FAILED;
222 }
subrata_modak04f47a12009-09-18 17:44:08 +0000223 ++count;
224 } else {
225 if (errno != EINTR)
226 break;
227 }
robbiew176cb5c2003-01-07 20:55:22 +0000228 }
229
230 /*
231 * Should have collected all children.
232 */
233
234 if (count != nwait) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 tst_resm(TFAIL, "\tWrong # children waited on, count = %d",
236 count);
robbiew176cb5c2003-01-07 20:55:22 +0000237 local_flag = FAILED;
238 }
239
240 chdir(homedir);
241
242 pid = fork();
243 if (pid < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800244 tst_brkm(TBROK | TERRNO, NULL, "fork failed");
robbiew176cb5c2003-01-07 20:55:22 +0000245 }
246
247 if (pid == 0) {
robbiew7fdd5142005-02-07 19:39:54 +0000248 execl("/bin/rm", "rm", "-rf", fuss, NULL);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800249 exit(1);
250 } else
251 wait(&status);
robbiew176cb5c2003-01-07 20:55:22 +0000252 if (status) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800253 tst_resm(TINFO, "CAUTION - ftest07, '%s' may not be removed",
254 fuss);
robbiew176cb5c2003-01-07 20:55:22 +0000255 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000256
subrata_modak04f47a12009-09-18 17:44:08 +0000257 sync();
robbiew176cb5c2003-01-07 20:55:22 +0000258}
259
260/*
261 * dotest()
262 * Children execute this.
263 *
264 * Randomly read/mod/write chunks with known pattern and check.
265 * When fill sectors, iterate.
266 */
267
268#define NMISC 4
Wanlong Gao354ebb42012-12-07 10:10:04 +0800269enum m_type { m_fsync, m_trunc, m_sync, m_fstat };
270char *m_str[] = { "fsync", "trunc", "sync", "fstat" };
robbiew176cb5c2003-01-07 20:55:22 +0000271
Wanlong Gao354ebb42012-12-07 10:10:04 +0800272int misc_cnt[NMISC]; /* counts # of each kind of misc */
273int file_max; /* file-max size */
274int nchunks;
275int last_trunc = -1;
276int tr_flag;
277enum m_type type = m_fsync;
robbiew176cb5c2003-01-07 20:55:22 +0000278
279#define CHUNK(i) (((off64_t)i) * csize)
280#define NEXTMISC ((rand() % misc_intvl) + 5)
281
subrata_modak04f47a12009-09-18 17:44:08 +0000282static void dotest(int testers, int me, int fd)
robbiew176cb5c2003-01-07 20:55:22 +0000283{
subrata_modak04f47a12009-09-18 17:44:08 +0000284 char *bits, *hold_bits;
285 char val;
286 int count, collide, chunk, whenmisc, xfr, i;
robbiew176cb5c2003-01-07 20:55:22 +0000287
288 /* Stuff for the readv call */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800289 struct iovec r_iovec[MAXIOVCNT];
290 int r_ioveclen;
robbiew176cb5c2003-01-07 20:55:22 +0000291
292 /* Stuff for the writev call */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800293 struct iovec val_iovec[MAXIOVCNT];
robbiew176cb5c2003-01-07 20:55:22 +0000294
Wanlong Gao354ebb42012-12-07 10:10:04 +0800295 struct iovec zero_iovec[MAXIOVCNT];
296 int w_ioveclen;
robbiew176cb5c2003-01-07 20:55:22 +0000297
298 nchunks = max_size / csize;
Garrett Cooperf01306b2010-11-05 11:14:08 -0700299 whenmisc = 0;
300
Wanlong Gao354ebb42012-12-07 10:10:04 +0800301 if ((bits = malloc((nchunks + 7) / 8)) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100302 tst_brkm(TBROK, NULL, "\tmalloc failed(bits)");
robbiew176cb5c2003-01-07 20:55:22 +0000303 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800304 if ((hold_bits = malloc((nchunks + 7) / 8)) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100305 tst_brkm(TBROK, NULL, "\tmalloc failed(hlod_bits)");
robbiew176cb5c2003-01-07 20:55:22 +0000306 }
307
308 /*Allocate memory for the iovec buffers and init the iovec arrays
309 */
310 r_ioveclen = w_ioveclen = csize / MAXIOVCNT;
311
Wanlong Gao354ebb42012-12-07 10:10:04 +0800312 /* Please note that the above statement implies that csize
313 * be evenly divisible by MAXIOVCNT.
314 */
robbiew176cb5c2003-01-07 20:55:22 +0000315
316 for (i = 0; i < MAXIOVCNT; i++) {
subrata_modak04f47a12009-09-18 17:44:08 +0000317 if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100318 tst_brkm(TFAIL, NULL,
319 "\tmalloc failed(r_iovec[i].iov_base)");
robbiew176cb5c2003-01-07 20:55:22 +0000320 }
321 r_iovec[i].iov_len = r_ioveclen;
322
323 /* Allocate unused memory areas between all the buffers to
324 * make things more diffult for the OS.
325 */
326
Wanlong Gao354ebb42012-12-07 10:10:04 +0800327 if (malloc((i + 1) * 8) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100328 tst_brkm(TBROK, NULL, "\tmalloc failed((i+1)*8)");
robbiew176cb5c2003-01-07 20:55:22 +0000329 }
subrata_modak04f47a12009-09-18 17:44:08 +0000330 if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) {
vapieraf64a872006-02-15 06:47:36 +0000331 tst_resm(TBROK, "\tmalloc failed(val_iovec[i]");
robbiew176cb5c2003-01-07 20:55:22 +0000332 exit(1);
333 }
334 val_iovec[i].iov_len = w_ioveclen;
Garrett Cooper2c282152010-12-16 00:55:50 -0800335
Wanlong Gao354ebb42012-12-07 10:10:04 +0800336 if (malloc((i + 1) * 8) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100337 tst_brkm(TBROK, NULL, "\tmalloc failed((i+1)*8)");
robbiew176cb5c2003-01-07 20:55:22 +0000338 }
subrata_modak04f47a12009-09-18 17:44:08 +0000339 if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100340 tst_brkm(TBROK, NULL, "\tmalloc failed(zero_iover)");
robbiew176cb5c2003-01-07 20:55:22 +0000341 }
342 zero_iovec[i].iov_len = w_ioveclen;
343
Wanlong Gao354ebb42012-12-07 10:10:04 +0800344 if (malloc((i + 1) * 8) == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100345 tst_brkm(TBROK, NULL, "\tmalloc failed((i+1)*8)");
robbiew176cb5c2003-01-07 20:55:22 +0000346 }
347 }
348 /*
349 * No init sectors; allow file to be sparse.
350 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800351 val = (64 / testers) * me + 1;
robbiew176cb5c2003-01-07 20:55:22 +0000352
subrata_modak4bb656a2009-02-26 12:02:09 +0000353 /*
354 * For each iteration:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800355 * zap bits array
356 * loop
357 * pick random chunk, read it.
358 * if corresponding bit off {
359 * verify = 0. (sparse file)
360 * ++count;
361 * } else
362 * verify = val.
363 * write "val" on it.
364 * repeat unitl count = nchunks.
365 * ++val.
366 */
robbiew176cb5c2003-01-07 20:55:22 +0000367
Wanlong Gao354ebb42012-12-07 10:10:04 +0800368 srand(getpid());
369 if (misc_intvl)
370 whenmisc = NEXTMISC;
subrata_modak04f47a12009-09-18 17:44:08 +0000371
Wanlong Gao354ebb42012-12-07 10:10:04 +0800372 while (iterations-- > 0) {
subrata_modak04f47a12009-09-18 17:44:08 +0000373 for (i = 0; i < NMISC; i++)
robbiew176cb5c2003-01-07 20:55:22 +0000374 misc_cnt[i] = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800375 ftruncate(fd, 0);
robbiew176cb5c2003-01-07 20:55:22 +0000376 file_max = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800377 memset(bits, 0, (nchunks + 7) / 8);
378 memset(hold_bits, 0, (nchunks + 7) / 8);
robbiew176cb5c2003-01-07 20:55:22 +0000379
380 /* Have to fill the val and zero iov buffers in a different manner
381 */
subrata_modak04f47a12009-09-18 17:44:08 +0000382 for (i = 0; i < MAXIOVCNT; i++) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800383 memset(val_iovec[i].iov_base, val,
384 val_iovec[i].iov_len);
385 memset(zero_iovec[i].iov_base, 0,
386 zero_iovec[i].iov_len);
robbiew176cb5c2003-01-07 20:55:22 +0000387
388 }
389 count = 0;
390 collide = 0;
subrata_modak04f47a12009-09-18 17:44:08 +0000391 while (count < nchunks) {
robbiew176cb5c2003-01-07 20:55:22 +0000392 chunk = rand() % nchunks;
393 /*
394 * Read it.
395 */
subrata_modak04f47a12009-09-18 17:44:08 +0000396 if (lseek64(fd, CHUNK(chunk), 0) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100397 tst_brkm(TFAIL,
398 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800399 "\tTest[%d]: lseek64(0) fail at %Lx, errno = %d.",
400 me, CHUNK(chunk), errno);
robbiew176cb5c2003-01-07 20:55:22 +0000401 }
402 if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100403 tst_brkm(TFAIL,
404 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800405 "\tTest[%d]: readv fail at %Lx, errno = %d.",
406 me, CHUNK(chunk), errno);
robbiew176cb5c2003-01-07 20:55:22 +0000407 }
408 /*
409 * If chunk beyond EOF just write on it.
410 * Else if bit off, haven't seen it yet.
411 * Else, have. Verify values.
412 */
413 if (CHUNK(chunk) >= file_max) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800414 bits[chunk / 8] |= (1 << (chunk % 8));
robbiew176cb5c2003-01-07 20:55:22 +0000415 ++count;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800416 } else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) {
robbiew176cb5c2003-01-07 20:55:22 +0000417 if (xfr != csize) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100418 tst_brkm(TFAIL,
419 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800420 "\tTest[%d]: xfr=%d != %d, zero read.",
421 me, xfr, csize);
robbiew176cb5c2003-01-07 20:55:22 +0000422 }
subrata_modak04f47a12009-09-18 17:44:08 +0000423 for (i = 0; i < MAXIOVCNT; i++) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800424 if (memcmp
425 (r_iovec[i].iov_base,
426 zero_iovec[i].iov_base,
427 r_iovec[i].iov_len)) {
robbiew176cb5c2003-01-07 20:55:22 +0000428 tst_resm(TFAIL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800429 "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x, should be 0.",
430 me, CHUNK(chunk), val,
431 count, xfr, file_max);
432 tst_resm(TINFO,
433 "\tTest[%d]: last_trunc = 0x%x.",
434 me, last_trunc);
robbiew176cb5c2003-01-07 20:55:22 +0000435 sync();
subrata_modak04f47a12009-09-18 17:44:08 +0000436 ft_dumpiov(&r_iovec[i]);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800437 ft_dumpbits(bits,
438 (nchunks + 7) / 8);
439 ft_orbits(hold_bits, bits,
440 (nchunks + 7) / 8);
subrata_modak04f47a12009-09-18 17:44:08 +0000441 tst_resm(TINFO, "\tHold ");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800442 ft_dumpbits(hold_bits,
443 (nchunks + 7) / 8);
robbiew176cb5c2003-01-07 20:55:22 +0000444 tst_exit();
445 }
446 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800447 bits[chunk / 8] |= (1 << (chunk % 8));
robbiew176cb5c2003-01-07 20:55:22 +0000448 ++count;
449 } else {
450 if (xfr != csize) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100451 tst_brkm(TFAIL,
452 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800453 "\tTest[%d]: xfr=%d != %d, val read.",
454 me, xfr, csize);
robbiew176cb5c2003-01-07 20:55:22 +0000455 }
456 ++collide;
subrata_modak04f47a12009-09-18 17:44:08 +0000457 for (i = 0; i < MAXIOVCNT; i++) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800458 if (memcmp
459 (r_iovec[i].iov_base,
460 val_iovec[i].iov_base,
461 r_iovec[i].iov_len)) {
462 tst_resm(TFAIL,
463 "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x.",
464 me, CHUNK(chunk), val,
465 count, xfr, file_max);
466 tst_resm(TINFO,
467 "\tTest[%d]: last_trunc = 0x%x.",
468 me, last_trunc);
robbiew176cb5c2003-01-07 20:55:22 +0000469 sync();
subrata_modak04f47a12009-09-18 17:44:08 +0000470 ft_dumpiov(&r_iovec[i]);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800471 ft_dumpbits(bits,
472 (nchunks + 7) / 8);
473 ft_orbits(hold_bits, bits,
474 (nchunks + 7) / 8);
subrata_modak04f47a12009-09-18 17:44:08 +0000475 tst_resm(TINFO, "\tHold ");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800476 ft_dumpbits(hold_bits,
477 (nchunks + 7) / 8);
robbiew176cb5c2003-01-07 20:55:22 +0000478 tst_exit();
479 }
480 }
481 }
482 /*
483 * Writev it.
484 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800485 if (lseek64(fd, -((off64_t) xfr), 1) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100486 tst_brkm(TFAIL,
487 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800488 "\tTest[%d]: lseek64(1) fail at %Lx, errno = %d.",
489 me, CHUNK(chunk), errno);
robbiew176cb5c2003-01-07 20:55:22 +0000490 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800491 if ((xfr =
492 writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
robbiew176cb5c2003-01-07 20:55:22 +0000493 if (errno == ENOSPC) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800494 tst_resm(TFAIL,
495 "\tTest[%d]: no space, exiting.",
496 me);
robbiew176cb5c2003-01-07 20:55:22 +0000497 fsync(fd);
498 tst_exit();
499 }
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100500 tst_brkm(TFAIL,
501 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800502 "\tTest[%d]: writev fail at %Lx xfr %d, errno = %d.",
503 me, CHUNK(chunk), xfr, errno);
robbiew176cb5c2003-01-07 20:55:22 +0000504 }
505 if (CHUNK(chunk) + csize > file_max)
506 file_max = CHUNK(chunk) + csize;
507 /*
508 * If hit "misc" interval, do it.
509 */
510 if (misc_intvl && --whenmisc <= 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800511 ft_orbits(hold_bits, bits, (nchunks + 7) / 8);
robbiew176cb5c2003-01-07 20:55:22 +0000512 domisc(me, fd, bits);
513 whenmisc = NEXTMISC;
514 }
515 if (count + collide > 2 * nchunks)
516 break;
517 }
518
519 /*
520 * End of iteration, maybe before doing all chunks.
521 */
robbiew176cb5c2003-01-07 20:55:22 +0000522 fsync(fd);
subrata_modak04f47a12009-09-18 17:44:08 +0000523 ++misc_cnt[m_fsync];
vapieraf64a872006-02-15 06:47:36 +0000524 //tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800525 // me, val, count, collide);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800526 //for (i = 0; i < NMISC; i++)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800527 // tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]);
robbiew176cb5c2003-01-07 20:55:22 +0000528 ++val;
529 }
robbiew176cb5c2003-01-07 20:55:22 +0000530}
531
532/*
533 * domisc()
534 * Inject misc syscalls into the thing.
535 */
subrata_modak04f47a12009-09-18 17:44:08 +0000536static void domisc(int me, int fd, char *bits)
robbiew176cb5c2003-01-07 20:55:22 +0000537{
subrata_modak04f47a12009-09-18 17:44:08 +0000538 int chunk;
539 struct stat sb;
robbiew176cb5c2003-01-07 20:55:22 +0000540
subrata_modak04f47a12009-09-18 17:44:08 +0000541 if (type > m_fstat)
robbiew176cb5c2003-01-07 20:55:22 +0000542 type = m_fsync;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800543 switch (type) {
robbiew176cb5c2003-01-07 20:55:22 +0000544 case m_fsync:
545 if (fsync(fd) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100546 tst_brkm(TFAIL, NULL, "\tTest[%d]: fsync error %d.",
547 me,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800548 errno);
robbiew176cb5c2003-01-07 20:55:22 +0000549 }
550 break;
551 case m_trunc:
552 chunk = rand() % (file_max / csize);
553 file_max = CHUNK(chunk);
554 last_trunc = file_max;
555 if (tr_flag) {
556 if (ftruncate(fd, file_max) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100557 tst_brkm(TFAIL,
558 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800559 "\tTest[%d]: ftruncate error %d @ 0x%x.",
560 me, errno, file_max);
robbiew176cb5c2003-01-07 20:55:22 +0000561 }
562 tr_flag = 0;
563 } else {
564 if (truncate(test_name, file_max) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100565 tst_brkm(TFAIL,
566 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800567 "\tTest[%d]: truncate error %d @ 0x%x.",
568 me, errno, file_max);
robbiew176cb5c2003-01-07 20:55:22 +0000569 }
570 tr_flag = 1;
571 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800572 for (; chunk % 8 != 0; chunk++)
573 bits[chunk / 8] &= ~(1 << (chunk % 8));
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800574 for (; chunk < nchunks; chunk += 8)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800575 bits[chunk / 8] = 0;
robbiew176cb5c2003-01-07 20:55:22 +0000576 break;
577 case m_sync:
578 sync();
579 break;
580 case m_fstat:
581 if (fstat(fd, &sb) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100582 tst_brkm(TFAIL, NULL, "\tTest[%d]: fstat() error %d.",
583 me,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800584 errno);
robbiew176cb5c2003-01-07 20:55:22 +0000585 }
586 if (sb.st_size != file_max) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100587 tst_brkm(TFAIL,
588 NULL, "\tTest[%d]: fstat() mismatch; st_size=%"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800589 PRIx64 ",file_max=%x.", me,
590 (int64_t) sb.st_size, file_max);
robbiew176cb5c2003-01-07 20:55:22 +0000591 }
592 break;
593 }
subrata_modak04f47a12009-09-18 17:44:08 +0000594
595 ++misc_cnt[type];
596 ++type;
robbiew176cb5c2003-01-07 20:55:22 +0000597}
598
robbiew176cb5c2003-01-07 20:55:22 +0000599/* term()
600 *
601 * This is called when a SIGTERM signal arrives.
602 */
subrata_modak04f47a12009-09-18 17:44:08 +0000603static void term(int sig LTP_ATTRIBUTE_UNUSED)
robbiew176cb5c2003-01-07 20:55:22 +0000604{
subrata_modak04f47a12009-09-18 17:44:08 +0000605 int i;
robbiew176cb5c2003-01-07 20:55:22 +0000606
vapieraf64a872006-02-15 06:47:36 +0000607 tst_resm(TINFO, "\tterm -[%d]- got sig term.", getpid());
robbiew176cb5c2003-01-07 20:55:22 +0000608
609 /*
610 * If run by hand we like to have the parent send the signal to
611 * the child processes. This makes life easy.
612 */
robbiew176cb5c2003-01-07 20:55:22 +0000613 if (parent_pid == getpid()) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800614 for (i = 0; i < nchild; i++)
subrata_modak04f47a12009-09-18 17:44:08 +0000615 if (pidlist[i])
robbiew176cb5c2003-01-07 20:55:22 +0000616 kill(pidlist[i], SIGTERM);
subrata_modak04f47a12009-09-18 17:44:08 +0000617 return;
robbiew176cb5c2003-01-07 20:55:22 +0000618 }
619
vapieraf64a872006-02-15 06:47:36 +0000620 tst_resm(TINFO, "\tunlinking '%s'", test_name);
robbiew176cb5c2003-01-07 20:55:22 +0000621
622 close(fd);
623 if (unlink(test_name))
vapieraf64a872006-02-15 06:47:36 +0000624 tst_resm(TBROK, "Unlink of '%s' failed, errno = %d.",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800625 test_name, errno);
robbiew176cb5c2003-01-07 20:55:22 +0000626 else
vapieraf64a872006-02-15 06:47:36 +0000627 tst_resm(TINFO, "Unlink of '%s' successful.", test_name);
robbiew176cb5c2003-01-07 20:55:22 +0000628
subrata_modak04f47a12009-09-18 17:44:08 +0000629 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700630}