• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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
20  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
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 #define FAILED 0
38 #define PASSED 1
39 
40 int local_flag = PASSED;
41 char *TCID = "mmapstress01";	//tmnoextend
42 FILE *temp;
43 int TST_TOTAL = 1;
44 
45 int anyfail();
46 void ok_exit();
47 /*****  **      **      *****/
48 
49 /*
50  *  This test stresses mmaps, without dealing with fragments or anything!
51  *  It forks a specified number of children,
52  *  all of whom mmap the same file, make a given number of accesses
53  *  to random pages in the map (reading & writing and comparing data).
54  *  Then the child exits and the parent forks another to take its place.
55  *  Each time a child is forked, it stats the file and maps the full
56  *  length of the file.
57  *
58  *  This program continues to run until it either receives a SIGINT,
59  *  or times out (if a timeout value is specified).  When either of
60  *  these things happens, it cleans up its kids, then checks the
61  *  file to make sure it has the correct data.
62  *
63  *  usage:
64  *	tmnoextend -p nprocs [-t minutes -f filesize -S sparseoffset
65  *			      -r -o -m -l -d]
66  *  where:
67  *	-p nprocs	- specifies the number of mapping children
68  *			  to create.  (nprocs + 1 children actually
69  *			  get created, since one is the writer child)
70  *	-t minutes	- specifies minutes to run.  If not specified,
71  *			  default is to run forever until a SIGINT
72  *			  is received.
73  *	-f filesize	- initial filesize (defaults to FILESIZE)
74  *	-S sparseoffset - when non-zero, causes a sparse area to
75  *			  be left before the data, meaning that the
76  *			  actual initial file size is sparseoffset +
77  *			  filesize.  Useful for testing large files.
78  *			  (default is 0).
79  *	-r		- randomize number of pages map children check.
80  *			  (random % MAXLOOPS).  If not specified, each
81  *			  child checks MAXLOOPS pages.
82  *	-o		- randomize offset of file to map. (default is 0)
83  *	-m		- do random msync/fsyncs as well
84  *	-l		- if set, the output file is not removed on
85  *			  program exit.
86  *	-d		- enable debug output
87  *
88  *  Compile with -DLARGE_FILE to enable file sizes > 2 GB.
89  */
90 
91 #define MAXLOOPS	500	/* max pages for map children to write */
92 #define	FILESIZE	4096	/* initial filesize set up by parent */
93 
94 #ifdef roundup
95 #undef roundup
96 #endif
97 #define roundup(x, y)	((((x)+((y)-1))/(y))*(y))
98 #define min(x, y)	(((x) < (y)) ? (x) : (y))
99 
100 extern time_t time(time_t *);
101 extern char *ctime(const time_t *);
102 extern void *malloc(size_t);
103 extern long lrand48(void);
104 extern void srand(unsigned);
105 extern void srand48(long);
106 extern int rand(void);
107 extern int atoi(const char *);
108 
109 char *usage =
110     "-p nprocs [-t minutes -f filesize -S sparseoffset -r -o -m -l -d]";
111 
112 typedef unsigned char uchar_t;
113 #define SIZE_MAX UINT_MAX
114 
115 unsigned int initrand(void);
116 void finish(int sig);
117 void child_mapper(char *file, unsigned procno, unsigned nprocs);
118 int fileokay(char *file, uchar_t * expbuf);
119 int finished = 0;
120 int leavefile = 0;
121 
122 int debug = 0;
123 #ifdef LARGE_FILE
124 off64_t filesize = FILESIZE;
125 off64_t sparseoffset = 0;
126 #else /* LARGE_FILE */
127 off_t filesize = FILESIZE;
128 off_t sparseoffset = 0;
129 #endif /* LARGE_FILE */
130 unsigned randloops = 0;
131 unsigned dosync = 0;
132 unsigned do_offset = 0;
133 unsigned pattern = 0;
134 char filename[64];
135 
main(int argc,char * argv[])136 int main(int argc, char *argv[])
137 {
138 	char *progname;
139 	int fd;
140 	int c;
141 	extern char *optarg;
142 	unsigned nprocs = 0;
143 	unsigned procno;
144 	pid_t *pidarray = NULL;
145 	pid_t pid;
146 	uchar_t *buf = NULL;
147 	unsigned int seed;
148 	int pagesize = sysconf(_SC_PAGE_SIZE);
149 	float alarmtime = 0;
150 	struct sigaction sa;
151 	unsigned i;
152 	int write_cnt;
153 	uchar_t data;
154 	int no_prob = 0;
155 	int wait_stat;
156 	time_t t;
157 #ifdef LARGE_FILE
158 	off64_t bytes_left;
159 #else /* LARGE_FILE */
160 	off_t bytes_left;
161 #endif /* LARGE_FILE */
162 
163 	progname = *argv;
164 	tst_tmpdir();
165 	if (argc < 2) {
166 		tst_brkm(TBROK, NULL, "usage: %s %s\n", progname, usage);
167 	}
168 
169 	while ((c = getopt(argc, argv, "S:omdlrf:p:t:")) != -1) {
170 		switch (c) {
171 		case 'd':
172 			debug = 1;
173 			break;
174 		case 't':
175 			alarmtime = atof(optarg) * 60;
176 			break;
177 		case 'p':
178 			nprocs = atoi(optarg);
179 			break;
180 		case 'l':
181 			leavefile = 1;
182 			break;
183 		case 'f':
184 #ifdef LARGE_FILE
185 			filesize = atoll(optarg);
186 #else /* LARGE_FILE */
187 			filesize = atoi(optarg);
188 #endif /* LARGE_FILE */
189 			if (filesize < 0) {
190 				(void)fprintf(stderr, "error: negative "
191 					      "filesize\n");
192 				anyfail();
193 			}
194 			break;
195 		case 'r':
196 			randloops = 1;
197 			break;
198 		case 'm':
199 			dosync = 1;
200 			break;
201 		case 'o':
202 			do_offset = 1;
203 			break;
204 		case 'S':
205 #ifdef LARGE_FILE
206 			sparseoffset = atoll(optarg);
207 #else /* LARGE_FILE */
208 			sparseoffset = atoi(optarg);
209 #endif /* LARGE_FILE */
210 			if (sparseoffset % pagesize != 0) {
211 				fprintf(stderr,
212 					"sparseoffset must be pagesize multiple\n");
213 				anyfail();
214 			}
215 			break;
216 		default:
217 			(void)fprintf(stderr, "usage: %s %s\n", progname,
218 				      usage);
219 			tst_exit();
220 		}
221 	}
222 
223 	/* nprocs is >= 0 since it's unsigned */
224 	if (nprocs > 255) {
225 		(void)fprintf(stderr, "invalid nprocs %d - (range 0-255)\n",
226 			      nprocs);
227 		anyfail();
228 	}
229 
230 	(void)time(&t);
231 	//(void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port
232 	(void)sprintf(filename, "%sout.%d", progname, getpid());
233 	seed = initrand();
234 	pattern = seed & 0xff;
235 
236 	if (debug) {
237 #ifdef LARGE_FILE
238 		(void)printf("creating file <%s> with %Ld bytes, pattern %d\n",
239 			     filename, filesize, pattern);
240 #else /* LARGE_FILE */
241 		(void)printf("creating file <%s> with %ld bytes, pattern %d\n",
242 			     filename, filesize, pattern);
243 #endif /* LARGE_FILE */
244 		if (alarmtime)
245 			(void)printf("running for %f minutes\n",
246 				     alarmtime / 60);
247 		else
248 			(void)printf("running with no time limit\n");
249 	}
250 
251 	/*
252 	 *  Plan for death by signal.  User may have specified
253 	 *  a time limit, in which set an alarm and catch SIGALRM.
254 	 *  Also catch and cleanup with SIGINT.
255 	 */
256 	sa.sa_handler = finish;
257 	sa.sa_flags = 0;
258 	if (sigemptyset(&sa.sa_mask)) {
259 		perror("sigemptyset error");
260 		goto cleanup;
261 	}
262 
263 	if (sigaction(SIGINT, &sa, 0) == -1) {
264 		perror("sigaction error SIGINT");
265 		goto cleanup;
266 	}
267 	if (sigaction(SIGQUIT, &sa, 0) == -1) {
268 		perror("sigaction error SIGQUIT");
269 		goto cleanup;
270 	}
271 	if (sigaction(SIGTERM, &sa, 0) == -1) {
272 		perror("sigaction error SIGTERM");
273 		goto cleanup;
274 	}
275 
276 	if (alarmtime) {
277 		if (sigaction(SIGALRM, &sa, 0) == -1) {
278 			perror("sigaction error");
279 			goto cleanup;
280 		}
281 		(void)alarm(alarmtime);
282 	}
283 #ifdef LARGE_FILE
284 	if ((fd = open64(filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) {
285 #else /* LARGE_FILE */
286 	if ((fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) {
287 #endif /* LARGE_FILE */
288 		perror("open error");
289 		anyfail();
290 	}
291 
292 	if ((buf = malloc(pagesize)) == NULL
293 	    || (pidarray = malloc(nprocs * sizeof(pid_t))) == NULL) {
294 		perror("malloc error");
295 		anyfail();
296 	}
297 
298 	for (i = 0; i < nprocs; i++)
299 		*(pidarray + i) = 0;
300 
301 	for (i = 0, data = 0; i < pagesize; i++) {
302 		*(buf + i) = (data + pattern) & 0xff;
303 		if (++data == nprocs)
304 			data = 0;
305 	}
306 #ifdef LARGE_FILE
307 	if (lseek64(fd, sparseoffset, SEEK_SET) < 0) {
308 #else /* LARGE_FILE */
309 	if (lseek(fd, sparseoffset, SEEK_SET) < 0) {
310 #endif /* LARGE_FILE */
311 		perror("lseek");
312 		anyfail();
313 	}
314 	for (bytes_left = filesize; bytes_left; bytes_left -= c) {
315 		write_cnt = min(pagesize, bytes_left);
316 		if ((c = write(fd, buf, write_cnt)) != write_cnt) {
317 			if (c == -1) {
318 				perror("write error");
319 			} else {
320 				(void)fprintf(stderr, "write: wrote %d of %d "
321 					      "bytes\n", c, write_cnt);
322 			}
323 			(void)close(fd);
324 			(void)unlink(filename);
325 			anyfail();
326 		}
327 	}
328 
329 	(void)close(fd);
330 
331 	/*
332 	 *  Fork off mmap children.
333 	 */
334 	for (procno = 0; procno < nprocs; procno++) {
335 		switch (pid = fork()) {
336 
337 		case -1:
338 			perror("fork error");
339 			goto cleanup;
340 
341 		case 0:
342 			child_mapper(filename, procno, nprocs);
343 			exit(0);
344 
345 		default:
346 			pidarray[procno] = pid;
347 		}
348 	}
349 
350 	/*
351 	 *  Now wait for children and refork them as needed.
352 	 */
353 
354 	while (!finished) {
355 		pid = wait(&wait_stat);
356 		/*
357 		 *  Block signals while processing child exit.
358 		 */
359 
360 		if (sighold(SIGALRM) || sighold(SIGINT)) {
361 			perror("sighold error");
362 			goto cleanup;
363 		}
364 
365 		if (pid != -1) {
366 			/*
367 			 *  Check exit status, then refork with the
368 			 *  appropriate procno.
369 			 */
370 			if (!WIFEXITED(wait_stat)
371 			    || WEXITSTATUS(wait_stat) != 0) {
372 				(void)fprintf(stderr, "child exit with err "
373 					      "<x%x>\n", wait_stat);
374 				goto cleanup;
375 			}
376 			for (i = 0; i < nprocs; i++)
377 				if (pid == pidarray[i])
378 					break;
379 			if (i == nprocs) {
380 				(void)fprintf(stderr, "unknown child pid %d, "
381 					      "<x%x>\n", pid, wait_stat);
382 				goto cleanup;
383 			}
384 
385 			if ((pid = fork()) == -1) {
386 				perror("fork error");
387 				pidarray[i] = 0;
388 				goto cleanup;
389 			} else if (pid == 0) {	/* child */
390 				child_mapper(filename, i, nprocs);
391 				exit(0);
392 			} else
393 				pidarray[i] = pid;
394 		} else {
395 			/*
396 			 *  wait returned an error.  If EINTR, then
397 			 *  normal finish, else it's an unexpected
398 			 *  error...
399 			 */
400 			if (errno != EINTR || !finished) {
401 				perror("unexpected wait error");
402 				goto cleanup;
403 			}
404 		}
405 		if (sigrelse(SIGALRM) || sigrelse(SIGINT)) {
406 			perror("sigrelse error");
407 			goto cleanup;
408 		}
409 	}
410 
411 	/*
412 	 *  Finished!  Check the file for sanity, then kill all
413 	 *  the children and done!.
414 	 */
415 
416 	if (sighold(SIGALRM)) {
417 		perror("sighold error");
418 		goto cleanup;
419 	}
420 	(void)alarm(0);
421 	no_prob = 1;
422 
423 cleanup:
424 	for (i = 0; i < nprocs; i++)
425 		(void)kill(pidarray[i], SIGKILL);
426 
427 	while (wait(&wait_stat) != -1 || errno != ECHILD)
428 		continue;
429 
430 	if (no_prob) {		/* only check file if no errors */
431 		if (!fileokay(filename, buf)) {
432 			(void)fprintf(stderr, "file data incorrect!\n");
433 			(void)printf("  leaving file <%s>\n", filename);
434 			/***** LTP Port *****/
435 			local_flag = FAILED;
436 			anyfail();
437 			/*****	**	*****/
438 		} else {
439 			(void)printf("file data okay\n");
440 			if (!leavefile)
441 				(void)unlink(filename);
442 		}
443 	} else
444 		(void)printf("  leaving file <%s>\n", filename);
445 
446 	(void)time(&t);
447 	//(void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP Port
448 	ok_exit();
449 	tst_exit();
450 }
451 
452 /*
453  *  Child process that reads/writes map.  The child stats the file
454  *  to determine the size, maps the size of the file, then reads/writes
455  *  its own locations on random pages of the map (its locations being
456  *  determined based on nprocs & procno).  After a specific number of
457  *  iterations, it exits.
458  */
459 void child_mapper(char *file, unsigned procno, unsigned nprocs)
460 {
461 #ifdef LARGE_FILE
462 	struct stat64 statbuf;
463 	off64_t filesize;
464 	off64_t offset;
465 #else /* LARGE_FILE */
466 	struct stat statbuf;
467 	off_t filesize;
468 	off_t offset;
469 #endif /* LARGE_FILE */
470 	size_t validsize;
471 	size_t mapsize;
472 	char *maddr = NULL, *paddr;
473 	int fd;
474 	size_t pagesize = sysconf(_SC_PAGE_SIZE);
475 	unsigned randpage;
476 	unsigned int seed;
477 	unsigned loopcnt;
478 	unsigned nloops;
479 	unsigned mappages;
480 	unsigned i;
481 
482 	seed = initrand();	/* initialize random seed */
483 
484 #ifdef LARGE_FILE
485 	if (stat64(file, &statbuf) == -1) {
486 #else /* LARGE_FILE */
487 	if (stat(file, &statbuf) == -1) {
488 #endif /* LARGE_FILE */
489 		perror("stat error");
490 		anyfail();
491 	}
492 	filesize = statbuf.st_size;
493 
494 #ifdef LARGE_FILE
495 	if ((fd = open64(file, O_RDWR)) == -1) {
496 #else /* LARGE_FILE */
497 	if ((fd = open(file, O_RDWR)) == -1) {
498 #endif /* LARGE_FILE */
499 		perror("open error");
500 		anyfail();
501 	}
502 
503 	if (statbuf.st_size - sparseoffset > SIZE_MAX) {
504 		fprintf(stderr, "size_t overflow when setting up map\n");
505 		anyfail();
506 	}
507 	mapsize = (size_t) (statbuf.st_size - sparseoffset);
508 	mappages = roundup(mapsize, pagesize) / pagesize;
509 	offset = sparseoffset;
510 	if (do_offset) {
511 		int pageoffset = lrand48() % mappages;
512 		int byteoffset = pageoffset * pagesize;
513 		offset += byteoffset;
514 		mapsize -= byteoffset;
515 		mappages -= pageoffset;
516 	}
517 	nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS;
518 
519 	if (debug) {
520 #ifdef LARGE_FILE
521 		(void)printf("child %d (pid %ld): seed %d, fsize %Ld, "
522 			     "mapsize %d, off %Ld, loop %d\n",
523 			     procno, getpid(), seed, filesize, mapsize,
524 			     offset / pagesize, nloops);
525 #else /* LARGE_FILE */
526 		(void)printf("child %d (pid %d): seed %d, fsize %ld, "
527 			     "mapsize %ld, off %ld, loop %d\n",
528 			     procno, getpid(), seed, filesize, (long)mapsize,
529 			     offset / pagesize, nloops);
530 #endif /* LARGE_FILE */
531 	}
532 #ifdef LARGE_FILE
533 	if ((maddr = mmap64(0, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED,
534 			    fd, offset)) == (caddr_t) - 1) {
535 #else /* LARGE_FILE */
536 	if ((maddr = mmap(0, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED,
537 			  fd, offset)) == (caddr_t) - 1) {
538 #endif /* LARGE_FILE */
539 		perror("mmap error");
540 		anyfail();
541 	}
542 
543 	(void)close(fd);
544 
545 	/*
546 	 *  Now loop read/writing random pages.
547 	 */
548 	for (loopcnt = 0; loopcnt < nloops; loopcnt++) {
549 		randpage = lrand48() % mappages;
550 		paddr = maddr + (randpage * pagesize);	/* page address */
551 
552 		if (randpage < mappages - 1 || !(mapsize % pagesize))
553 			validsize = pagesize;
554 		else
555 			validsize = mapsize % pagesize;
556 
557 		for (i = procno; i < validsize; i += nprocs) {
558 			if (*((unsigned char *)(paddr + i))
559 			    != ((procno + pattern) & 0xff)) {
560 				(void)fprintf(stderr, "child %d: invalid data "
561 					      "<x%x>", procno,
562 					      *((unsigned char *)(paddr + i)));
563 				(void)fprintf(stderr, " at pg %d off %d, exp "
564 					      "<x%x>\n", randpage, i,
565 					      (procno + pattern) & 0xff);
566 				anyfail();
567 			}
568 
569 			/*
570 			 *  Now write it.
571 			 */
572 			*(paddr + i) = (procno + pattern) & 0xff;
573 		}
574 	}
575 	if (dosync) {
576 		/*
577 		 * Exercise msync() as well!
578 		 */
579 		randpage = lrand48() % mappages;
580 		paddr = maddr + (randpage * pagesize);	/* page address */
581 		if (msync(paddr, (mappages - randpage) * pagesize,
582 			  MS_SYNC) == -1) {
583 			anyfail();
584 		}
585 	}
586 	if (munmap(maddr, mapsize) == -1) {
587 		perror("munmap failed");
588 		local_flag = FAILED;
589 		anyfail();
590 	}
591 	exit(0);
592 }
593 
594 /*
595  *  Make sure file has all the correct data.
596  */
597 int fileokay(char *file, uchar_t * expbuf)
598 {
599 #ifdef LARGE_FILE
600 	struct stat64 statbuf;
601 #else /* LARGE_FILE */
602 	struct stat statbuf;
603 #endif /* LARGE_FILE */
604 	size_t mapsize;
605 	unsigned mappages;
606 	unsigned pagesize = sysconf(_SC_PAGE_SIZE);
607 	uchar_t readbuf[pagesize];
608 	int fd;
609 	int cnt;
610 	unsigned i, j;
611 
612 #ifdef LARGE_FILE
613 	if ((fd = open64(file, O_RDONLY)) == -1) {
614 #else /* LARGE_FILE */
615 	if ((fd = open(file, O_RDONLY)) == -1) {
616 #endif /* LARGE_FILE */
617 		perror("open error");
618 		/***** LTP Port *****/
619 		local_flag = FAILED;
620 		anyfail();
621 		/*****	**	*****/
622 		return 0;
623 	}
624 #ifdef LARGE_FILE
625 	if (fstat64(fd, &statbuf) == -1) {
626 #else /* LARGE_FILE */
627 	if (fstat(fd, &statbuf) == -1) {
628 #endif /* LARGE_FILE */
629 		perror("stat error");
630 		/***** LTP Port *****/
631 		local_flag = FAILED;
632 		anyfail();
633 		/*****	**	*****/
634 		return 0;
635 	}
636 #ifdef LARGE_FILE
637 	if (lseek64(fd, sparseoffset, SEEK_SET) < 0) {
638 #else /* LARGE_FILE */
639 	if (lseek(fd, sparseoffset, SEEK_SET) < 0) {
640 #endif /* LARGE_FILE */
641 		perror("lseek");
642 		anyfail();
643 	}
644 
645 	if (statbuf.st_size - sparseoffset > SIZE_MAX) {
646 		fprintf(stderr, "size_t overflow when setting up map\n");
647 		anyfail();
648 	}
649 	mapsize = (size_t) (statbuf.st_size - sparseoffset);
650 
651 	mappages = roundup(mapsize, pagesize) / pagesize;
652 
653 	for (i = 0; i < mappages; i++) {
654 		cnt = read(fd, readbuf, pagesize);
655 		if (cnt == -1) {
656 			perror("read error");
657 			/***** LTP Port *****/
658 			local_flag = FAILED;
659 			anyfail();
660 			/*****	**	*****/
661 			return 0;
662 		} else if (cnt != pagesize) {
663 			/*
664 			 *  Okay if at last page in file...
665 			 */
666 			if ((i * pagesize) + cnt != mapsize) {
667 				(void)fprintf(stderr, "read %d of %ld bytes\n",
668 					      (i * pagesize) + cnt,
669 					      (long)mapsize);
670 				close(fd);
671 				return 0;
672 			}
673 		}
674 		/*
675 		 *  Compare read bytes of data.
676 		 */
677 		for (j = 0; j < cnt; j++) {
678 			if (expbuf[j] != readbuf[j]) {
679 				(void)fprintf(stderr,
680 					      "read bad data: exp %c got %c)",
681 					      expbuf[j], readbuf[j]);
682 #ifdef LARGE_FILE
683 				(void)fprintf(stderr, ", pg %d off %d, "
684 					      "(fsize %Ld)\n", i, j,
685 					      statbuf.st_size);
686 #else /* LARGE_FILE */
687 				(void)fprintf(stderr, ", pg %d off %d, "
688 					      "(fsize %ld)\n", i, j,
689 					      statbuf.st_size);
690 #endif /* LARGE_FILE */
691 				close(fd);
692 				return 0;
693 			}
694 		}
695 	}
696 	close(fd);
697 
698 	return 1;
699 }
700 
701  /*ARGSUSED*/ void finish(int sig)
702 {
703 	finished++;
704 	return;
705 }
706 
707 unsigned int initrand(void)
708 {
709 	unsigned int seed;
710 
711 	/*
712 	 *  Initialize random seed...  Got this from a test written
713 	 *  by scooter:
714 	 *      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.
718 	 */
719 	srand((unsigned int)getpid());
720 	seed = rand();
721 	srand((unsigned int)time(NULL));
722 	seed = (seed ^ rand()) % 100000;
723 	srand48((long int)seed);
724 	return (seed);
725 }
726 
727 /*****  LTP Port        *****/
728 void ok_exit(void)
729 {
730 	tst_resm(TPASS, "Test passed");
731 	tst_rmdir();
732 	tst_exit();
733 }
734 
735 int anyfail(void)
736 {
737 	tst_brkm(TFAIL, tst_rmdir, "Test failed");
738 }
739 
740 /*****  **      **      *****/
741