blob: 5c8768054a4550763e32a04136069e260d69ef83 [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"
robbiew5aab8a72003-03-26 18:05:30 +000049#include <sys/stat.h>
50#include <sys/types.h>
mridgedb639212005-01-04 21:04:11 +000051#include <sys/wait.h>
plars865695b2001-08-27 22:15:12 +000052
Xiong Zhoua2d860c2014-08-26 03:01:26 -040053#include "tst_fs_type.h"
54
mridgedb639212005-01-04 21:04:11 +000055#define SKIPVAL 0x0f00
subrata_modak56207ce2009-03-23 13:35:39 +000056//#define SKIP SKIPVAL, 0, 0L, 0L, IGNORED
mridge1902af92005-01-11 16:01:53 +000057#define SKIP 0,0,0L,0L,0
mridgedb639212005-01-04 21:04:11 +000058#if (SKIPVAL == F_RDLCK) || (SKIPVAL == F_WRLCK)
59#error invalid SKIP, must not be F_RDLCK or F_WRLCK
60#endif
plars865695b2001-08-27 22:15:12 +000061
62#define IGNORED 0
63#define NOBLOCK 2 /* immediate success */
64#define WILLBLOCK 3 /* blocks, succeeds, parent unlocks records */
65#define TIME_OUT 10
Xiong Zhoua2d860c2014-08-26 03:01:26 -040066int NO_NFS = 1; /* Test on NFS or not */
plars865695b2001-08-27 22:15:12 +000067
68typedef struct {
Cyril Hrubisb87a83c2013-11-07 12:05:25 +010069 struct flock parent_a;
70 struct flock parent_b;
71 struct flock child_a;
72 struct flock child_b;
73 struct flock parent_c;
74 struct flock parent_d;
plars865695b2001-08-27 22:15:12 +000075} testcase;
76
77static testcase testcases[] = {
78 /* #1 Parent_a making a write lock on entire file */
subrata_modak56207ce2009-03-23 13:35:39 +000079 {{F_WRLCK, 0, 0L, 0L, IGNORED},
80 /* Parent_b skipped */
81 {SKIP},
82 /* Child_a read lock on byte 1 to byte 5 */
83 {F_RDLCK, 0, 0L, 5L, NOBLOCK},
84 /* Child_b read lock on byte 6 to byte 10 */
85 {F_RDLCK, 0, 6L, 5L, NOBLOCK},
86 /*
87 * Parent_c read lock on entire file
88 */
89 {F_RDLCK, 0, 0L, 0L, IGNORED},
90 /* Parent_d skipped */
91 {SKIP},},
plars865695b2001-08-27 22:15:12 +000092
93 /* #2 Parent_a making a write lock on entire file */
94 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +000095 /* Parent_b skipped */
96 {SKIP},
97 /* Child_a read lock on byte 1 to byte 5 */
98 {F_RDLCK, 0, 0L, 5L, WILLBLOCK},
99 /* Child_b read lock on byte 6 to byte 10 */
100 {F_RDLCK, 0, 6L, 5L, WILLBLOCK},
101 /*
102 * Parent_c write lock on entire
103 * file
104 */
105 {F_WRLCK, 0, 0L, 0L, IGNORED},
106 /* Parent_d skipped */
107 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000108
109 /* #3 Parent_a making a write lock on entire file */
110 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000111 /* Parent_b skipped */
112 {SKIP},
113 /* Child_a read lock on byte 2 to byte 4 */
114 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
115 /* Child_b read lock on byte 6 to byte 8 */
116 {F_RDLCK, 0, 6L, 3L, WILLBLOCK},
117 /*
118 * Parent_c read lock on byte 3 to
119 * byte 7
120 */
121 {F_RDLCK, 0, 3L, 5L, IGNORED},
122 /* Parent_d skipped */
123 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000124
125 /* #4 Parent_a making a write lock on entire file */
126 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000127 /* Parent_b skipped */
128 {SKIP},
129 /* Child_a read lock on byte 2 to byte 4 */
130 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
131 /* Child_b read lock on byte 6 to byte 8 */
132 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
133 /*
134 * Parent_c read lock on byte 5 to
135 * byte 9
136 */
137 {F_RDLCK, 0, 5L, 5L, IGNORED},
138 /* Parent_d skipped */
139 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000140
141 /* #5 Parent_a making a write lock on entire file */
142 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000143 /* Parent_b skipped */
144 {SKIP},
145 /* Child_a read lock on byte 3 to byte 7 */
146 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
147 /* Child_b read lock on byte 5 to byte 10 */
148 {F_RDLCK, 0, 5L, 6L, WILLBLOCK},
149 /*
150 * Parent_c read lock on byte 2 to
151 * byte 8
152 */
153 {F_RDLCK, 0, 2L, 7L, IGNORED},
154 /* Parent_d skipped */
155 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000156
157 /* #6 Parent_a making a write lock on entire file */
158 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000159 /* Parent_b skipped */
160 {SKIP},
161 /* Child_a read lock on byte 2 to byte 4 */
162 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
163 /* Child_b write lock on byte 6 to byte 8 */
164 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
165 /* Parent_c no lock on byte 3 to 9 */
166 {F_UNLCK, 0, 3L, 7L, IGNORED},
167 /* Parent_d skipped */
168 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000169
170 /* #7 Parent_a making a write lock on entire file */
171 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000172 /* Parent_b read lock on byte 3 to byte 7 */
173 {F_RDLCK, 0, 3L, 5L, IGNORED},
174 /* Child_a read lock on byte 2 to byte 4 */
175 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
176 /* Child_b read lock on byte 6 to byte 8 */
177 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
178 /*
179 * Parent_c read lock on byte 1 to
180 * byte 9
181 */
182 {F_RDLCK, 0, 1L, 9L, IGNORED},
183 /* Parent_d skipped */
184 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000185
186 /* #8 Parent_a making a write lock on byte 2 to byte 4 */
187 {{F_WRLCK, 0, 2L, 3L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000188 /* Parent_b write lock on byte 6 to byte 8 */
189 {F_WRLCK, 0, 6L, 3L, IGNORED},
190 /* Child_a read lock on byte 3 to byte 7 */
191 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
192 /* Child_b skipped */
193 {SKIP},
194 /*
195 * Parent_c read lock on byte 1 to
196 * byte 5
197 */
198 {F_RDLCK, 0, 1L, 5L, IGNORED},
199 /*
200 * Parent_d read lock on
201 * byte 5 to byte 9
202 */
203 {F_RDLCK, 0, 5L, 5L,
204 IGNORED},},
plars865695b2001-08-27 22:15:12 +0000205
206 /* #9 Parent_a making a write lock on entire file */
207 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000208 /* Parent_b read lock on byte 3 to byte 7 */
209 {F_RDLCK, 0, 3L, 5L, IGNORED},
210 /* Child_a read lock on byte 2 to byte 4 */
211 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
212 /* Child_b read lock on byte 6 to byte 8 */
213 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
214 /*
215 * Parent_c read lock on byte 1 to
216 * byte 3
217 */
218 {F_RDLCK, 0, 1L, 3L, IGNORED},
219 /*
220 * Parent_d read lock on
221 * byte 7 to byte 9
222 */
223 {F_RDLCK, 0, 7L, 3L,
224 IGNORED},},
plars865695b2001-08-27 22:15:12 +0000225
226 /* #10 Parent_a making a write lock on entire file */
227 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000228 /* Parent_b skipped */
229 {SKIP},
230 /* Child_a read lock on byte 2 to byte 4 */
231 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
232 /* Child_b read lock on byte 6 to byte 8 */
233 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
234 /*
235 * Parent_c read lock on byte 1 to
236 * byte 7
237 */
238 {F_RDLCK, 0, 1L, 7L, IGNORED},
239 /*
240 * Parent_d read lock on
241 * byte 3 to byte 9
242 */
243 {F_RDLCK, 0, 3L, 7L,
244 IGNORED},},
plars865695b2001-08-27 22:15:12 +0000245
246 /* #11 Parent_a making a write lock on entire file */
247 {{F_WRLCK, 0, 0L, 0L, IGNORED},
subrata_modak56207ce2009-03-23 13:35:39 +0000248 /* Parent_b skipped */
249 {SKIP},
250 /* Child_a read lock on byte 3 to byte 7 */
251 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
252 /* Child_b read lock on byte 3 to byte 7 */
253 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
254 /*
255 * Parent_c read lock on byte 3 to
256 * byte 7
257 */
258 {F_RDLCK, 0, 3L, 5L, IGNORED},
259 /* Parent_d skipped */
260 {SKIP},},
plars865695b2001-08-27 22:15:12 +0000261};
262
subrata_modak56207ce2009-03-23 13:35:39 +0000263static testcase *thiscase;
Cyril Hrubisb87a83c2013-11-07 12:05:25 +0100264static struct flock *thislock;
subrata_modak56207ce2009-03-23 13:35:39 +0000265static int parent;
266static int child_flag1 = 0;
267static int child_flag2 = 0;
268static int parent_flag = 0;
269static int alarm_flag = 0;
270static int child_pid[2], flag[2];
271static int fd;
272static int test;
273static char tmpname[40];
plars865695b2001-08-27 22:15:12 +0000274
275#define FILEDATA "tenbytes!"
276
Mike Frysingere61ddba2014-04-09 23:24:32 -0400277extern void catch_int(int sig); /* signal catching subroutine */
plars865695b2001-08-27 22:15:12 +0000278
nstrazfa31d552002-05-14 16:50:06 +0000279char *TCID = "fcntl16";
plars865695b2001-08-27 22:15:12 +0000280int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +0000281
robbiewd34d5812005-07-11 22:28:09 +0000282#ifdef UCLINUX
283static char *argv0;
284#endif
285
robbiew5aab8a72003-03-26 18:05:30 +0000286/*
287 * cleanup - performs all the ONE TIME cleanup for this test at completion or
subrata_modak56207ce2009-03-23 13:35:39 +0000288 * premature exit
robbiew5aab8a72003-03-26 18:05:30 +0000289 */
subrata_modak56207ce2009-03-23 13:35:39 +0000290void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000291{
robbiew5aab8a72003-03-26 18:05:30 +0000292 tst_rmdir();
293
robbiew5aab8a72003-03-26 18:05:30 +0000294}
295
robbiew5aab8a72003-03-26 18:05:30 +0000296void dochild(int kid)
297{
298 /* child process */
robbiew9c8bd5c2005-02-07 20:03:09 +0000299 struct sigaction sact;
subrata_modak56207ce2009-03-23 13:35:39 +0000300 sact.sa_flags = 0;
301 sact.sa_handler = catch_int;
Jan Stancekc5532e42013-05-14 11:59:33 +0200302 sigemptyset(&sact.sa_mask);
subrata_modakbdbaec52009-02-26 12:14:51 +0000303 (void)sigaction(SIGUSR1, &sact, NULL);
robbiew5aab8a72003-03-26 18:05:30 +0000304
305 /* Lock should succeed after blocking and parent releases lock */
306 if (kid) {
307 if ((kill(parent, SIGUSR2)) < 0) {
308 tst_resm(TFAIL, "Attempt to send signal to parent "
309 "failed");
310 tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
311 test + 1, kid, errno);
312 exit(1);
313 }
314 } else {
315 if ((kill(parent, SIGUSR1)) < 0) {
316 tst_resm(TFAIL, "Attempt to send signal to parent "
317 "failed");
318 tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
319 test + 1, kid, errno);
320 exit(1);
321 }
322 }
323
324 if ((fcntl(fd, F_SETLKW, thislock)) < 0) {
325 if (errno == EINTR && parent_flag) {
326 /*
327 * signal received is waiting for lock to clear,
328 * this is expected if flag = WILLBLOCK
329 */
330 exit(1);
331 } else {
332 tst_resm(TFAIL, "Attempt to set child BLOCKING lock "
333 "failed");
334 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
335 errno);
336 exit(2);
337 }
338 }
339 exit(0);
subrata_modak56207ce2009-03-23 13:35:39 +0000340} /* end of child process */
robbiew5aab8a72003-03-26 18:05:30 +0000341
robbiewd34d5812005-07-11 22:28:09 +0000342#ifdef UCLINUX
343static int kid_uc;
344
Mike Frysingerc57fba52014-04-09 18:56:30 -0400345void dochild_uc(void)
robbiewd34d5812005-07-11 22:28:09 +0000346{
347 dochild(kid_uc);
348}
349#endif
350
Mike Frysingere61ddba2014-04-09 23:24:32 -0400351void catch_alarm(int sig)
robbiew5aab8a72003-03-26 18:05:30 +0000352{
353 alarm_flag = 1;
354}
355
Mike Frysingere61ddba2014-04-09 23:24:32 -0400356void catch_usr1(int sig)
subrata_modak56207ce2009-03-23 13:35:39 +0000357{ /* invoked on catching SIGUSR1 */
robbiew5aab8a72003-03-26 18:05:30 +0000358 /*
359 * Set flag to let parent know that child #1 is ready to have the
360 * lock removed
361 */
362 child_flag1 = 1;
363}
364
Mike Frysingere61ddba2014-04-09 23:24:32 -0400365void catch_usr2(int sig)
subrata_modak56207ce2009-03-23 13:35:39 +0000366{ /* invoked on catching SIGUSR2 */
robbiew5aab8a72003-03-26 18:05:30 +0000367 /*
368 * Set flag to let parent know that child #2 is ready to have the
369 * lock removed
370 */
371 child_flag2 = 1;
372}
373
Mike Frysingere61ddba2014-04-09 23:24:32 -0400374void catch_int(int sig)
subrata_modak56207ce2009-03-23 13:35:39 +0000375{ /* invoked on child catching SIGUSR1 */
robbiew5aab8a72003-03-26 18:05:30 +0000376 /*
377 * Set flag to interrupt fcntl call in child and force a controlled
378 * exit
379 */
380 parent_flag = 1;
381}
382
383void child_sig(int sig, int nkids)
384{
385 int i;
386
387 for (i = 0; i < nkids; i++) {
388 if (kill(child_pid[i], 0) == 0) {
389 if ((kill(child_pid[i], sig)) < 0) {
390 tst_resm(TFAIL, "Attempt to signal child %d, "
391 "failed", i + 1);
392 }
393 }
394 }
395}
396
397/*
398 * setup - performs all ONE TIME steup for this test
399 */
subrata_modak56207ce2009-03-23 13:35:39 +0000400void setup(void)
robbiew5aab8a72003-03-26 18:05:30 +0000401{
robbiew1e4cf0c2005-02-24 17:03:42 +0000402 struct sigaction sact;
mridgedb639212005-01-04 21:04:11 +0000403
robbiew5aab8a72003-03-26 18:05:30 +0000404 tst_sig(FORK, DEF_HANDLER, cleanup);
405
406 umask(0);
407
408 /* Pause if option was specified */
409 TEST_PAUSE;
410
411 parent = getpid();
412
413 tst_tmpdir();
subrata_modakbdbaec52009-02-26 12:14:51 +0000414
Xiong Zhoua2d860c2014-08-26 03:01:26 -0400415 /* On NFS or not */
416 if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC)
417 NO_NFS = 0;
418
robbiew5aab8a72003-03-26 18:05:30 +0000419 /* set up temp filename */
420 sprintf(tmpname, "fcntl4.%d", parent);
plars865695b2001-08-27 22:15:12 +0000421
robbiew5aab8a72003-03-26 18:05:30 +0000422 /*
423 * Set up signal handling functions
424 */
robbiew1e4cf0c2005-02-24 17:03:42 +0000425 memset(&sact, 0, sizeof(sact));
subrata_modak56207ce2009-03-23 13:35:39 +0000426 sact.sa_handler = catch_usr1;
robbiew1e4cf0c2005-02-24 17:03:42 +0000427 sigemptyset(&sact.sa_mask);
428 sigaddset(&sact.sa_mask, SIGUSR1);
429 sigaction(SIGUSR1, &sact, NULL);
mridgedb639212005-01-04 21:04:11 +0000430
robbiew1e4cf0c2005-02-24 17:03:42 +0000431 memset(&sact, 0, sizeof(sact));
subrata_modak56207ce2009-03-23 13:35:39 +0000432 sact.sa_handler = catch_usr2;
robbiew1e4cf0c2005-02-24 17:03:42 +0000433 sigemptyset(&sact.sa_mask);
434 sigaddset(&sact.sa_mask, SIGUSR2);
435 sigaction(SIGUSR2, &sact, NULL);
mridgedb639212005-01-04 21:04:11 +0000436
robbiew1e4cf0c2005-02-24 17:03:42 +0000437 memset(&sact, 0, sizeof(sact));
subrata_modak56207ce2009-03-23 13:35:39 +0000438 sact.sa_handler = catch_alarm;
robbiew1e4cf0c2005-02-24 17:03:42 +0000439 sigemptyset(&sact.sa_mask);
440 sigaddset(&sact.sa_mask, SIGALRM);
441 sigaction(SIGALRM, &sact, NULL);
plars865695b2001-08-27 22:15:12 +0000442}
443
subrata_modak56207ce2009-03-23 13:35:39 +0000444int run_test(int file_flag, int file_mode, int start, int end)
plars865695b2001-08-27 22:15:12 +0000445{
446 int child_count;
447 int child;
448 int nexited;
449 int status, expect_stat;
450 int i, fail = 0;
451
452 /* loop through all test cases */
453 for (test = start; test < end; test++) {
454 /* open a temp file to lock */
455 fd = open(tmpname, file_flag, file_mode);
456 if (fd < 0) {
457 tst_brkm(TBROK, cleanup, "open failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800458 }
plars865695b2001-08-27 22:15:12 +0000459
460 /* write some dummy data to the file */
461 (void)write(fd, FILEDATA, 10);
462
463 /* Initialize first parent lock structure */
464 thiscase = &testcases[test];
465 thislock = &thiscase->parent_a;
466
467 /* set the initial parent lock on the file */
468 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
469 tst_resm(TFAIL, "First parent lock failed");
470 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
471 errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400472 close(fd);
plars865695b2001-08-27 22:15:12 +0000473 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000474 return 1;
plars865695b2001-08-27 22:15:12 +0000475 }
476
477 /* Initialize second parent lock structure */
478 thislock = &thiscase->parent_b;
479
Cyril Hrubisb87a83c2013-11-07 12:05:25 +0100480 if ((thislock->l_type) != IGNORED) { /*SKIPVAL */
plars865695b2001-08-27 22:15:12 +0000481 /* set the second parent lock */
482 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
483 tst_resm(TFAIL, "Second parent lock failed");
484 tst_resm(TFAIL, "Test case %d, errno = %d",
485 test + 1, errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400486 close(fd);
plars865695b2001-08-27 22:15:12 +0000487 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000488 return 1;
plars865695b2001-08-27 22:15:12 +0000489 }
490 }
491
492 /* Initialize first child lock structure */
493 thislock = &thiscase->child_a;
494
495 /* Initialize child counter and flags */
496 alarm_flag = parent_flag = 0;
497 child_flag1 = child_flag2 = 0;
498 child_count = 0;
499
500 /* spawn child processes */
501 for (i = 0; i < 2; i++) {
Cyril Hrubisb87a83c2013-11-07 12:05:25 +0100502 if (thislock->l_type != IGNORED) {
robbiewd34d5812005-07-11 22:28:09 +0000503 if ((child = FORK_OR_VFORK()) == 0) {
504#ifdef UCLINUX
505 if (self_exec(argv0, "ddddd", i, parent,
506 test, thislock, fd) < 0) {
507 perror("self_exec failed");
subrata_modak134e8962009-02-26 11:46:54 +0000508 return 1;
robbiewd34d5812005-07-11 22:28:09 +0000509 }
510#else
plars865695b2001-08-27 22:15:12 +0000511 dochild(i);
robbiewd34d5812005-07-11 22:28:09 +0000512#endif
plars865695b2001-08-27 22:15:12 +0000513 }
514 if (child < 0) {
515 perror("Fork failed");
subrata_modak134e8962009-02-26 11:46:54 +0000516 return 1;
plars865695b2001-08-27 22:15:12 +0000517 }
518 child_count++;
519 child_pid[i] = child;
Cyril Hrubisb87a83c2013-11-07 12:05:25 +0100520 flag[i] = thislock->l_pid;
plars865695b2001-08-27 22:15:12 +0000521 }
522 /* Initialize second child lock structure */
523 thislock = &thiscase->child_b;
524 }
525 /* parent process */
526
527 /*
528 * Wait for children to signal they are ready. Set a timeout
529 * just in case they don't signal at all.
530 */
531 alarm(TIME_OUT);
532
533 while (!alarm_flag
534 && (child_flag1 + child_flag2 != child_count)) {
535 pause();
536 }
537
538 /*
539 * Turn off alarm and unmask signals
540 */
541 alarm((unsigned)0);
542
543 if (child_flag1 + child_flag2 != child_count) {
544 tst_resm(TFAIL, "Test case %d: kids didn't signal",
545 test + 1);
546 fail = 1;
547 }
548 child_flag1 = child_flag2 = alarm_flag = 0;
549
550 thislock = &thiscase->parent_c;
551
552 /* set the third parent lock on the file */
553 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
554 tst_resm(TFAIL, "Third parent lock failed");
555 tst_resm(TFAIL, "Test case %d, errno = %d",
556 test + 1, errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400557 close(fd);
plars865695b2001-08-27 22:15:12 +0000558 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000559 return 1;
plars865695b2001-08-27 22:15:12 +0000560 }
561
562 /* Initialize fourth parent lock structure */
563 thislock = &thiscase->parent_d;
564
Cyril Hrubisb87a83c2013-11-07 12:05:25 +0100565 if ((thislock->l_type) != IGNORED) { /*SKIPVAL */
plars865695b2001-08-27 22:15:12 +0000566 /* set the fourth parent lock */
567 if ((fcntl(fd, F_SETLK, thislock)) < 0) {
568 tst_resm(TINFO, "Fourth parent lock failed");
569 tst_resm(TINFO, "Test case %d, errno = %d",
570 test + 1, errno);
Stanislav Kholmanskikh8c200cb2013-10-31 12:41:47 +0400571 close(fd);
plars865695b2001-08-27 22:15:12 +0000572 unlink(tmpname);
subrata_modak134e8962009-02-26 11:46:54 +0000573 return 1;
plars865695b2001-08-27 22:15:12 +0000574 }
575 }
576
577 /*
578 * Wait for children to exit, or for timeout to occur.
579 * Timeouts are expected for testcases where kids are
580 * 'WILLBLOCK', In that case, send kids a wakeup interrupt
581 * and wait again for them. If a second timeout occurs, then
582 * something is wrong.
583 */
584 alarm_flag = nexited = 0;
585 while (nexited < child_count) {
586 alarm(TIME_OUT);
587 child = wait(&status);
588 alarm(0);
589
590 if (child == -1) {
591 if (errno != EINTR || alarm_flag != 1) {
592 /*
593 * Some error other than a timeout,
594 * or else this is the second
595 * timeout. Both cases are errors.
596 */
597 break;
598 }
599
600 /*
601 * Expected timeout case. Signal kids then
602 * go back and wait again
603 */
604 child_sig(SIGUSR1, child_count);
605 continue;
606 }
607
608 for (i = 0; i < child_count; i++)
609 if (child == child_pid[i])
610 break;
611 if (i == child_count) {
612 /*
613 * Ignore unexpected kid, it could be a
614 * leftover from a previous iteration that
615 * timed out.
616 */
617 continue;
618 }
619
620 /* Found the right kid, check his status */
621 nexited++;
622
623 expect_stat = (flag[i] == NOBLOCK) ? 0 : 1;
624
625 if (!WIFEXITED(status)
626 || WEXITSTATUS(status) != expect_stat) {
627 /* got unexpected exit status from kid */
628 tst_resm(TFAIL, "Test case %d: child %d %s "
629 "or got bad status (x%x)", test + 1,
630 i, (flag[i] == NOBLOCK) ?
631 "BLOCKED unexpectedly" :
632 "failed to BLOCK", status);
633 fail = 1;
634 }
635 }
636
637 if (nexited != child_count) {
638 tst_resm(TFAIL, "Test case %d, caught %d expected %d "
639 "children", test + 1, nexited, child_count);
640 child_sig(SIGKILL, nexited);
641 fail = 1;
642 }
643 close(fd);
644 }
645 unlink(tmpname);
646 if (fail) {
subrata_modak134e8962009-02-26 11:46:54 +0000647 return 1;
plars865695b2001-08-27 22:15:12 +0000648 } else {
subrata_modak43337a32009-02-26 11:43:51 +0000649 return 0;
plars865695b2001-08-27 22:15:12 +0000650 }
subrata_modak43337a32009-02-26 11:43:51 +0000651 return 0;
plars865695b2001-08-27 22:15:12 +0000652}
653
robbiew5aab8a72003-03-26 18:05:30 +0000654int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000655{
subrata_modakbdbaec52009-02-26 12:14:51 +0000656
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200657 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200658 const char *msg;
plars865695b2001-08-27 22:15:12 +0000659
Garrett Cooper45e285d2010-11-22 12:19:25 -0800660 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800661 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiew5aab8a72003-03-26 18:05:30 +0000662 }
robbiewd34d5812005-07-11 22:28:09 +0000663#ifdef UCLINUX
664 maybe_run_child(dochild_uc, "ddddd", &kid_uc, &parent, &test,
665 &thislock, &fd);
666 argv0 = av[0];
667#endif
668
subrata_modak56207ce2009-03-23 13:35:39 +0000669 setup(); /* global setup */
robbiew5aab8a72003-03-26 18:05:30 +0000670
robbiew5aab8a72003-03-26 18:05:30 +0000671 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800672 /* reset tst_count in case we are looping */
673 tst_count = 0;
robbiew5aab8a72003-03-26 18:05:30 +0000674
mridgedb639212005-01-04 21:04:11 +0000675/* //block1: */
subrata_modak4bb656a2009-02-26 12:02:09 +0000676 /*
robbiew5aab8a72003-03-26 18:05:30 +0000677 * Check file locks on an ordinary file without
678 * mandatory locking
679 */
680 tst_resm(TINFO, "Entering block 1");
681 if (run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 0, 11)) {
682 tst_resm(TINFO, "Test case 1: without mandatory "
683 "locking FAILED");
684 } else {
685 tst_resm(TINFO, "Test case 1: without manadatory "
686 "locking PASSED");
687 }
688 tst_resm(TINFO, "Exiting block 1");
689
mridgedb639212005-01-04 21:04:11 +0000690/* //block2: */
robbiew5aab8a72003-03-26 18:05:30 +0000691 /*
692 * Check the file locks on a file with mandatory record
693 * locking
694 */
695 tst_resm(TINFO, "Entering block 2");
Xiong Zhoua2d860c2014-08-26 03:01:26 -0400696 if (NO_NFS && run_test(O_CREAT | O_RDWR | O_TRUNC, S_ISGID |
robbiew5aab8a72003-03-26 18:05:30 +0000697 S_IRUSR | S_IWUSR, 0, 11)) {
698 tst_resm(TINFO, "Test case 2: with mandatory record "
699 "locking FAILED");
700 } else {
Xiong Zhoua2d860c2014-08-26 03:01:26 -0400701 if (NO_NFS)
702 tst_resm(TINFO, "Test case 2: with mandatory"
703 " record locking PASSED");
704 else
705 tst_resm(TCONF, "Test case 2: NFS does not"
706 " support mandatory locking");
robbiew5aab8a72003-03-26 18:05:30 +0000707 }
708 tst_resm(TINFO, "Exiting block 2");
709
mridgedb639212005-01-04 21:04:11 +0000710/* //block3: */
robbiew5aab8a72003-03-26 18:05:30 +0000711 /*
712 * Check file locks on a file with mandatory record locking
713 * and no delay
714 */
715 tst_resm(TINFO, "Entering block 3");
Xiong Zhoua2d860c2014-08-26 03:01:26 -0400716 if (NO_NFS && run_test(O_CREAT | O_RDWR | O_TRUNC | O_NDELAY,
robbiew5aab8a72003-03-26 18:05:30 +0000717 S_ISGID | S_IRUSR | S_IWUSR, 0, 11)) {
718 tst_resm(TINFO, "Test case 3: mandatory locking with "
719 "NODELAY FAILED");
720 } else {
Xiong Zhoua2d860c2014-08-26 03:01:26 -0400721 if (NO_NFS)
722 tst_resm(TINFO, "Test case 3: mandatory"
723 " locking with NODELAY PASSED");
724 else
725 tst_resm(TCONF, "Test case 3: NFS does not"
726 " support mandatory locking");
robbiew5aab8a72003-03-26 18:05:30 +0000727 }
728 tst_resm(TINFO, "Exiting block 3");
729 }
730 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800731 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700732}