blob: eab4f45c7b817c9bb707aca067b96337277da3df [file] [log] [blame]
robbiew84457092003-01-10 17:48:12 +00001/* IBM Corporation */
2/* 01/02/2003 Port to LTP avenkat@us.ibm.com */
3/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
4/*
5 * Copyright (c) International Business Machines Corp., 2003
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew84457092003-01-10 17:48:12 +000021 */
22
23#define _GNU_SOURCE 1
24#include <stdio.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <sys/mman.h>
28#include <sys/wait.h>
29#include <sys/stat.h>
30#include <unistd.h>
31#include <stdlib.h>
32#include <errno.h>
33#include <sys/types.h>
34#include <limits.h>
35/***** LTP Port *****/
36#include "test.h"
37#include "usctest.h"
38#define FAILED 0
39#define PASSED 1
40
41int local_flag = PASSED;
Wanlong Gao354ebb42012-12-07 10:10:04 +080042char *TCID = "mmapstress01"; //tmnoextend
robbiew84457092003-01-10 17:48:12 +000043FILE *temp;
44int TST_TOTAL = 1;
robbiew84457092003-01-10 17:48:12 +000045
46int anyfail();
47void ok_exit();
48/***** ** ** *****/
49
50/*
51 * This test stresses mmaps, without dealing with fragments or anything!
52 * It forks a specified number of children,
53 * all of whom mmap the same file, make a given number of accesses
54 * to random pages in the map (reading & writing and comparing data).
55 * Then the child exits and the parent forks another to take its place.
56 * Each time a child is forked, it stats the file and maps the full
57 * length of the file.
58 *
59 * This program continues to run until it either receives a SIGINT,
60 * or times out (if a timeout value is specified). When either of
61 * these things happens, it cleans up its kids, then checks the
62 * file to make sure it has the correct data.
63 *
64 * usage:
65 * tmnoextend -p nprocs [-t minutes -f filesize -S sparseoffset
66 * -r -o -m -l -d]
67 * where:
68 * -p nprocs - specifies the number of mapping children
69 * to create. (nprocs + 1 children actually
70 * get created, since one is the writer child)
71 * -t minutes - specifies minutes to run. If not specified,
72 * default is to run forever until a SIGINT
73 * is received.
74 * -f filesize - initial filesize (defaults to FILESIZE)
75 * -S sparseoffset - when non-zero, causes a sparse area to
76 * be left before the data, meaning that the
77 * actual initial file size is sparseoffset +
78 * filesize. Useful for testing large files.
79 * (default is 0).
80 * -r - randomize number of pages map children check.
81 * (random % MAXLOOPS). If not specified, each
82 * child checks MAXLOOPS pages.
83 * -o - randomize offset of file to map. (default is 0)
84 * -m - do random msync/fsyncs as well
85 * -l - if set, the output file is not removed on
86 * program exit.
87 * -d - enable debug output
88 *
89 * Compile with -DLARGE_FILE to enable file sizes > 2 GB.
90 */
91
92#define MAXLOOPS 500 /* max pages for map children to write */
subrata_modakbdbaec52009-02-26 12:14:51 +000093#define FILESIZE 4096 /* initial filesize set up by parent */
robbiew84457092003-01-10 17:48:12 +000094
robbiew4be90982003-07-31 15:15:25 +000095#ifdef roundup
96#undef roundup
97#endif
robbiew84457092003-01-10 17:48:12 +000098#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
99#define min(x, y) (((x) < (y)) ? (x) : (y))
100
Wanlong Gao354ebb42012-12-07 10:10:04 +0800101extern time_t time(time_t *);
102extern char *ctime(const time_t *);
robbiew84457092003-01-10 17:48:12 +0000103extern void *malloc(size_t);
104extern long lrand48(void);
105extern void srand(unsigned);
106extern void srand48(long);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107extern int rand(void);
108extern int atoi(const char *);
robbiew84457092003-01-10 17:48:12 +0000109
Wanlong Gao354ebb42012-12-07 10:10:04 +0800110char *usage =
111 "-p nprocs [-t minutes -f filesize -S sparseoffset -r -o -m -l -d]";
robbiew84457092003-01-10 17:48:12 +0000112
113typedef unsigned char uchar_t;
114#define SIZE_MAX UINT_MAX
115
116unsigned int initrand(void);
117void finish(int sig);
118void child_mapper(char *file, unsigned procno, unsigned nprocs);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800119int fileokay(char *file, uchar_t * expbuf);
robbiew84457092003-01-10 17:48:12 +0000120int finished = 0;
121int leavefile = 0;
122
123int debug = 0;
124#ifdef LARGE_FILE
125off64_t filesize = FILESIZE;
126off64_t sparseoffset = 0;
127#else /* LARGE_FILE */
128off_t filesize = FILESIZE;
129off_t sparseoffset = 0;
130#endif /* LARGE_FILE */
131unsigned randloops = 0;
132unsigned dosync = 0;
133unsigned do_offset = 0;
134unsigned pattern = 0;
135char filename[64];
136
Wanlong Gao354ebb42012-12-07 10:10:04 +0800137int main(int argc, char *argv[])
robbiew84457092003-01-10 17:48:12 +0000138{
139 char *progname;
140 int fd;
141 int c;
142 extern char *optarg;
143 unsigned nprocs = 0;
144 unsigned procno;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800145 pid_t *pidarray = NULL;
robbiew84457092003-01-10 17:48:12 +0000146 pid_t pid;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800147 uchar_t *buf = NULL;
robbiew84457092003-01-10 17:48:12 +0000148 unsigned int seed;
149 int pagesize = sysconf(_SC_PAGE_SIZE);
subrata_modakae1b3952008-10-30 03:53:09 +0000150 float alarmtime = 0;
robbiew84457092003-01-10 17:48:12 +0000151 struct sigaction sa;
152 unsigned i;
153 int write_cnt;
154 uchar_t data;
155 int no_prob = 0;
156 int wait_stat;
157 time_t t;
158#ifdef LARGE_FILE
159 off64_t bytes_left;
160#else /* LARGE_FILE */
161 off_t bytes_left;
162#endif /* LARGE_FILE */
163
164 progname = *argv;
165 tst_tmpdir();
166 if (argc < 2) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100167 tst_brkm(TBROK, NULL, "usage: %s %s\n", progname, usage);
robbiew84457092003-01-10 17:48:12 +0000168 }
169
170 while ((c = getopt(argc, argv, "S:omdlrf:p:t:")) != -1) {
171 switch (c) {
172 case 'd':
173 debug = 1;
174 break;
175 case 't':
subrata_modakae1b3952008-10-30 03:53:09 +0000176 alarmtime = atof(optarg) * 60;
robbiew84457092003-01-10 17:48:12 +0000177 break;
178 case 'p':
179 nprocs = atoi(optarg);
180 break;
181 case 'l':
182 leavefile = 1;
183 break;
184 case 'f':
185#ifdef LARGE_FILE
186 filesize = atoll(optarg);
187#else /* LARGE_FILE */
188 filesize = atoi(optarg);
189#endif /* LARGE_FILE */
190 if (filesize < 0) {
191 (void)fprintf(stderr, "error: negative "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800192 "filesize\n");
robbiew84457092003-01-10 17:48:12 +0000193 anyfail();
194 }
195 break;
196 case 'r':
197 randloops = 1;
198 break;
199 case 'm':
200 dosync = 1;
201 break;
202 case 'o':
203 do_offset = 1;
204 break;
205 case 'S':
206#ifdef LARGE_FILE
207 sparseoffset = atoll(optarg);
208#else /* LARGE_FILE */
209 sparseoffset = atoi(optarg);
210#endif /* LARGE_FILE */
211 if (sparseoffset % pagesize != 0) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000212 fprintf(stderr,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800213 "sparseoffset must be pagesize multiple\n");
robbiew84457092003-01-10 17:48:12 +0000214 anyfail();
215 }
216 break;
217 default:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800218 (void)fprintf(stderr, "usage: %s %s\n", progname,
219 usage);
220 tst_exit();
robbiew84457092003-01-10 17:48:12 +0000221 }
222 }
223
224 /* nprocs is >= 0 since it's unsigned */
225 if (nprocs > 255) {
226 (void)fprintf(stderr, "invalid nprocs %d - (range 0-255)\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800227 nprocs);
robbiew84457092003-01-10 17:48:12 +0000228 anyfail();
229 }
230
231 (void)time(&t);
232 //(void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port
233 (void)sprintf(filename, "%sout.%d", progname, getpid());
234 seed = initrand();
235 pattern = seed & 0xff;
236
237 if (debug) {
238#ifdef LARGE_FILE
subrata_modak4bb656a2009-02-26 12:02:09 +0000239 (void)printf("creating file <%s> with %Ld bytes, pattern %d\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800240 filename, filesize, pattern);
robbiew84457092003-01-10 17:48:12 +0000241#else /* LARGE_FILE */
subrata_modak4bb656a2009-02-26 12:02:09 +0000242 (void)printf("creating file <%s> with %ld bytes, pattern %d\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800243 filename, filesize, pattern);
robbiew84457092003-01-10 17:48:12 +0000244#endif /* LARGE_FILE */
245 if (alarmtime)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800246 (void)printf("running for %f minutes\n",
247 alarmtime / 60);
robbiew84457092003-01-10 17:48:12 +0000248 else
249 (void)printf("running with no time limit\n");
250 }
251
252 /*
253 * Plan for death by signal. User may have specified
254 * a time limit, in which set an alarm and catch SIGALRM.
255 * Also catch and cleanup with SIGINT.
256 */
257 sa.sa_handler = finish;
258 sa.sa_flags = 0;
259 if (sigemptyset(&sa.sa_mask)) {
260 perror("sigemptyset error");
261 goto cleanup;
262 }
263
264 if (sigaction(SIGINT, &sa, 0) == -1) {
265 perror("sigaction error SIGINT");
266 goto cleanup;
267 }
268 if (sigaction(SIGQUIT, &sa, 0) == -1) {
269 perror("sigaction error SIGQUIT");
270 goto cleanup;
271 }
272 if (sigaction(SIGTERM, &sa, 0) == -1) {
273 perror("sigaction error SIGTERM");
274 goto cleanup;
275 }
276
277 if (alarmtime) {
278 if (sigaction(SIGALRM, &sa, 0) == -1) {
279 perror("sigaction error");
280 goto cleanup;
281 }
282 (void)alarm(alarmtime);
283 }
robbiew84457092003-01-10 17:48:12 +0000284#ifdef LARGE_FILE
Wanlong Gao354ebb42012-12-07 10:10:04 +0800285 if ((fd = open64(filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) {
robbiew84457092003-01-10 17:48:12 +0000286#else /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800287 if ((fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) {
robbiew84457092003-01-10 17:48:12 +0000288#endif /* LARGE_FILE */
289 perror("open error");
290 anyfail();
291 }
292
Cyril Hrubisd218f342014-09-23 13:14:56 +0200293 if ((buf = malloc(pagesize)) == NULL
294 || (pidarray = malloc(nprocs * sizeof(pid_t))) == NULL) {
robbiew84457092003-01-10 17:48:12 +0000295 perror("malloc error");
296 anyfail();
297 }
298
299 for (i = 0; i < nprocs; i++)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800300 *(pidarray + i) = 0;
robbiew84457092003-01-10 17:48:12 +0000301
302 for (i = 0, data = 0; i < pagesize; i++) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800303 *(buf + i) = (data + pattern) & 0xff;
robbiew84457092003-01-10 17:48:12 +0000304 if (++data == nprocs)
305 data = 0;
306 }
307#ifdef LARGE_FILE
308 if (lseek64(fd, sparseoffset, SEEK_SET) < 0) {
309#else /* LARGE_FILE */
310 if (lseek(fd, sparseoffset, SEEK_SET) < 0) {
311#endif /* LARGE_FILE */
312 perror("lseek");
313 anyfail();
314 }
315 for (bytes_left = filesize; bytes_left; bytes_left -= c) {
316 write_cnt = min(pagesize, bytes_left);
317 if ((c = write(fd, buf, write_cnt)) != write_cnt) {
318 if (c == -1) {
319 perror("write error");
320 } else {
321 (void)fprintf(stderr, "write: wrote %d of %d "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800322 "bytes\n", c, write_cnt);
robbiew84457092003-01-10 17:48:12 +0000323 }
324 (void)close(fd);
325 (void)unlink(filename);
326 anyfail();
327 }
328 }
329
330 (void)close(fd);
331
332 /*
333 * Fork off mmap children.
334 */
335 for (procno = 0; procno < nprocs; procno++) {
336 switch (pid = fork()) {
337
338 case -1:
339 perror("fork error");
340 goto cleanup;
341
342 case 0:
343 child_mapper(filename, procno, nprocs);
344 exit(0);
345
346 default:
347 pidarray[procno] = pid;
348 }
349 }
350
351 /*
352 * Now wait for children and refork them as needed.
353 */
subrata_modakbdbaec52009-02-26 12:14:51 +0000354
robbiew84457092003-01-10 17:48:12 +0000355 while (!finished) {
356 pid = wait(&wait_stat);
357 /*
358 * Block signals while processing child exit.
359 */
360
361 if (sighold(SIGALRM) || sighold(SIGINT)) {
362 perror("sighold error");
363 goto cleanup;
364 }
365
366 if (pid != -1) {
367 /*
368 * Check exit status, then refork with the
369 * appropriate procno.
370 */
subrata_modak4bb656a2009-02-26 12:02:09 +0000371 if (!WIFEXITED(wait_stat)
robbiew84457092003-01-10 17:48:12 +0000372 || WEXITSTATUS(wait_stat) != 0) {
373 (void)fprintf(stderr, "child exit with err "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800374 "<x%x>\n", wait_stat);
robbiew84457092003-01-10 17:48:12 +0000375 goto cleanup;
376 }
377 for (i = 0; i < nprocs; i++)
378 if (pid == pidarray[i])
379 break;
380 if (i == nprocs) {
381 (void)fprintf(stderr, "unknown child pid %d, "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800382 "<x%x>\n", pid, wait_stat);
robbiew84457092003-01-10 17:48:12 +0000383 goto cleanup;
384 }
385
386 if ((pid = fork()) == -1) {
387 perror("fork error");
388 pidarray[i] = 0;
389 goto cleanup;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800390 } else if (pid == 0) { /* child */
robbiew84457092003-01-10 17:48:12 +0000391 child_mapper(filename, i, nprocs);
392 exit(0);
393 } else
394 pidarray[i] = pid;
395 } else {
396 /*
397 * wait returned an error. If EINTR, then
398 * normal finish, else it's an unexpected
399 * error...
400 */
401 if (errno != EINTR || !finished) {
402 perror("unexpected wait error");
403 goto cleanup;
404 }
405 }
406 if (sigrelse(SIGALRM) || sigrelse(SIGINT)) {
407 perror("sigrelse error");
408 goto cleanup;
409 }
410 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000411
robbiew84457092003-01-10 17:48:12 +0000412 /*
413 * Finished! Check the file for sanity, then kill all
414 * the children and done!.
415 */
416
417 if (sighold(SIGALRM)) {
418 perror("sighold error");
419 goto cleanup;
420 }
421 (void)alarm(0);
422 no_prob = 1;
423
424cleanup:
425 for (i = 0; i < nprocs; i++)
426 (void)kill(pidarray[i], SIGKILL);
427
428 while (wait(&wait_stat) != -1 || errno != ECHILD)
429 continue;
430
431 if (no_prob) { /* only check file if no errors */
432 if (!fileokay(filename, buf)) {
433 (void)fprintf(stderr, "file data incorrect!\n");
434 (void)printf(" leaving file <%s>\n", filename);
435 /***** LTP Port *****/
436 local_flag = FAILED;
437 anyfail();
438 /***** ** *****/
439 } else {
440 (void)printf("file data okay\n");
441 if (!leavefile)
442 (void)unlink(filename);
443 }
444 } else
445 (void)printf(" leaving file <%s>\n", filename);
subrata_modakbdbaec52009-02-26 12:14:51 +0000446
robbiew84457092003-01-10 17:48:12 +0000447 (void)time(&t);
448 //(void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP Port
449 ok_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800450 tst_exit();
robbiew84457092003-01-10 17:48:12 +0000451}
452
robbiew84457092003-01-10 17:48:12 +0000453/*
454 * Child process that reads/writes map. The child stats the file
455 * to determine the size, maps the size of the file, then reads/writes
456 * its own locations on random pages of the map (its locations being
457 * determined based on nprocs & procno). After a specific number of
458 * iterations, it exits.
459 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800460void child_mapper(char *file, unsigned procno, unsigned nprocs)
robbiew84457092003-01-10 17:48:12 +0000461{
462#ifdef LARGE_FILE
463 struct stat64 statbuf;
464 off64_t filesize;
465 off64_t offset;
466#else /* LARGE_FILE */
467 struct stat statbuf;
468 off_t filesize;
469 off_t offset;
470#endif /* LARGE_FILE */
471 size_t validsize;
472 size_t mapsize;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800473 char *maddr = NULL, *paddr;
robbiew84457092003-01-10 17:48:12 +0000474 int fd;
475 size_t pagesize = sysconf(_SC_PAGE_SIZE);
476 unsigned randpage;
477 unsigned int seed;
478 unsigned loopcnt;
479 unsigned nloops;
subrata_modak4bb656a2009-02-26 12:02:09 +0000480 unsigned mappages;
robbiew84457092003-01-10 17:48:12 +0000481 unsigned i;
482
Wanlong Gao354ebb42012-12-07 10:10:04 +0800483 seed = initrand(); /* initialize random seed */
robbiew84457092003-01-10 17:48:12 +0000484
485#ifdef LARGE_FILE
486 if (stat64(file, &statbuf) == -1) {
487#else /* LARGE_FILE */
488 if (stat(file, &statbuf) == -1) {
489#endif /* LARGE_FILE */
490 perror("stat error");
491 anyfail();
492 }
493 filesize = statbuf.st_size;
494
495#ifdef LARGE_FILE
496 if ((fd = open64(file, O_RDWR)) == -1) {
497#else /* LARGE_FILE */
498 if ((fd = open(file, O_RDWR)) == -1) {
499#endif /* LARGE_FILE */
500 perror("open error");
501 anyfail();
502 }
503
504 if (statbuf.st_size - sparseoffset > SIZE_MAX) {
505 fprintf(stderr, "size_t overflow when setting up map\n");
506 anyfail();
507 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800508 mapsize = (size_t) (statbuf.st_size - sparseoffset);
robbiew84457092003-01-10 17:48:12 +0000509 mappages = roundup(mapsize, pagesize) / pagesize;
510 offset = sparseoffset;
511 if (do_offset) {
512 int pageoffset = lrand48() % mappages;
513 int byteoffset = pageoffset * pagesize;
514 offset += byteoffset;
515 mapsize -= byteoffset;
516 mappages -= pageoffset;
517 }
518 nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS;
519
520 if (debug) {
521#ifdef LARGE_FILE
522 (void)printf("child %d (pid %ld): seed %d, fsize %Ld, "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800523 "mapsize %d, off %Ld, loop %d\n",
524 procno, getpid(), seed, filesize, mapsize,
525 offset / pagesize, nloops);
robbiew84457092003-01-10 17:48:12 +0000526#else /* LARGE_FILE */
527 (void)printf("child %d (pid %d): seed %d, fsize %ld, "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800528 "mapsize %ld, off %ld, loop %d\n",
529 procno, getpid(), seed, filesize, (long)mapsize,
530 offset / pagesize, nloops);
robbiew84457092003-01-10 17:48:12 +0000531#endif /* LARGE_FILE */
532 }
robbiew84457092003-01-10 17:48:12 +0000533#ifdef LARGE_FILE
Wanlong Gao354ebb42012-12-07 10:10:04 +0800534 if ((maddr = mmap64(0, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED,
535 fd, offset)) == (caddr_t) - 1) {
robbiew84457092003-01-10 17:48:12 +0000536#else /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800537 if ((maddr = mmap(0, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED,
538 fd, offset)) == (caddr_t) - 1) {
robbiew84457092003-01-10 17:48:12 +0000539#endif /* LARGE_FILE */
540 perror("mmap error");
541 anyfail();
542 }
543
544 (void)close(fd);
545
546 /*
547 * Now loop read/writing random pages.
548 */
549 for (loopcnt = 0; loopcnt < nloops; loopcnt++) {
550 randpage = lrand48() % mappages;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800551 paddr = maddr + (randpage * pagesize); /* page address */
robbiew84457092003-01-10 17:48:12 +0000552
Wanlong Gao354ebb42012-12-07 10:10:04 +0800553 if (randpage < mappages - 1 || !(mapsize % pagesize))
robbiew84457092003-01-10 17:48:12 +0000554 validsize = pagesize;
555 else
556 validsize = mapsize % pagesize;
557
558 for (i = procno; i < validsize; i += nprocs) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800559 if (*((unsigned char *)(paddr + i))
robbiew84457092003-01-10 17:48:12 +0000560 != ((procno + pattern) & 0xff)) {
561 (void)fprintf(stderr, "child %d: invalid data "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800562 "<x%x>", procno,
563 *((unsigned char *)(paddr + i)));
robbiew84457092003-01-10 17:48:12 +0000564 (void)fprintf(stderr, " at pg %d off %d, exp "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800565 "<x%x>\n", randpage, i,
566 (procno + pattern) & 0xff);
robbiew84457092003-01-10 17:48:12 +0000567 anyfail();
568 }
569
570 /*
571 * Now write it.
572 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800573 *(paddr + i) = (procno + pattern) & 0xff;
robbiew84457092003-01-10 17:48:12 +0000574 }
575 }
576 if (dosync) {
577 /*
578 * Exercise msync() as well!
579 */
580 randpage = lrand48() % mappages;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800581 paddr = maddr + (randpage * pagesize); /* page address */
582 if (msync(paddr, (mappages - randpage) * pagesize,
583 MS_SYNC) == -1) {
robbiew84457092003-01-10 17:48:12 +0000584 anyfail();
585 }
586 }
Subrata Modak76a720a2010-07-03 21:08:18 +0530587 if (munmap(maddr, mapsize) == -1) {
588 perror("munmap failed");
589 local_flag = FAILED;
590 anyfail();
591 }
robbiew84457092003-01-10 17:48:12 +0000592 exit(0);
593}
594
595/*
596 * Make sure file has all the correct data.
597 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800598int fileokay(char *file, uchar_t * expbuf)
robbiew84457092003-01-10 17:48:12 +0000599{
600#ifdef LARGE_FILE
601 struct stat64 statbuf;
602#else /* LARGE_FILE */
603 struct stat statbuf;
604#endif /* LARGE_FILE */
605 size_t mapsize;
606 uchar_t *readbuf;
607 unsigned mappages;
608 unsigned pagesize = sysconf(_SC_PAGE_SIZE);
609 int fd;
610 int cnt;
611 unsigned i, j;
612
613#ifdef LARGE_FILE
614 if ((fd = open64(file, O_RDONLY)) == -1) {
615#else /* LARGE_FILE */
616 if ((fd = open(file, O_RDONLY)) == -1) {
617#endif /* LARGE_FILE */
618 perror("open error");
619 /***** LTP Port *****/
620 local_flag = FAILED;
621 anyfail();
622 /***** ** *****/
subrata_modakbdbaec52009-02-26 12:14:51 +0000623 return 0;
robbiew84457092003-01-10 17:48:12 +0000624 }
625#ifdef LARGE_FILE
626 if (fstat64(fd, &statbuf) == -1) {
627#else /* LARGE_FILE */
628 if (fstat(fd, &statbuf) == -1) {
629#endif /* LARGE_FILE */
630 perror("stat error");
631 /***** LTP Port *****/
632 local_flag = FAILED;
633 anyfail();
634 /***** ** *****/
subrata_modak43337a32009-02-26 11:43:51 +0000635 return 0;
robbiew84457092003-01-10 17:48:12 +0000636 }
637#ifdef LARGE_FILE
638 if (lseek64(fd, sparseoffset, SEEK_SET) < 0) {
639#else /* LARGE_FILE */
640 if (lseek(fd, sparseoffset, SEEK_SET) < 0) {
641#endif /* LARGE_FILE */
642 perror("lseek");
643 anyfail();
644 }
Cyril Hrubisd218f342014-09-23 13:14:56 +0200645 readbuf = malloc(pagesize);
robbiew84457092003-01-10 17:48:12 +0000646
647 if (statbuf.st_size - sparseoffset > SIZE_MAX) {
648 fprintf(stderr, "size_t overflow when setting up map\n");
649 anyfail();
650 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800651 mapsize = (size_t) (statbuf.st_size - sparseoffset);
robbiew84457092003-01-10 17:48:12 +0000652
653 mappages = roundup(mapsize, pagesize) / pagesize;
654
655 for (i = 0; i < mappages; i++) {
656 cnt = read(fd, readbuf, pagesize);
657 if (cnt == -1) {
658 perror("read error");
659 /***** LTP Port *****/
660 local_flag = FAILED;
661 anyfail();
662 /***** ** *****/
subrata_modakbdbaec52009-02-26 12:14:51 +0000663 return 0;
robbiew84457092003-01-10 17:48:12 +0000664 } else if (cnt != pagesize) {
665 /*
subrata_modak4bb656a2009-02-26 12:02:09 +0000666 * Okay if at last page in file...
robbiew84457092003-01-10 17:48:12 +0000667 */
668 if ((i * pagesize) + cnt != mapsize) {
robbiewd1d12372003-04-03 21:50:49 +0000669 (void)fprintf(stderr, "read %d of %ld bytes\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800670 (i * pagesize) + cnt,
robbiewd1d12372003-04-03 21:50:49 +0000671 (long)mapsize);
subrata_modak43337a32009-02-26 11:43:51 +0000672 return 0;
robbiew84457092003-01-10 17:48:12 +0000673 }
674 }
675 /*
676 * Compare read bytes of data.
677 */
678 for (j = 0; j < cnt; j++) {
679 if (expbuf[j] != readbuf[j]) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000680 (void)fprintf(stderr,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800681 "read bad data: exp %c got %c)",
682 expbuf[j], readbuf[j]);
robbiew84457092003-01-10 17:48:12 +0000683#ifdef LARGE_FILE
684 (void)fprintf(stderr, ", pg %d off %d, "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800685 "(fsize %Ld)\n", i, j,
686 statbuf.st_size);
robbiew84457092003-01-10 17:48:12 +0000687#else /* LARGE_FILE */
688 (void)fprintf(stderr, ", pg %d off %d, "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800689 "(fsize %ld)\n", i, j,
690 statbuf.st_size);
robbiew84457092003-01-10 17:48:12 +0000691#endif /* LARGE_FILE */
subrata_modak43337a32009-02-26 11:43:51 +0000692 return 0;
robbiew84457092003-01-10 17:48:12 +0000693 }
694 }
695 }
Subrata Modak76a720a2010-07-03 21:08:18 +0530696 close(fd);
Garrett Cooper2c282152010-12-16 00:55:50 -0800697
subrata_modak134e8962009-02-26 11:46:54 +0000698 return 1;
robbiew84457092003-01-10 17:48:12 +0000699}
700
Wanlong Gao354ebb42012-12-07 10:10:04 +0800701 /*ARGSUSED*/ void finish(int sig)
robbiew84457092003-01-10 17:48:12 +0000702{
703 finished++;
704 return;
705}
706
Wanlong Gao354ebb42012-12-07 10:10:04 +0800707unsigned int initrand(void)
robbiew84457092003-01-10 17:48:12 +0000708{
709 unsigned int seed;
710
711 /*
712 * Initialize random seed... Got this from a test written
713 * by scooter:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800714 * Use srand/rand to diffuse the information from the
715 * time and pid. If you start several processes, then
716 * the time and pid information don't provide much
717 * variation.
robbiew84457092003-01-10 17:48:12 +0000718 */
719 srand((unsigned int)getpid());
720 seed = rand();
Cyril Hrubis4e2bab82014-09-24 16:34:35 +0200721 srand((unsigned int)time(NULL));
robbiew84457092003-01-10 17:48:12 +0000722 seed = (seed ^ rand()) % 100000;
723 srand48((long int)seed);
724 return (seed);
725}
726
727/***** LTP Port *****/
728void ok_exit()
729{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800730 tst_resm(TPASS, "Test passed");
robbiew84457092003-01-10 17:48:12 +0000731 tst_rmdir();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800732 tst_exit();
robbiew84457092003-01-10 17:48:12 +0000733}
734
robbiew84457092003-01-10 17:48:12 +0000735int anyfail()
736{
Cyril Hrubis9fa8ad02014-12-16 13:20:49 +0100737 tst_brkm(TFAIL, tst_rmdir, "Test failed");
robbiew84457092003-01-10 17:48:12 +0000738}
739
Chris Dearmanec6edca2012-10-17 19:54:01 -0700740/***** ** ** *****/