• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2002
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /* 11/01/2002	Port to LTP	robbiew@us.ibm.com */
21 /* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
22 
23 			   /*inode02.c */
24 /*======================================================================
25 	=================== TESTPLAN SEGMENT ===================
26 CALLS:	mkdir, stat, open
27 
28 	Run with TERM mode.
29 
30 >KEYS:  < file system and I/O management, system resource constraints.
31 >WHAT:  < Can the system handle a heavy load on the file system I/O
32 	< functions?
33 >HOW:   < Create several identical process that call inode02.c.  This
34 	< will simulate the multi-user environment, and hopefully uncover
35 	< conflicts that might occur in "real life" use.
36 >BUGS:  <
37 ======================================================================*/
38 
39 #define PATH_STRING_LENGTH  1024
40 #define NAME_LENGTH  8
41 #define MAX_PATH_STRING_LENGTH  (PATH_STRING_LENGTH - NAME_LENGTH - 40)
42 #define DIRECTORY_MODE  00777
43 #define FILE_MODE       00777
44 
45 #define MKDIR_STRING_LENGTH  (MAX_PATH_STRING_LENGTH + 7)
46 
47 /* #define DEBUG	 you can watch the generation with this flag */
48 
49 #define TRUE  1
50 #define FALSE 0
51 #define READ  0
52 #define WRITE 1
53 
54 #include <stdio.h>
55 #include <errno.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 #include <signal.h>
59 #include <fcntl.h>
60 #include <errno.h>
61 #include <sys/wait.h>
62 
63 #ifdef LINUX
64 #include <stdlib.h>
65 #include <unistd.h>
66 #include <string.h>
67 #endif
68 
69 #define MAXCHILD	25
70 int allchild[MAXCHILD + 1];
71 
72 char name[NAME_LENGTH + 1];
73 char path_string[PATH_STRING_LENGTH + 1];
74 char read_string[PATH_STRING_LENGTH + 1];
75 char write_string[PATH_STRING_LENGTH + 1];
76 char remove_string[PATH_STRING_LENGTH + 10];
77 int parent_pid;
78 int nchild;
79 
80 FILE *list_stream = NULL;
81 int list_id;
82 int file_id;
83 
84 int increment_name(), get_next_name(), mode(), escrivez(), massmurder();
85 int max_depth, max_breadth, file_length;
86 int bd_arg(char *);
87 
88 #ifdef LINUX
89 void (*sigset(int, void (*)(int))) (int);
90 #endif
91 
92 /** LTP Port **/
93 #include "test.h"
94 
95 void setup(void);
96 void fail_exit(void);
97 void anyfail(void);
98 void ok_exit(void);
99 void forkfail(void);
100 void terror(char *);
101 int instress(void);
102 
103 #define FAILED 0
104 #define PASSED 1
105 
106 int local_flag = PASSED;
107 FILE *temp;
108 
109 char *TCID = "inode02";		/* Test program identifier.    */
110 int TST_TOTAL = 1;		/* Total number of test cases. */
111 /**************/
112 
main(int argc,char * argv[])113 int main(int argc, char *argv[])
114 {
115 	int pid, tree(), p, status;
116 	int count, child;
117 	register int i;
118 	int term();
119 
120 	setup();
121 
122 	parent_pid = getpid();
123 
124 	if (sigset(SIGTERM, (void (*)())term) == SIG_ERR) {
125 		tst_resm(TBROK, "\tSIGTERM sigset set failed, errno=%d\n",
126 			 errno);
127 		exit(1);
128 	}
129 
130 	/************************************************/
131 	/*                                              */
132 	/*  Input the parameters for the directory---   */
133 	/*  file trees which are to be generated        */
134 	/*                                              */
135 	/************************************************/
136 
137 	if (argc < 2) {
138 		max_depth = 6;
139 		max_breadth = 5;
140 		file_length = 8;
141 		nchild = 5;
142 	} else if (argc < 5) {
143 		tst_resm(TCONF, "Bad argument count.\n");
144 		printf
145 		    ("\tinode02 max_depth max_breadth file_length #children\n\tdefault: inode02 6 5 8 5\n");
146 		exit(1);
147 	} else {
148 		i = 1;
149 		if (sscanf(argv[i++], "%d", &max_depth) != 1)
150 			bd_arg(argv[i - 1]);
151 		if (sscanf(argv[i++], "%d", &max_breadth) != 1)
152 			bd_arg(argv[i - 1]);
153 		if (sscanf(argv[i++], "%d", &file_length) != 1)
154 			bd_arg(argv[i - 1]);
155 		if (sscanf(argv[i++], "%d", &nchild) != 1)
156 			bd_arg(argv[i - 1]);
157 		if (nchild > MAXCHILD) {
158 			fprintf(temp, "too many children - max is %d\n",
159 				MAXCHILD);
160 			exit(1);
161 		}
162 	}
163 
164 	/************************************************/
165 	/*                                              */
166 	/*  Generate and check nchild trees             */
167 	/*                                              */
168 	/************************************************/
169 
170 	for (p = 0; p < nchild; p++) {
171 		pid = fork();
172 		if (pid == 0) {
173 			tree();
174 		} else {
175 			if (pid < 1) {
176 				terror
177 				    ("Fork failed (may be OK if under stress)");
178 				massmurder();
179 				if (instress()) {
180 					ok_exit();
181 				}
182 				forkfail();
183 			}
184 		}
185 	}
186 
187 	count = 0;
188 	while ((child = wait(&status)) > 0) {
189 #ifdef DEBUG
190 		tst_resm(TINFO, "Test %d exited status = %d\n", child, status);
191 #endif
192 		if (status) {
193 			fprintf(temp, "Test %d failed - expected 0 exit.\n",
194 				child);
195 			local_flag = FAILED;
196 		}
197 		count++;
198 	}
199 
200 	if (count != nchild) {
201 		tst_resm(TFAIL, "Wrong number of children waited on!\n");
202 		tst_resm(TFAIL, "Saw %d, expected %d\n", count, nchild);
203 		local_flag = FAILED;
204 	}
205 
206 	/************************************************/
207 	/*                                              */
208 	/*  And report the results..........            */
209 	/*                                              */
210 	/************************************************/
211 
212 	anyfail();
213 	/** NOT REACHED **/
214 	tst_exit();
215 }
216 
bd_arg(char * str)217 int bd_arg(char *str)
218 {
219 	fprintf(temp,
220 		"Bad argument - %s - could not parse as number.\n\tinode02 [max_depth] [max_breadth] [file_length] [#children]\n\tdefault: inode02 6 5 8 5\n",
221 		str);
222 	exit(1);
223 }
224 
tree(void)225 int tree(void)
226 
227 /************************************************/
228 /*						*/
229 /*  		      TREE			*/
230 /*						*/
231 /*   generate a tree of directories and files   */
232 /*   and save the path names in the path_list	*/
233 /*   file 					*/
234 /*						*/
235 /*   then, read the path names and attempt to   */
236 /*   access the corresponding directories and	*/
237 /*   files					*/
238 /*						*/
239 /************************************************/
240 {
241 	int gen_ret_val, ch_ret_val, exit_val, level;
242 	int ret_val;
243 	int generate(), check();
244 	char path_list_string[PATH_STRING_LENGTH + 10];
245 	int len;
246 	int status;
247 	int snp_ret;
248 
249 	/********************************/
250 	/*                              */
251 	/*  make the root directory for */
252 	/*  the tree                    */
253 	/*                              */
254 	/********************************/
255 
256 	sprintf(path_string, "inode02.%d", getpid());
257 
258 	ret_val = mkdir(path_string, DIRECTORY_MODE);
259 
260 	if (ret_val == -1) {
261 		tst_resm(TBROK,
262 			 "Reason: Impossible to create directory %s, errno=%d\n",
263 			 path_string, errno);
264 		exit(-5);
265 	}
266 
267 	strcpy(remove_string, "rm -rf ");
268 	strcat(remove_string, path_string);
269 
270 #ifdef DEBUG
271 	tst_resm(TINFO, "\n%s\n", path_string);
272 #endif
273 
274 	/****************************************/
275 	/*                                      */
276 	/*  create the "path_list" file, in     */
277 	/*  which the list of generated paths   */
278 	/*  will be stored so that they later   */
279 	/*  may be checked                      */
280 	/*                                      */
281 	/****************************************/
282 
283 	snp_ret = snprintf(path_list_string, sizeof(path_list_string),
284 		"%s/path_list",	path_string);
285 	if (snp_ret < 0 || snp_ret >= sizeof(path_list_string)) {
286 		tst_resm(TBROK, "snprintf(path_list_string,..) returned %d",
287 			snp_ret);
288 		exit(-1);
289 	}
290 	list_id = creat(path_list_string, FILE_MODE);
291 	if (list_id == -1) {
292 		fprintf(temp,
293 			"\nThe path_list file '%s' cannot be created, errno=%d\n",
294 			path_list_string, errno);
295 		exit(-7);
296 	}
297 
298 	/****************************************/
299 	/*                                      */
300 	/*   and store its name in path_list    */
301 	/*                                      */
302 	/****************************************/
303 
304 	strcpy(write_string, path_string);
305 	len = strlen(write_string);
306 	write_string[len++] = 'D';
307 	write_string[len] = '\0';
308 	escrivez(write_string);
309 
310 	/****************************************/
311 	/*                                      */
312 	/*   generate the directory-file tree   */
313 	/*                                      */
314 	/****************************************/
315 
316 	level = 0;
317 
318 #ifdef DEBUG
319 	tst_resm(TINFO, "\n\t%s\n\n", "GENERATING:");
320 #endif
321 
322 	gen_ret_val = generate(path_string, level);
323 	close(list_id);
324 	list_id = open(path_list_string, READ);
325 	if (list_id == -1) {
326 		fprintf(temp,
327 			"\nThe path_list file cannot be opened for reading, errno=%d\n",
328 			errno);
329 		exit(-8);
330 	}
331 	list_stream = fdopen(list_id, "r");
332 
333 	/****************************************/
334 	/*                                      */
335 	/*   check the directory-file tree      */
336 	/*      for correctness                 */
337 	/*                                      */
338 	/****************************************/
339 
340 #ifdef DEBUG
341 	tst_resm(TINFO, "\n\t%s\n\n", "CHECKING:");
342 #endif
343 
344 	ch_ret_val = check();
345 
346 	exit_val = MIN(ch_ret_val, gen_ret_val);
347 
348 	status = fclose(list_stream);
349 	if (status != 0) {
350 		fprintf(temp,
351 			"Failed to close list_stream: ret=%d errno=%d (%s)\n",
352 			status, errno, strerror(errno));
353 		exit(-8);
354 	}
355 
356 	/*
357 	 * Remove file.
358 	 */
359 
360 	status = system(remove_string);
361 	if (status) {
362 		fprintf(temp, "Caution - `%s' failed.\n", remove_string);
363 		fprintf(temp, "Status returned %d.\n", status);
364 	}
365 
366 	/****************************************/
367 	/*                                      */
368 	/*         .....and exit main           */
369 	/*                                      */
370 	/****************************************/
371 
372 	exit(exit_val);
373 }
374 
generate(char * string,int level)375 int generate(char *string, int level)
376 
377 /****************************************/
378 /*					*/
379 /*   generate recursively a tree of	*/
380 /*   directories and files:  within   	*/
381 /*   created directory, an alternating	*/
382 /*   series of files and directories 	*/
383 /*   are constructed---until tree	*/
384 /*   breadth and depth limits are	*/
385 /*   reached or an error occurs		*/
386 /*					*/
387 /****************************************/
388 /***************************/
389 /*  string:                */
390 /*  the directory path     */
391 /*  string below which a   */
392 /*  tree is generated      */
393 /*                         */
394 /***************************/
395 
396 /***************************/
397 /* level:                  */
398 /* the tree depth variable */
399 /*                         */
400 /***************************/
401 {
402 	int switch_flag;
403 	int ret_val = 0;
404 	int new_ret_val, len, ret_len;
405 	char new_string[PATH_STRING_LENGTH + 1];
406 	int new_level;
407 	int i, j;		/* iteration counters */
408 	int snp_ret;
409 
410 	switch_flag = level & TRUE;
411 	if (strlen(string) >= MAX_PATH_STRING_LENGTH) {
412 
413 		/********************************/
414 		/*                              */
415 		/*   Maximum path name length   */
416 		/*          reached             */
417 		/*                              */
418 		/********************************/
419 
420 		fprintf(temp, "\nMaximum path_name length reached\n");
421 		return (-1);
422 	} else if (level < max_depth) {
423 		for (i = 0; i <= max_breadth; i++) {
424 			get_next_name();
425 			snp_ret = snprintf(new_string, sizeof(new_string),
426 				"%s/%s", string, name);
427 			if (snp_ret < 0 || snp_ret >= sizeof(new_string)) {
428 				tst_resm(TBROK, "snprintf(new_string,..) "
429 					"returned %d", snp_ret);
430 				exit(-1);
431 			}
432 
433 			/****************************************/
434 			/*                                      */
435 			/*    switch between creating files     */
436 			/*    and making directories            */
437 			/*                                      */
438 			/****************************************/
439 
440 			if (switch_flag) {
441 				switch_flag = FALSE;
442 
443 				/****************************************/
444 				/*                                      */
445 				/*        create a new file             */
446 				/*                                      */
447 				/****************************************/
448 
449 				file_id = creat(new_string, FILE_MODE);
450 				if (file_id == -1) {
451 					fprintf(temp,
452 						"\nImpossible to create file %s, errno=%d\n",
453 						new_string, errno);
454 					return (-2);
455 				}
456 #ifdef DEBUG
457 				tst_resm(TINFO, "%d  %s F\n", level,
458 					 new_string);
459 #endif
460 
461 				/****************************************/
462 				/*                                      */
463 				/*            write to it               */
464 				/*                                      */
465 				/****************************************/
466 
467 				len = strlen(new_string);
468 				for (j = 1; j <= file_length; j++) {
469 					ret_len =
470 					    write(file_id, new_string, len);
471 					if (ret_len != len) {
472 						fprintf(temp,
473 							"\nUnsuccessful write to file %s, errno=%d\n",
474 							new_string, errno);
475 						return (-3);
476 					}
477 				}
478 				close(file_id);
479 
480 				/****************************************/
481 				/*                                      */
482 				/*   and store its name in path_list    */
483 				/*                                      */
484 				/****************************************/
485 
486 				strcpy(write_string, new_string);
487 				len = strlen(write_string);
488 				write_string[len++] = 'F';
489 				write_string[len] = '\0';
490 				escrivez(write_string);
491 			} else {
492 				switch_flag = TRUE;
493 
494 				/****************************************/
495 				/*                                      */
496 				/*       or make a directory            */
497 				/*                                      */
498 				/*  (mknod can only be called when in   */
499 				/*   super user mode)                   */
500 				/*                                      */
501 				/****************************************/
502 
503 				ret_val = mkdir(new_string, DIRECTORY_MODE);
504 
505 				if (ret_val != 0) {
506 					fprintf(temp,
507 						"\nImpossible to create directory %s, errno=%d\n",
508 						new_string, errno);
509 					return (-5);
510 				}
511 #ifdef DEBUG
512 				tst_resm(TINFO, "%d  %s D\n", level,
513 					 new_string);
514 #endif
515 
516 				/****************************************/
517 				/*                                      */
518 				/*     store its name in path_list      */
519 				/*                                      */
520 				/****************************************/
521 
522 				strcpy(write_string, new_string);
523 				len = strlen(write_string);
524 				write_string[len++] = 'D';
525 				write_string[len] = '\0';
526 				escrivez(write_string);
527 
528 				/****************************************/
529 				/*                                      */
530 				/*      and generate a new level        */
531 				/*                                      */
532 				/****************************************/
533 
534 				new_level = level + 1;
535 				new_ret_val = generate(new_string, new_level);
536 				if (new_ret_val < ret_val)
537 					ret_val = new_ret_val;
538 			}
539 		}
540 
541 		/********************************/
542 		/*                              */
543 		/*    Maximum breadth reached   */
544 		/*                              */
545 		/********************************/
546 
547 		return (ret_val);
548 	} else
549 		    /********************************/
550 		/*                             */
551 		/*    Maximum depth reached    */
552 		/*                             */
553  /********************************/
554 		return 0;
555 }
556 
check(void)557 int check(void)
558 
559 /****************************************/
560 /*					*/
561 /*   check for file and directory	*/
562 /*   correctness by reading records	*/
563 /*   from the path_list and attempting	*/
564 /*   to determine if the corresponding	*/
565 /*   files or directories are as 	*/
566 /*   created 				*/
567 /*					*/
568 /****************************************/
569 {
570 	int len, path_mode, val, ret_len, j;
571 
572 	for (;;) {
573 
574 		/****************************************/
575 		/*                                      */
576 		/*  read a path string from path_list   */
577 		/*                                      */
578 		/****************************************/
579 
580 		if (fscanf(list_stream, "%s", path_string) == EOF) {
581 
582 #ifdef DEBUG
583 			tst_resm(TINFO, "\nEnd of path_list file reached \n");
584 #endif
585 
586 			return 0;
587 		}
588 #ifdef DEBUG
589 		tst_resm(TINFO, "%s\n", path_string);
590 #endif
591 
592 		len = strlen(path_string);
593 		len--;
594 		if (path_string[len] == 'F') {
595 
596 		/********************************/
597 			/*                              */
598 			/*    this should be a file     */
599 			/*                              */
600 		/********************************/
601 
602 			path_string[len] = '\0';
603 			file_id = open(path_string, READ);
604 			if (file_id <= 0) {
605 				fprintf(temp,
606 					"\nImpossible to open file %s, errno=%d\n",
607 					path_string, errno);
608 				return (-1);
609 			}
610 
611 			else {
612 				/********************************/
613 				/*                              */
614 				/*    check its contents        */
615 				/*                              */
616 				/********************************/
617 
618 				ret_len = 0;
619 				len = strlen(path_string);
620 				for (j = 1; j <= file_length; j++) {
621 					ret_len =
622 					    read(file_id, read_string, len);
623 					if (len != ret_len) {
624 						fprintf(temp,
625 							"\nFile read error for file %s, errno=%d\n",
626 							path_string, errno);
627 						return (-3);
628 					}
629 					read_string[len] = '\0';
630 					val = strcmp(read_string, path_string);
631 					if (val != 0) {
632 						fprintf(temp,
633 							"\nContents of file %s are different than expected: %s\n",
634 							path_string,
635 							read_string);
636 						return (-4);
637 					}
638 				}
639 				close(file_id);
640 			}	/* else for */
641 			if (ret_len <= 0) {
642 				fprintf(temp,
643 					"\nImpossible to read file %s, errno=%d\n",
644 					path_string, errno);
645 				return (-2);
646 			}
647 		} else {
648 
649 		/********************************/
650 			/*                              */
651 			/*  otherwise..........         */
652 			/*  it should be a directory    */
653 			/*                              */
654 		/********************************/
655 
656 			path_string[len] = '\0';
657 			path_mode = mode(path_string);
658 			if (path_mode == -1) {
659 				fprintf(temp,
660 					"\nPreviously created directory path %s was not open\n",
661 					path_string);
662 				return (-4);
663 			}
664 			if ((040000 & path_mode) != 040000) {
665 				fprintf(temp,
666 					"\nPath %s was not recognized to be a directory\n",
667 					path_string);
668 				fprintf(temp, "Its mode is %o\n", path_mode);
669 				return (-5);
670 			}
671 		}
672 	}			/* while */
673 }
674 
get_next_name(void)675 int get_next_name(void)
676 
677 /****************************************/
678 /*					*/
679 /*   get the next---in a dictionary	*/
680 /*   sense---file or directory name	*/
681 /*					*/
682 /****************************************/
683 {
684 	static int k;
685 	int i;
686 	int last_position;
687 
688 	last_position = NAME_LENGTH - 1;
689 	if (k == 0) {
690 
691 		/************************/
692 		/*                      */
693 		/*   initialize name    */
694 		/*                      */
695 		/************************/
696 
697 		for (i = 0; i < NAME_LENGTH; i++)
698 			name[i] = 'a';
699 		name[NAME_LENGTH] = '\0';
700 		k++;
701 	}
702 					    /********************************/
703 	/*                              */
704 	else
705 		increment_name(last_position);	/* i.e., beginning at the last  */
706 	/* position                     */
707 	/*                              */
708 					    /********************************/
709 	return 0;
710 }
711 
increment_name(int position)712 int increment_name(int position)
713 
714 /****************************************/
715 /*					*/
716 /*  recursively revise the letters in 	*/
717 /*  a name to get the lexiographically	*/
718 /*  next name				*/
719 /*					*/
720 /****************************************/
721 {
722 	int next_position;
723 
724 	if (name[position] == 'z')
725 		if (position == 0) {
726 			fprintf(temp,
727 				"ERROR: There are no more available names\n");
728 			exit(-1);
729 		} else {
730 			name[position] = 'a';	       /**********************/
731 			next_position = --position;	/*                    */
732 			increment_name(next_position);	/*  increment the     */
733 			/*  previous letter   */
734 			/*                    */
735 						       /**********************/
736 		}
737 				  /*********************************/
738 	/*                               */
739 	else
740 		name[position]++;	/* otherwise, increment this one */
741 	return 0;		/*                               */
742 				  /*********************************/
743 }
744 
mode(char * path_string)745 int mode(char *path_string)
746 
747 /****************************************/
748 /*					*/
749 /*   determine and return the mode of	*/
750 /*   the file named by path_string 	*/
751 /*					*/
752 /****************************************/
753 {
754 	struct stat buf;
755 	int ret_val, mod;
756 
757 	ret_val = stat(path_string, &buf);
758 	if (ret_val == -1)
759 		return (-1);
760 	else {
761 		mod = buf.st_mode;
762 		return (mod);
763 	}
764 }
765 
escrivez(char * string)766 int escrivez(char *string)
767 {
768 	char write_string[PATH_STRING_LENGTH + 1];
769 	int len, ret_len;
770 
771 	strcpy(write_string, string);
772 	len = strlen(write_string);
773 	write_string[len] = '\n';
774 	len++;
775 	ret_len = write(list_id, write_string, len);
776 	if (len != ret_len) {
777 		fprintf(temp,
778 			"A string of deviant length %d written to path_list, errno=%d\n",
779 			ret_len, errno);
780 		exit(-2);
781 	}
782 	return 0;
783 }
784 
term(void)785 int term(void)
786 {
787 	int status;
788 
789 	fflush(temp);
790 	if (parent_pid == getpid()) {
791 		massmurder();	/* kill kids */
792 		fprintf(temp, "\term1 - SIGTERM received by parent.\n");
793 		fflush(temp);
794 	} else {
795 		fprintf(temp, "\tchild - got SIGTERM signal.\n");
796 		if (list_stream != NULL)
797 			fclose(list_stream);
798 		close(list_id);
799 		close(file_id);
800 		status = system(remove_string);
801 		if (status) {
802 			fprintf(temp, "Caution - ``%s'' returned status %d\n",
803 				remove_string, status);
804 		}
805 		exit(0);
806 	}
807 	return 0;
808 }
809 
massmurder(void)810 int massmurder(void)
811 {
812 	int i;
813 	for (i = 0; i < MAXCHILD; i++) {
814 		if (allchild[i]) {
815 			kill(allchild[i], SIGTERM);
816 		}
817 	}
818 	return 0;
819 }
820 
821 /** LTP Port **/
822 /*
823  * setup
824  *
825  * Do set up - here its a dummy function
826  */
setup(void)827 void setup(void)
828 {
829 	tst_tmpdir();
830 	temp = stderr;
831 }
832 
833 /*
834  * fail_exit()
835  *
836  * Exit on failure
837  */
fail_exit(void)838 void fail_exit(void)
839 {
840 	tst_brkm(TFAIL, tst_rmdir, "Test failed\n");
841 }
842 
843 /*
844  *
845  * Function: anyfail()
846  *
847  * Description: Exit a test.
848  */
anyfail(void)849 void anyfail(void)
850 {
851 	(local_flag == FAILED) ? tst_resm(TFAIL, "Test failed")
852 	    : tst_resm(TPASS, "Test passed");
853 	tst_rmdir();
854 	tst_exit();
855 }
856 
857 /*
858  * ok_exit
859  *
860  * Calling block passed the test
861  */
ok_exit(void)862 void ok_exit(void)
863 {
864 	local_flag = PASSED;
865 	return;
866 }
867 
868 /*
869  * forkfail()
870  *
871  * exit on failure
872  */
forkfail(void)873 void forkfail(void)
874 {
875 	tst_brkm(TBROK, tst_rmdir, "Reason: %s\n", strerror(errno));
876 }
877 
878 /*
879  * Function: terror
880  *
881  * Description: prints error message this may not be because some part of the
882  *              test case failed, for example fork() failed. We will log this
883  *              failure as TBROK instead of TFAIL.
884  */
terror(char * message)885 void terror(char *message)
886 {
887 	tst_resm(TBROK, "Reason: %s:%s\n", message, strerror(errno));
888 	return;
889 }
890 
891 /*
892  * instress
893  *
894  * Assume that we are always running under stress, so this function will
895  * return > 0 value always.
896  */
instress(void)897 int instress(void)
898 {
899 	tst_resm(TINFO, "System resource may be too low, fork() malloc()"
900 		 " etc are likely to fail.\n");
901 	return 1;
902 }
903