• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2001
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 /*
21  * NAME
22  *	fcntl16.c
23  *
24  * DESCRIPTION
25  *	Additional file locking test cases for checking proper notifictaion
26  *	of processes on lock change
27  *
28  * ALGORITHM
29  *	Various test cases are used to lock a file opened without mandatory
30  *	locking, with madatory locking and mandatory locking with NOBLOCK.
31  *	Checking that processes waiting on lock boundaries are notified
32  *	properly when boundaries change
33  *
34  * USAGE
35  *	fcntl16
36  *
37  * HISTORY
38  *	07/2001 Ported by Wayne Boyer
39  *	04/2002 wjhuie sigset cleanups
40  *
41  * RESTRICTIONS
42  *	None
43  */
44 
45 #include <fcntl.h>
46 #include <signal.h>
47 #include <errno.h>
48 #include "test.h"
49 #include <sys/stat.h>
50 #include <sys/types.h>
51 #include <sys/wait.h>
52 
53 
54 #define SKIPVAL 0x0f00
55 //#define       SKIP    SKIPVAL, 0, 0L, 0L, IGNORED
56 #define SKIP 0,0,0L,0L,0
57 #if (SKIPVAL == F_RDLCK) || (SKIPVAL == F_WRLCK)
58 #error invalid SKIP, must not be F_RDLCK or F_WRLCK
59 #endif
60 
61 #define	IGNORED		0
62 #define	NOBLOCK		2	/* immediate success */
63 #define	WILLBLOCK	3	/* blocks, succeeds, parent unlocks records */
64 #define	TIME_OUT	10
65 int NO_NFS = 1;			/* Test on NFS or not */
66 
67 typedef struct {
68 	struct flock parent_a;
69 	struct flock parent_b;
70 	struct flock child_a;
71 	struct flock child_b;
72 	struct flock parent_c;
73 	struct flock parent_d;
74 } testcase;
75 
76 static testcase testcases[] = {
77 	/* #1 Parent_a making a write lock on entire file */
78 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
79 	 /* Parent_b skipped */
80 	 {SKIP},
81 	 /* Child_a read lock on byte 1 to byte 5 */
82 	 {F_RDLCK, 0, 0L, 5L, NOBLOCK},
83 	 /* Child_b read lock on byte 6 to byte 10 */
84 	 {F_RDLCK, 0, 6L, 5L, NOBLOCK},
85 	 /*
86 	  * Parent_c read lock on entire file
87 	  */
88 	 {F_RDLCK, 0, 0L, 0L, IGNORED},
89 	 /* Parent_d skipped */
90 	 {SKIP},},
91 
92 	/* #2 Parent_a making a write lock on entire file */
93 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
94 	 /* Parent_b skipped */
95 	 {SKIP},
96 	 /* Child_a read lock on byte 1 to byte 5 */
97 	 {F_RDLCK, 0, 0L, 5L, WILLBLOCK},
98 	 /* Child_b read lock on byte 6 to byte 10 */
99 	 {F_RDLCK, 0, 6L, 5L, WILLBLOCK},
100 	 /*
101 	  * Parent_c write lock on entire
102 	  * file
103 	  */
104 	 {F_WRLCK, 0, 0L, 0L, IGNORED},
105 	 /* Parent_d skipped */
106 	 {SKIP},},
107 
108 	/* #3 Parent_a making a write lock on entire file */
109 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
110 	 /* Parent_b skipped */
111 	 {SKIP},
112 	 /* Child_a read lock on byte 2 to byte 4 */
113 	 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
114 	 /* Child_b read lock on byte 6 to byte 8 */
115 	 {F_RDLCK, 0, 6L, 3L, WILLBLOCK},
116 	 /*
117 	  * Parent_c read lock on byte 3 to
118 	  * byte 7
119 	  */
120 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
121 	 /* Parent_d skipped */
122 	 {SKIP},},
123 
124 	/* #4 Parent_a making a write lock on entire file */
125 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
126 	 /* Parent_b skipped */
127 	 {SKIP},
128 	 /* Child_a read lock on byte 2 to byte 4 */
129 	 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
130 	 /* Child_b read lock on byte 6 to byte 8 */
131 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
132 	 /*
133 	  * Parent_c read lock on byte 5 to
134 	  * byte 9
135 	  */
136 	 {F_RDLCK, 0, 5L, 5L, IGNORED},
137 	 /* Parent_d skipped */
138 	 {SKIP},},
139 
140 	/* #5 Parent_a making a write lock on entire file */
141 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
142 	 /* Parent_b skipped */
143 	 {SKIP},
144 	 /* Child_a read lock on byte 3 to byte 7 */
145 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
146 	 /* Child_b read lock on byte 5 to byte 10 */
147 	 {F_RDLCK, 0, 5L, 6L, WILLBLOCK},
148 	 /*
149 	  * Parent_c read lock on byte 2 to
150 	  * byte 8
151 	  */
152 	 {F_RDLCK, 0, 2L, 7L, IGNORED},
153 	 /* Parent_d skipped */
154 	 {SKIP},},
155 
156 	/* #6 Parent_a making a write lock on entire file */
157 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
158 	 /* Parent_b skipped */
159 	 {SKIP},
160 	 /* Child_a read lock on byte 2 to byte 4 */
161 	 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
162 	 /* Child_b write lock on byte 6 to byte 8 */
163 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
164 	 /* Parent_c no lock on byte 3 to 9 */
165 	 {F_UNLCK, 0, 3L, 7L, IGNORED},
166 	 /* Parent_d skipped */
167 	 {SKIP},},
168 
169 	/* #7 Parent_a making a write lock on entire file */
170 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
171 	 /* Parent_b read lock on byte 3 to byte 7 */
172 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
173 	 /* Child_a read lock on byte 2 to byte 4 */
174 	 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
175 	 /* Child_b read lock on byte 6 to byte 8 */
176 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
177 	 /*
178 	  * Parent_c read lock on byte 1 to
179 	  * byte 9
180 	  */
181 	 {F_RDLCK, 0, 1L, 9L, IGNORED},
182 	 /* Parent_d skipped */
183 	 {SKIP},},
184 
185 	/* #8 Parent_a making a write lock on byte 2 to byte 4 */
186 	{{F_WRLCK, 0, 2L, 3L, IGNORED},
187 	 /* Parent_b write lock on byte 6 to byte 8 */
188 	 {F_WRLCK, 0, 6L, 3L, IGNORED},
189 	 /* Child_a read lock on byte 3 to byte 7 */
190 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
191 	 /* Child_b skipped */
192 	 {SKIP},
193 	 /*
194 	  * Parent_c read lock on byte 1 to
195 	  * byte 5
196 	  */
197 	 {F_RDLCK, 0, 1L, 5L, IGNORED},
198 	 /*
199 	  * Parent_d read lock on
200 	  * byte 5 to byte 9
201 	  */
202 	 {F_RDLCK, 0, 5L, 5L,
203 	  IGNORED},},
204 
205 	/* #9 Parent_a making a write lock on entire file */
206 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
207 	 /* Parent_b read lock on byte 3 to byte 7 */
208 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
209 	 /* Child_a read lock on byte 2 to byte 4 */
210 	 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
211 	 /* Child_b read lock on byte 6 to byte 8 */
212 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
213 	 /*
214 	  * Parent_c read lock on byte 1 to
215 	  * byte 3
216 	  */
217 	 {F_RDLCK, 0, 1L, 3L, IGNORED},
218 	 /*
219 	  * Parent_d read lock on
220 	  * byte 7 to byte 9
221 	  */
222 	 {F_RDLCK, 0, 7L, 3L,
223 	  IGNORED},},
224 
225 	/* #10 Parent_a making a write lock on entire file */
226 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
227 	 /* Parent_b skipped */
228 	 {SKIP},
229 	 /* Child_a read lock on byte 2 to byte 4 */
230 	 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
231 	 /* Child_b read lock on byte 6 to byte 8 */
232 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
233 	 /*
234 	  * Parent_c read lock on byte 1 to
235 	  * byte 7
236 	  */
237 	 {F_RDLCK, 0, 1L, 7L, IGNORED},
238 	 /*
239 	  * Parent_d read lock on
240 	  * byte 3 to byte 9
241 	  */
242 	 {F_RDLCK, 0, 3L, 7L,
243 	  IGNORED},},
244 
245 	/* #11 Parent_a making a write lock on entire file */
246 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
247 	 /* Parent_b skipped */
248 	 {SKIP},
249 	 /* Child_a read lock on byte 3 to byte 7 */
250 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
251 	 /* Child_b read lock on byte 3 to byte 7 */
252 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
253 	 /*
254 	  * Parent_c read lock on byte 3 to
255 	  * byte 7
256 	  */
257 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
258 	 /* Parent_d skipped */
259 	 {SKIP},},
260 };
261 
262 static testcase *thiscase;
263 static struct flock *thislock;
264 static int parent;
265 static int child_flag1 = 0;
266 static int child_flag2 = 0;
267 static int parent_flag = 0;
268 static int alarm_flag = 0;
269 static int child_pid[2], flag[2];
270 static int fd;
271 static int test;
272 static char tmpname[40];
273 
274 #define	FILEDATA	"tenbytes!"
275 
276 extern void catch_int(int sig);	/* signal catching subroutine */
277 
278 char *TCID = "fcntl16";
279 int TST_TOTAL = 1;
280 
281 #ifdef UCLINUX
282 static char *argv0;
283 #endif
284 
285 /*
286  * cleanup - performs all the ONE TIME cleanup for this test at completion or
287  *	premature exit
288  */
cleanup(void)289 void cleanup(void)
290 {
291 	tst_rmdir();
292 
293 }
294 
dochild(int kid)295 void dochild(int kid)
296 {
297 	/* child process */
298 	struct sigaction sact;
299 	sact.sa_flags = 0;
300 	sact.sa_handler = catch_int;
301 	sigemptyset(&sact.sa_mask);
302 	(void)sigaction(SIGUSR1, &sact, NULL);
303 
304 	/* Lock should succeed after blocking and parent releases lock */
305 	if (kid) {
306 		if ((kill(parent, SIGUSR2)) < 0) {
307 			tst_resm(TFAIL, "Attempt to send signal to parent "
308 				 "failed");
309 			tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
310 				 test + 1, kid, errno);
311 			exit(1);
312 		}
313 	} else {
314 		if ((kill(parent, SIGUSR1)) < 0) {
315 			tst_resm(TFAIL, "Attempt to send signal to parent "
316 				 "failed");
317 			tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
318 				 test + 1, kid, errno);
319 			exit(1);
320 		}
321 	}
322 
323 	if ((fcntl(fd, F_SETLKW, thislock)) < 0) {
324 		if (errno == EINTR && parent_flag) {
325 			/*
326 			 * signal received is waiting for lock to clear,
327 			 * this is expected if flag = WILLBLOCK
328 			 */
329 			exit(1);
330 		} else {
331 			tst_resm(TFAIL, "Attempt to set child BLOCKING lock "
332 				 "failed");
333 			tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
334 				 errno);
335 			exit(2);
336 		}
337 	}
338 	exit(0);
339 }				/* end of child process */
340 
341 #ifdef UCLINUX
342 static int kid_uc;
343 
dochild_uc(void)344 void dochild_uc(void)
345 {
346 	dochild(kid_uc);
347 }
348 #endif
349 
catch_alarm(int sig)350 void catch_alarm(int sig)
351 {
352 	alarm_flag = 1;
353 }
354 
catch_usr1(int sig)355 void catch_usr1(int sig)
356 {				/* invoked on catching SIGUSR1 */
357 	/*
358 	 * Set flag to let parent know that child #1 is ready to have the
359 	 * lock removed
360 	 */
361 	child_flag1 = 1;
362 }
363 
catch_usr2(int sig)364 void catch_usr2(int sig)
365 {				/* invoked on catching SIGUSR2 */
366 	/*
367 	 * Set flag to let parent know that child #2 is ready to have the
368 	 * lock removed
369 	 */
370 	child_flag2 = 1;
371 }
372 
catch_int(int sig)373 void catch_int(int sig)
374 {				/* invoked on child catching SIGUSR1 */
375 	/*
376 	 * Set flag to interrupt fcntl call in child and force a controlled
377 	 * exit
378 	 */
379 	parent_flag = 1;
380 }
381 
child_sig(int sig,int nkids)382 void child_sig(int sig, int nkids)
383 {
384 	int i;
385 
386 	for (i = 0; i < nkids; i++) {
387 		if (kill(child_pid[i], 0) == 0) {
388 			if ((kill(child_pid[i], sig)) < 0) {
389 				tst_resm(TFAIL, "Attempt to signal child %d, "
390 					 "failed", i + 1);
391 			}
392 		}
393 	}
394 }
395 
396 /*
397  * setup - performs all ONE TIME steup for this test
398  */
setup(void)399 void setup(void)
400 {
401 	struct sigaction sact;
402 
403 	tst_sig(FORK, DEF_HANDLER, cleanup);
404 
405 	umask(0);
406 
407 	/* Pause if option was specified */
408 	TEST_PAUSE;
409 
410 	parent = getpid();
411 
412 	tst_tmpdir();
413 
414 	/* On NFS or not */
415 	if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC)
416 		NO_NFS = 0;
417 
418 	/* set up temp filename */
419 	sprintf(tmpname, "fcntl4.%d", parent);
420 
421 	/*
422 	 * Set up signal handling functions
423 	 */
424 	memset(&sact, 0, sizeof(sact));
425 	sact.sa_handler = catch_usr1;
426 	sigemptyset(&sact.sa_mask);
427 	sigaddset(&sact.sa_mask, SIGUSR1);
428 	sigaction(SIGUSR1, &sact, NULL);
429 
430 	memset(&sact, 0, sizeof(sact));
431 	sact.sa_handler = catch_usr2;
432 	sigemptyset(&sact.sa_mask);
433 	sigaddset(&sact.sa_mask, SIGUSR2);
434 	sigaction(SIGUSR2, &sact, NULL);
435 
436 	memset(&sact, 0, sizeof(sact));
437 	sact.sa_handler = catch_alarm;
438 	sigemptyset(&sact.sa_mask);
439 	sigaddset(&sact.sa_mask, SIGALRM);
440 	sigaction(SIGALRM, &sact, NULL);
441 }
442 
run_test(int file_flag,int file_mode,int start,int end)443 int run_test(int file_flag, int file_mode, int start, int end)
444 {
445 	int child_count;
446 	int child;
447 	int nexited;
448 	int status, expect_stat;
449 	int i, fail = 0;
450 
451 	/* loop through all test cases */
452 	for (test = start; test < end; test++) {
453 		/* open a temp file to lock */
454 		fd = open(tmpname, file_flag, file_mode);
455 		if (fd < 0) {
456 			tst_brkm(TBROK, cleanup, "open failed");
457 		}
458 
459 		/* write some dummy data to the file */
460 		(void)write(fd, FILEDATA, 10);
461 
462 		/* Initialize first parent lock structure */
463 		thiscase = &testcases[test];
464 		thislock = &thiscase->parent_a;
465 
466 		/* set the initial parent lock on the file */
467 		if ((fcntl(fd, F_SETLK, thislock)) < 0) {
468 			tst_resm(TFAIL, "First parent lock failed");
469 			tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
470 				 errno);
471 			close(fd);
472 			unlink(tmpname);
473 			return 1;
474 		}
475 
476 		/* Initialize second parent lock structure */
477 		thislock = &thiscase->parent_b;
478 
479 		if ((thislock->l_type) != IGNORED) {	/*SKIPVAL */
480 			/* set the second parent lock */
481 			if ((fcntl(fd, F_SETLK, thislock)) < 0) {
482 				tst_resm(TFAIL, "Second parent lock failed");
483 				tst_resm(TFAIL, "Test case %d, errno = %d",
484 					 test + 1, errno);
485 				close(fd);
486 				unlink(tmpname);
487 				return 1;
488 			}
489 		}
490 
491 		/* Initialize first child lock structure */
492 		thislock = &thiscase->child_a;
493 
494 		/* Initialize child counter and flags */
495 		alarm_flag = parent_flag = 0;
496 		child_flag1 = child_flag2 = 0;
497 		child_count = 0;
498 
499 		/* spawn child processes */
500 		for (i = 0; i < 2; i++) {
501 			if (thislock->l_type != IGNORED) {
502 				if ((child = FORK_OR_VFORK()) == 0) {
503 #ifdef UCLINUX
504 					if (self_exec(argv0, "ddddd", i, parent,
505 						      test, thislock, fd) < 0) {
506 						perror("self_exec failed");
507 						return 1;
508 					}
509 #else
510 					dochild(i);
511 #endif
512 				}
513 				if (child < 0) {
514 					perror("Fork failed");
515 					return 1;
516 				}
517 				child_count++;
518 				child_pid[i] = child;
519 				flag[i] = thislock->l_pid;
520 			}
521 			/* Initialize second child lock structure */
522 			thislock = &thiscase->child_b;
523 		}
524 		/* parent process */
525 
526 		/*
527 		 * Wait for children to signal they are ready. Set a timeout
528 		 * just in case they don't signal at all.
529 		 */
530 		alarm(TIME_OUT);
531 
532 		while (!alarm_flag
533 		       && (child_flag1 + child_flag2 != child_count)) {
534 			pause();
535 		}
536 
537 		/*
538 		 * Turn off alarm and unmask signals
539 		 */
540 		alarm((unsigned)0);
541 
542 		if (child_flag1 + child_flag2 != child_count) {
543 			tst_resm(TFAIL, "Test case %d: kids didn't signal",
544 				 test + 1);
545 			fail = 1;
546 		}
547 		child_flag1 = child_flag2 = alarm_flag = 0;
548 
549 		thislock = &thiscase->parent_c;
550 
551 		/* set the third parent lock on the file */
552 		if ((fcntl(fd, F_SETLK, thislock)) < 0) {
553 			tst_resm(TFAIL, "Third parent lock failed");
554 			tst_resm(TFAIL, "Test case %d, errno = %d",
555 				 test + 1, errno);
556 			close(fd);
557 			unlink(tmpname);
558 			return 1;
559 		}
560 
561 		/* Initialize fourth parent lock structure */
562 		thislock = &thiscase->parent_d;
563 
564 		if ((thislock->l_type) != IGNORED) {	/*SKIPVAL */
565 			/* set the fourth parent lock */
566 			if ((fcntl(fd, F_SETLK, thislock)) < 0) {
567 				tst_resm(TINFO, "Fourth parent lock failed");
568 				tst_resm(TINFO, "Test case %d, errno = %d",
569 					 test + 1, errno);
570 				close(fd);
571 				unlink(tmpname);
572 				return 1;
573 			}
574 		}
575 
576 		/*
577 		 * Wait for children to exit, or for timeout to occur.
578 		 * Timeouts are expected for testcases where kids are
579 		 * 'WILLBLOCK', In that case, send kids a wakeup interrupt
580 		 * and wait again for them. If a second timeout occurs, then
581 		 * something is wrong.
582 		 */
583 		alarm_flag = nexited = 0;
584 		while (nexited < child_count) {
585 			alarm(TIME_OUT);
586 			child = wait(&status);
587 			alarm(0);
588 
589 			if (child == -1) {
590 				if (errno != EINTR || alarm_flag != 1) {
591 					/*
592 					 * Some error other than a timeout,
593 					 * or else this is the second
594 					 * timeout. Both cases are errors.
595 					 */
596 					break;
597 				}
598 
599 				/*
600 				 * Expected timeout case. Signal kids then
601 				 * go back and wait again
602 				 */
603 				child_sig(SIGUSR1, child_count);
604 				continue;
605 			}
606 
607 			for (i = 0; i < child_count; i++)
608 				if (child == child_pid[i])
609 					break;
610 			if (i == child_count) {
611 				/*
612 				 * Ignore unexpected kid, it could be a
613 				 * leftover from a previous iteration that
614 				 * timed out.
615 				 */
616 				continue;
617 			}
618 
619 			/* Found the right kid, check his status */
620 			nexited++;
621 
622 			expect_stat = (flag[i] == NOBLOCK) ? 0 : 1;
623 
624 			if (!WIFEXITED(status)
625 			    || WEXITSTATUS(status) != expect_stat) {
626 				/* got unexpected exit status from kid */
627 				tst_resm(TFAIL, "Test case %d: child %d %s "
628 					 "or got bad status (x%x)", test + 1,
629 					 i, (flag[i] == NOBLOCK) ?
630 					 "BLOCKED unexpectedly" :
631 					 "failed to BLOCK", status);
632 				fail = 1;
633 			}
634 		}
635 
636 		if (nexited != child_count) {
637 			tst_resm(TFAIL, "Test case %d, caught %d expected %d "
638 				 "children", test + 1, nexited, child_count);
639 			child_sig(SIGKILL, nexited);
640 			fail = 1;
641 		}
642 		close(fd);
643 	}
644 	unlink(tmpname);
645 	if (fail) {
646 		return 1;
647 	} else {
648 		return 0;
649 	}
650 	return 0;
651 }
652 
main(int ac,char ** av)653 int main(int ac, char **av)
654 {
655 
656 	int lc;
657 
658 	tst_parse_opts(ac, av, NULL, NULL);
659 #ifdef UCLINUX
660 	maybe_run_child(dochild_uc, "ddddd", &kid_uc, &parent, &test,
661 			&thislock, &fd);
662 	argv0 = av[0];
663 #endif
664 
665 	setup();		/* global setup */
666 
667 	for (lc = 0; TEST_LOOPING(lc); lc++) {
668 		/* reset tst_count in case we are looping */
669 		tst_count = 0;
670 
671 /* //block1: */
672 		/*
673 		 * Check file locks on an ordinary file without
674 		 * mandatory locking
675 		 */
676 		tst_resm(TINFO, "Entering block 1");
677 		if (run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 0, 11)) {
678 			tst_resm(TINFO, "Test case 1: without mandatory "
679 				 "locking FAILED");
680 		} else {
681 			tst_resm(TINFO, "Test case 1: without manadatory "
682 				 "locking PASSED");
683 		}
684 		tst_resm(TINFO, "Exiting block 1");
685 
686 /* //block2: */
687 		/*
688 		 * Check the file locks on a file with mandatory record
689 		 * locking
690 		 */
691 		tst_resm(TINFO, "Entering block 2");
692 		if (NO_NFS && run_test(O_CREAT | O_RDWR | O_TRUNC, S_ISGID |
693 			     S_IRUSR | S_IWUSR, 0, 11)) {
694 			tst_resm(TINFO, "Test case 2: with mandatory record "
695 				 "locking FAILED");
696 		} else {
697 			if (NO_NFS)
698 				tst_resm(TINFO, "Test case 2: with mandatory"
699 					 " record locking PASSED");
700 			else
701 				tst_resm(TCONF, "Test case 2: NFS does not"
702 					 " support mandatory locking");
703 		}
704 		tst_resm(TINFO, "Exiting block 2");
705 
706 /* //block3: */
707 		/*
708 		 * Check file locks on a file with mandatory record locking
709 		 * and no delay
710 		 */
711 		tst_resm(TINFO, "Entering block 3");
712 		if (NO_NFS && run_test(O_CREAT | O_RDWR | O_TRUNC | O_NDELAY,
713 			     S_ISGID | S_IRUSR | S_IWUSR, 0, 11)) {
714 			tst_resm(TINFO, "Test case 3: mandatory locking with "
715 				 "NODELAY FAILED");
716 		} else {
717 			if (NO_NFS)
718 				tst_resm(TINFO, "Test case 3: mandatory"
719 					 " locking with NODELAY PASSED");
720 			else
721 				tst_resm(TCONF, "Test case 3: NFS does not"
722 					 " support mandatory locking");
723 		}
724 		tst_resm(TINFO, "Exiting block 3");
725 	}
726 	cleanup();
727 	tst_exit();
728 }
729