blob: 12696a8f8e11a2c06dacb4b981def96feb719195 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
subrata_modak56207ce2009-03-23 13:35:39 +000022 * fcntl16.c
plars865695b2001-08-27 22:15:12 +000023 *
24 * DESCRIPTION
subrata_modak56207ce2009-03-23 13:35:39 +000025 * Additional file locking test cases for checking proper notifictaion
26 * of processes on lock change
plars865695b2001-08-27 22:15:12 +000027 *
28 * ALGORITHM
subrata_modak56207ce2009-03-23 13:35:39 +000029 * 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
plars865695b2001-08-27 22:15:12 +000033 *
34 * USAGE
nstrazfa31d552002-05-14 16:50:06 +000035 * fcntl16
plars865695b2001-08-27 22:15:12 +000036 *
37 * HISTORY
38 * 07/2001 Ported by Wayne Boyer
robbiew4644c7e2002-04-26 14:33:32 +000039 * 04/2002 wjhuie sigset cleanups
plars865695b2001-08-27 22:15:12 +000040 *
41 * RESTRICTIONS
subrata_modak56207ce2009-03-23 13:35:39 +000042 * None
plars865695b2001-08-27 22:15:12 +000043 */
44
45#include <fcntl.h>
plars865695b2001-08-27 22:15:12 +000046#include <signal.h>
47#include <errno.h>
Garrett Cooper0a643cb2010-12-21 11:21:19 -080048#include "test.h"
49#include "usctest.h"
robbiew5aab8a72003-03-26 18:05:30 +000050#include <sys/stat.h>
51#include <sys/types.h>
mridgedb639212005-01-04 21:04:11 +000052#include <sys/wait.h>
plars865695b2001-08-27 22:15:12 +000053
mridgedb639212005-01-04 21:04:11 +000054#define SKIPVAL 0x0f00
subrata_modak56207ce2009-03-23 13:35:39 +000055//#define SKIP SKIPVAL, 0, 0L, 0L, IGNORED
mridge1902af92005-01-11 16:01:53 +000056#define SKIP 0,0,0L,0L,0
mridgedb639212005-01-04 21:04:11 +000057#if (SKIPVAL == F_RDLCK) || (SKIPVAL == F_WRLCK)
58#error invalid SKIP, must not be F_RDLCK or F_WRLCK
59#endif
plars865695b2001-08-27 22:15:12 +000060
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
66typedef struct {
subrata_modak56207ce2009-03-23 13:35:39 +000067 short type;
68 short whence;
69 long start;
70 long len;
71 short flag;
plars865695b2001-08-27 22:15:12 +000072} lock;
73
74typedef struct {
subrata_modak56207ce2009-03-23 13:35:39 +000075 lock parent_a;
76 lock parent_b;
77 lock child_a;
78 lock child_b;
79 lock parent_c;
80 lock parent_d;
plars865695b2001-08-27 22:15:12 +000081} testcase;
82
83static testcase testcases[] = {
84 /* #1 Parent_a making a write lock on entire file */
subrata_modak56207ce2009-03-23 13:35:39 +000085 {{F_WRLCK, 0, 0L, 0L, IGNORED},
86 /* Parent_b skipped */
87 {SKIP},
88 /* Child_a read lock on byte 1 to byte 5 */
89 {F_RDLCK, 0, 0L, 5L, NOBLOCK},
90 /* Child_b read lock on byte 6 to byte 10 */
91 {F_RDLCK, 0, 6L, 5L, NOBLOCK},
92 /*
93 * Parent_c read lock on entire file
94 */
95 {F_RDLCK, 0, 0L, 0L, IGNORED},
96 /* Parent_d skipped */
97 {SKIP},},
plars865695b2001-08-27 22:15:12 +000098
99 /* #2 Parent_a making a write lock on entire file */
100 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000101 /* Parent_b skipped */
102 {SKIP},
103 /* Child_a read lock on byte 1 to byte 5 */
104 {F_RDLCK, 0, 0L, 5L, WILLBLOCK},
105 /* Child_b read lock on byte 6 to byte 10 */
106 {F_RDLCK, 0, 6L, 5L, WILLBLOCK},
107 /*
108 * Parent_c write lock on entire
109 * file
110 */
111 {F_WRLCK, 0, 0L, 0L, IGNORED},
112 /* Parent_d skipped */
113 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000114
115 /* #3 Parent_a making a write lock on entire file */
116 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000117 /* Parent_b skipped */
118 {SKIP},
119 /* Child_a read lock on byte 2 to byte 4 */
120 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
121 /* Child_b read lock on byte 6 to byte 8 */
122 {F_RDLCK, 0, 6L, 3L, WILLBLOCK},
123 /*
124 * Parent_c read lock on byte 3 to
125 * byte 7
126 */
127 {F_RDLCK, 0, 3L, 5L, IGNORED},
128 /* Parent_d skipped */
129 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000130
131 /* #4 Parent_a making a write lock on entire file */
132 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000133 /* Parent_b skipped */
134 {SKIP},
135 /* Child_a read lock on byte 2 to byte 4 */
136 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
137 /* Child_b read lock on byte 6 to byte 8 */
138 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
139 /*
140 * Parent_c read lock on byte 5 to
141 * byte 9
142 */
143 {F_RDLCK, 0, 5L, 5L, IGNORED},
144 /* Parent_d skipped */
145 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000146
147 /* #5 Parent_a making a write lock on entire file */
148 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000149 /* Parent_b skipped */
150 {SKIP},
151 /* Child_a read lock on byte 3 to byte 7 */
152 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
153 /* Child_b read lock on byte 5 to byte 10 */
154 {F_RDLCK, 0, 5L, 6L, WILLBLOCK},
155 /*
156 * Parent_c read lock on byte 2 to
157 * byte 8
158 */
159 {F_RDLCK, 0, 2L, 7L, IGNORED},
160 /* Parent_d skipped */
161 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000162
163 /* #6 Parent_a making a write lock on entire file */
164 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000165 /* Parent_b skipped */
166 {SKIP},
167 /* Child_a read lock on byte 2 to byte 4 */
168 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
169 /* Child_b write lock on byte 6 to byte 8 */
170 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
171 /* Parent_c no lock on byte 3 to 9 */
172 {F_UNLCK, 0, 3L, 7L, IGNORED},
173 /* Parent_d skipped */
174 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000175
176 /* #7 Parent_a making a write lock on entire file */
177 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000178 /* Parent_b read lock on byte 3 to byte 7 */
179 {F_RDLCK, 0, 3L, 5L, IGNORED},
180 /* Child_a read lock on byte 2 to byte 4 */
181 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
182 /* Child_b read lock on byte 6 to byte 8 */
183 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
184 /*
185 * Parent_c read lock on byte 1 to
186 * byte 9
187 */
188 {F_RDLCK, 0, 1L, 9L, IGNORED},
189 /* Parent_d skipped */
190 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000191
192 /* #8 Parent_a making a write lock on byte 2 to byte 4 */
193 {{F_WRLCK, 0, 2L, 3L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000194 /* Parent_b write lock on byte 6 to byte 8 */
195 {F_WRLCK, 0, 6L, 3L, IGNORED},
196 /* Child_a read lock on byte 3 to byte 7 */
197 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
198 /* Child_b skipped */
199 {SKIP},
200 /*
201 * Parent_c read lock on byte 1 to
202 * byte 5
203 */
204 {F_RDLCK, 0, 1L, 5L, IGNORED},
205 /*
206 * Parent_d read lock on
207 * byte 5 to byte 9
208 */
209 {F_RDLCK, 0, 5L, 5L,
210 IGNORED},},
plars865695b2001-08-27 22:15:12 +0000211
212 /* #9 Parent_a making a write lock on entire file */
213 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000214 /* Parent_b read lock on byte 3 to byte 7 */
215 {F_RDLCK, 0, 3L, 5L, IGNORED},
216 /* Child_a read lock on byte 2 to byte 4 */
217 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
218 /* Child_b read lock on byte 6 to byte 8 */
219 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
220 /*
221 * Parent_c read lock on byte 1 to
222 * byte 3
223 */
224 {F_RDLCK, 0, 1L, 3L, IGNORED},
225 /*
226 * Parent_d read lock on
227 * byte 7 to byte 9
228 */
229 {F_RDLCK, 0, 7L, 3L,
230 IGNORED},},
plars865695b2001-08-27 22:15:12 +0000231
232 /* #10 Parent_a making a write lock on entire file */
233 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000234 /* Parent_b skipped */
235 {SKIP},
236 /* Child_a read lock on byte 2 to byte 4 */
237 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
238 /* Child_b read lock on byte 6 to byte 8 */
239 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
240 /*
241 * Parent_c read lock on byte 1 to
242 * byte 7
243 */
244 {F_RDLCK, 0, 1L, 7L, IGNORED},
245 /*
246 * Parent_d read lock on
247 * byte 3 to byte 9
248 */
249 {F_RDLCK, 0, 3L, 7L,
250 IGNORED},},
plars865695b2001-08-27 22:15:12 +0000251
252 /* #11 Parent_a making a write lock on entire file */
253 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000254 /* Parent_b skipped */
255 {SKIP},
256 /* Child_a read lock on byte 3 to byte 7 */
257 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
258 /* Child_b read lock on byte 3 to byte 7 */
259 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
260 /*
261 * Parent_c read lock on byte 3 to
262 * byte 7
263 */
264 {F_RDLCK, 0, 3L, 5L, IGNORED},
265 /* Parent_d skipped */
266 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000267};
268
subrata_modak56207ce2009-03-23 13:35:39 +0000269static testcase *thiscase;
270static lock *thislock;
271static int parent;
272static int child_flag1 = 0;
273static int child_flag2 = 0;
274static int parent_flag = 0;
275static int alarm_flag = 0;
276static int child_pid[2], flag[2];
277static int fd;
278static int test;
279static char tmpname[40];
plars865695b2001-08-27 22:15:12 +0000280
281#define FILEDATA "tenbytes!"
282
subrata_modak56207ce2009-03-23 13:35:39 +0000283extern void catch_usr1(); /* signal catching subroutine */
284extern void catch_usr2(); /* signal catching subroutine */
285extern void catch_int(); /* signal catching subroutine */
286extern void catch_alarm(); /* signal catching subroutine */
plars865695b2001-08-27 22:15:12 +0000287
nstrazfa31d552002-05-14 16:50:06 +0000288char *TCID = "fcntl16";
plars865695b2001-08-27 22:15:12 +0000289int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +0000290
robbiewd34d5812005-07-11 22:28:09 +0000291#ifdef UCLINUX
292static char *argv0;
293#endif
294
robbiew5aab8a72003-03-26 18:05:30 +0000295/*
296 * cleanup - performs all the ONE TIME cleanup for this test at completion or
subrata_modak56207ce2009-03-23 13:35:39 +0000297 * premature exit
robbiew5aab8a72003-03-26 18:05:30 +0000298 */
subrata_modak56207ce2009-03-23 13:35:39 +0000299void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000300{
robbiew5aab8a72003-03-26 18:05:30 +0000301 TEST_CLEANUP;
302
303 tst_rmdir();
304
robbiew5aab8a72003-03-26 18:05:30 +0000305}
306
robbiew5aab8a72003-03-26 18:05:30 +0000307void dochild(int kid)
308{
309 /* child process */
robbiew9c8bd5c2005-02-07 20:03:09 +0000310 struct sigaction sact;
subrata_modak56207ce2009-03-23 13:35:39 +0000311 sact.sa_flags = 0;
312 sact.sa_handler = catch_int;
Jan Stancekc5532e42013-05-14 11:59:33 +0200313 sigemptyset(&sact.sa_mask);
subrata_modakbdbaec52009-02-26 12:14:51 +0000314 (void)sigaction(SIGUSR1, &sact, NULL);
robbiew5aab8a72003-03-26 18:05:30 +0000315
316 /* Lock should succeed after blocking and parent releases lock */
317 if (kid) {
318 if ((kill(parent, SIGUSR2)) < 0) {
319 tst_resm(TFAIL, "Attempt to send signal to parent "
320 "failed");
321 tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
322 test + 1, kid, errno);
323 exit(1);
324 }
325 } else {
326 if ((kill(parent, SIGUSR1)) < 0) {
327 tst_resm(TFAIL, "Attempt to send signal to parent "
328 "failed");
329 tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
330 test + 1, kid, errno);
331 exit(1);
332 }
333 }
334
335 if ((fcntl(fd, F_SETLKW, thislock)) < 0) {
336 if (errno == EINTR && parent_flag) {
337 /*
338 * signal received is waiting for lock to clear,
339 * this is expected if flag = WILLBLOCK
340 */
341 exit(1);
342 } else {
343 tst_resm(TFAIL, "Attempt to set child BLOCKING lock "
344 "failed");
345 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
346 errno);
347 exit(2);
348 }
349 }
350 exit(0);
subrata_modak56207ce2009-03-23 13:35:39 +0000351} /* end of child process */
robbiew5aab8a72003-03-26 18:05:30 +0000352
robbiewd34d5812005-07-11 22:28:09 +0000353#ifdef UCLINUX
354static int kid_uc;
355
subrata_modak56207ce2009-03-23 13:35:39 +0000356void dochild_uc()
robbiewd34d5812005-07-11 22:28:09 +0000357{
358 dochild(kid_uc);
359}
360#endif
361
subrata_modak56207ce2009-03-23 13:35:39 +0000362void catch_alarm()
robbiew5aab8a72003-03-26 18:05:30 +0000363{
364 alarm_flag = 1;
365}
366
subrata_modak56207ce2009-03-23 13:35:39 +0000367void catch_usr1()
368{ /* invoked on catching SIGUSR1 */
robbiew5aab8a72003-03-26 18:05:30 +0000369 /*
370 * Set flag to let parent know that child #1 is ready to have the
371 * lock removed
372 */
373 child_flag1 = 1;
374}
375
subrata_modak56207ce2009-03-23 13:35:39 +0000376void catch_usr2()
377{ /* invoked on catching SIGUSR2 */
robbiew5aab8a72003-03-26 18:05:30 +0000378 /*
379 * Set flag to let parent know that child #2 is ready to have the
380 * lock removed
381 */
382 child_flag2 = 1;
383}
384
subrata_modak56207ce2009-03-23 13:35:39 +0000385void catch_int()
386{ /* invoked on child catching SIGUSR1 */
robbiew5aab8a72003-03-26 18:05:30 +0000387 /*
388 * Set flag to interrupt fcntl call in child and force a controlled
389 * exit
390 */
391 parent_flag = 1;
392}
393
394void child_sig(int sig, int nkids)
395{
396 int i;
397
398 for (i = 0; i < nkids; i++) {
399 if (kill(child_pid[i], 0) == 0) {
400 if ((kill(child_pid[i], sig)) < 0) {
401 tst_resm(TFAIL, "Attempt to signal child %d, "
402 "failed", i + 1);
403 }
404 }
405 }
406}
407
408/*
409 * setup - performs all ONE TIME steup for this test
410 */
subrata_modak56207ce2009-03-23 13:35:39 +0000411void setup(void)
robbiew5aab8a72003-03-26 18:05:30 +0000412{
robbiew1e4cf0c2005-02-24 17:03:42 +0000413 struct sigaction sact;
mridgedb639212005-01-04 21:04:11 +0000414
robbiew5aab8a72003-03-26 18:05:30 +0000415 tst_sig(FORK, DEF_HANDLER, cleanup);
416
417 umask(0);
418
419 /* Pause if option was specified */
420 TEST_PAUSE;
421
422 parent = getpid();
423
424 tst_tmpdir();
subrata_modakbdbaec52009-02-26 12:14:51 +0000425
robbiew5aab8a72003-03-26 18:05:30 +0000426 /* set up temp filename */
427 sprintf(tmpname, "fcntl4.%d", parent);
plars865695b2001-08-27 22:15:12 +0000428
robbiew5aab8a72003-03-26 18:05:30 +0000429 /*
430 * Set up signal handling functions
431 */
robbiew1e4cf0c2005-02-24 17:03:42 +0000432 memset(&sact, 0, sizeof(sact));
subrata_modak56207ce2009-03-23 13:35:39 +0000433 sact.sa_handler = catch_usr1;
robbiew1e4cf0c2005-02-24 17:03:42 +0000434 sigemptyset(&sact.sa_mask);
435 sigaddset(&sact.sa_mask, SIGUSR1);
436 sigaction(SIGUSR1, &sact, NULL);
mridgedb639212005-01-04 21:04:11 +0000437
robbiew1e4cf0c2005-02-24 17:03:42 +0000438 memset(&sact, 0, sizeof(sact));
subrata_modak56207ce2009-03-23 13:35:39 +0000439 sact.sa_handler = catch_usr2;
robbiew1e4cf0c2005-02-24 17:03:42 +0000440 sigemptyset(&sact.sa_mask);
441 sigaddset(&sact.sa_mask, SIGUSR2);
442 sigaction(SIGUSR2, &sact, NULL);
mridgedb639212005-01-04 21:04:11 +0000443
robbiew1e4cf0c2005-02-24 17:03:42 +0000444 memset(&sact, 0, sizeof(sact));
subrata_modak56207ce2009-03-23 13:35:39 +0000445 sact.sa_handler = catch_alarm;
robbiew1e4cf0c2005-02-24 17:03:42 +0000446 sigemptyset(&sact.sa_mask);
447 sigaddset(&sact.sa_mask, SIGALRM);
448 sigaction(SIGALRM, &sact, NULL);
plars865695b2001-08-27 22:15:12 +0000449}
450
subrata_modak56207ce2009-03-23 13:35:39 +0000451int run_test(int file_flag, int file_mode, int start, int end)
plars865695b2001-08-27 22:15:12 +0000452{
453 int child_count;
454 int child;
455 int nexited;
456 int status, expect_stat;
457 int i, fail = 0;
458
459 /* loop through all test cases */
460 for (test = start; test < end; test++) {
461 /* open a temp file to lock */
462 fd = open(tmpname, file_flag, file_mode);
463 if (fd < 0) {
464 tst_brkm(TBROK, cleanup, "open failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800465 }
plars865695b2001-08-27 22:15:12 +0000466
467 /* write some dummy data to the file */
468 (void)write(fd, FILEDATA, 10);
469
470 /* Initialize first parent lock structure */
471 thiscase = &testcases[test];
472 thislock = &thiscase->parent_a;
473
474 /* set the initial parent lock on the file */
475 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
476 tst_resm(TFAIL, "First parent lock failed");
477 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
478 errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400479 close(fd);
plars865695b2001-08-27 22:15:12 +0000480 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000481 return 1;
plars865695b2001-08-27 22:15:12 +0000482 }
483
484 /* Initialize second parent lock structure */
485 thislock = &thiscase->parent_b;
486
subrata_modak56207ce2009-03-23 13:35:39 +0000487 if ((thislock->type) != IGNORED) { /*SKIPVAL */
plars865695b2001-08-27 22:15:12 +0000488 /* set the second parent lock */
489 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
490 tst_resm(TFAIL, "Second parent lock failed");
491 tst_resm(TFAIL, "Test case %d, errno = %d",
492 test + 1, errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400493 close(fd);
plars865695b2001-08-27 22:15:12 +0000494 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000495 return 1;
plars865695b2001-08-27 22:15:12 +0000496 }
497 }
498
499 /* Initialize first child lock structure */
500 thislock = &thiscase->child_a;
501
502 /* Initialize child counter and flags */
503 alarm_flag = parent_flag = 0;
504 child_flag1 = child_flag2 = 0;
505 child_count = 0;
506
507 /* spawn child processes */
508 for (i = 0; i < 2; i++) {
mridge1902af92005-01-11 16:01:53 +0000509 if (thislock->type != IGNORED) {
robbiewd34d5812005-07-11 22:28:09 +0000510 if ((child = FORK_OR_VFORK()) == 0) {
511#ifdef UCLINUX
512 if (self_exec(argv0, "ddddd", i, parent,
513 test, thislock, fd) < 0) {
514 perror("self_exec failed");
subrata_modak134e8962009-02-26 11:46:54 +0000515 return 1;
robbiewd34d5812005-07-11 22:28:09 +0000516 }
517#else
plars865695b2001-08-27 22:15:12 +0000518 dochild(i);
robbiewd34d5812005-07-11 22:28:09 +0000519#endif
plars865695b2001-08-27 22:15:12 +0000520 }
521 if (child < 0) {
522 perror("Fork failed");
subrata_modak134e8962009-02-26 11:46:54 +0000523 return 1;
plars865695b2001-08-27 22:15:12 +0000524 }
525 child_count++;
526 child_pid[i] = child;
527 flag[i] = thislock->flag;
528 }
529 /* Initialize second child lock structure */
530 thislock = &thiscase->child_b;
531 }
532 /* parent process */
533
534 /*
535 * Wait for children to signal they are ready. Set a timeout
536 * just in case they don't signal at all.
537 */
538 alarm(TIME_OUT);
539
540 while (!alarm_flag
541 && (child_flag1 + child_flag2 != child_count)) {
542 pause();
543 }
544
545 /*
546 * Turn off alarm and unmask signals
547 */
548 alarm((unsigned)0);
549
550 if (child_flag1 + child_flag2 != child_count) {
551 tst_resm(TFAIL, "Test case %d: kids didn't signal",
552 test + 1);
553 fail = 1;
554 }
555 child_flag1 = child_flag2 = alarm_flag = 0;
556
557 thislock = &thiscase->parent_c;
558
559 /* set the third parent lock on the file */
560 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
561 tst_resm(TFAIL, "Third parent lock failed");
562 tst_resm(TFAIL, "Test case %d, errno = %d",
563 test + 1, errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400564 close(fd);
plars865695b2001-08-27 22:15:12 +0000565 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000566 return 1;
plars865695b2001-08-27 22:15:12 +0000567 }
568
569 /* Initialize fourth parent lock structure */
570 thislock = &thiscase->parent_d;
571
subrata_modak56207ce2009-03-23 13:35:39 +0000572 if ((thislock->type) != IGNORED) { /*SKIPVAL */
plars865695b2001-08-27 22:15:12 +0000573 /* set the fourth parent lock */
574 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
575 tst_resm(TINFO, "Fourth parent lock failed");
576 tst_resm(TINFO, "Test case %d, errno = %d",
577 test + 1, errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400578 close(fd);
plars865695b2001-08-27 22:15:12 +0000579 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000580 return 1;
plars865695b2001-08-27 22:15:12 +0000581 }
582 }
583
584 /*
585 * Wait for children to exit, or for timeout to occur.
586 * Timeouts are expected for testcases where kids are
587 * 'WILLBLOCK', In that case, send kids a wakeup interrupt
588 * and wait again for them. If a second timeout occurs, then
589 * something is wrong.
590 */
591 alarm_flag = nexited = 0;
592 while (nexited < child_count) {
593 alarm(TIME_OUT);
594 child = wait(&status);
595 alarm(0);
596
597 if (child == -1) {
598 if (errno != EINTR || alarm_flag != 1) {
599 /*
600 * Some error other than a timeout,
601 * or else this is the second
602 * timeout. Both cases are errors.
603 */
604 break;
605 }
606
607 /*
608 * Expected timeout case. Signal kids then
609 * go back and wait again
610 */
611 child_sig(SIGUSR1, child_count);
612 continue;
613 }
614
615 for (i = 0; i < child_count; i++)
616 if (child == child_pid[i])
617 break;
618 if (i == child_count) {
619 /*
620 * Ignore unexpected kid, it could be a
621 * leftover from a previous iteration that
622 * timed out.
623 */
624 continue;
625 }
626
627 /* Found the right kid, check his status */
628 nexited++;
629
630 expect_stat = (flag[i] == NOBLOCK) ? 0 : 1;
631
632 if (!WIFEXITED(status)
633 || WEXITSTATUS(status) != expect_stat) {
634 /* got unexpected exit status from kid */
635 tst_resm(TFAIL, "Test case %d: child %d %s "
636 "or got bad status (x%x)", test + 1,
637 i, (flag[i] == NOBLOCK) ?
638 "BLOCKED unexpectedly" :
639 "failed to BLOCK", status);
640 fail = 1;
641 }
642 }
643
644 if (nexited != child_count) {
645 tst_resm(TFAIL, "Test case %d, caught %d expected %d "
646 "children", test + 1, nexited, child_count);
647 child_sig(SIGKILL, nexited);
648 fail = 1;
649 }
650 close(fd);
651 }
652 unlink(tmpname);
653 if (fail) {
subrata_modak134e8962009-02-26 11:46:54 +0000654 return 1;
plars865695b2001-08-27 22:15:12 +0000655 } else {
subrata_modak43337a32009-02-26 11:43:51 +0000656 return 0;
plars865695b2001-08-27 22:15:12 +0000657 }
subrata_modak43337a32009-02-26 11:43:51 +0000658 return 0;
plars865695b2001-08-27 22:15:12 +0000659}
660
robbiew5aab8a72003-03-26 18:05:30 +0000661int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000662{
subrata_modakbdbaec52009-02-26 12:14:51 +0000663
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200664 int lc;
665 char *msg;
plars865695b2001-08-27 22:15:12 +0000666
Garrett Cooper45e285d2010-11-22 12:19:25 -0800667 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800668 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiew5aab8a72003-03-26 18:05:30 +0000669 }
robbiewd34d5812005-07-11 22:28:09 +0000670#ifdef UCLINUX
671 maybe_run_child(dochild_uc, "ddddd", &kid_uc, &parent, &test,
672 &thislock, &fd);
673 argv0 = av[0];
674#endif
675
subrata_modak56207ce2009-03-23 13:35:39 +0000676 setup(); /* global setup */
robbiew5aab8a72003-03-26 18:05:30 +0000677
robbiew5aab8a72003-03-26 18:05:30 +0000678 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800679 /* reset tst_count in case we are looping */
680 tst_count = 0;
robbiew5aab8a72003-03-26 18:05:30 +0000681
mridgedb639212005-01-04 21:04:11 +0000682/* //block1: */
subrata_modak4bb656a2009-02-26 12:02:09 +0000683 /*
robbiew5aab8a72003-03-26 18:05:30 +0000684 * Check file locks on an ordinary file without
685 * mandatory locking
686 */
687 tst_resm(TINFO, "Entering block 1");
688 if (run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 0, 11)) {
689 tst_resm(TINFO, "Test case 1: without mandatory "
690 "locking FAILED");
691 } else {
692 tst_resm(TINFO, "Test case 1: without manadatory "
693 "locking PASSED");
694 }
695 tst_resm(TINFO, "Exiting block 1");
696
mridgedb639212005-01-04 21:04:11 +0000697/* //block2: */
robbiew5aab8a72003-03-26 18:05:30 +0000698 /*
699 * Check the file locks on a file with mandatory record
700 * locking
701 */
702 tst_resm(TINFO, "Entering block 2");
703 if (run_test(O_CREAT | O_RDWR | O_TRUNC, S_ISGID |
704 S_IRUSR | S_IWUSR, 0, 11)) {
705 tst_resm(TINFO, "Test case 2: with mandatory record "
706 "locking FAILED");
707 } else {
708 tst_resm(TINFO, "Test case 2: with mandatory record "
709 "locking PASSED");
710 }
711 tst_resm(TINFO, "Exiting block 2");
712
mridgedb639212005-01-04 21:04:11 +0000713/* //block3: */
robbiew5aab8a72003-03-26 18:05:30 +0000714 /*
715 * Check file locks on a file with mandatory record locking
716 * and no delay
717 */
718 tst_resm(TINFO, "Entering block 3");
719 if (run_test(O_CREAT | O_RDWR | O_TRUNC | O_NDELAY,
720 S_ISGID | S_IRUSR | S_IWUSR, 0, 11)) {
721 tst_resm(TINFO, "Test case 3: mandatory locking with "
722 "NODELAY FAILED");
723 } else {
724 tst_resm(TINFO, "Test case 3: mandatory locking with "
725 "NODELAY PASSED");
726 }
727 tst_resm(TINFO, "Exiting block 3");
728 }
729 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800730 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700731}