1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Lock operation C testcase */
28
29 #include "nfsgen.h"
30
31 #define READ_FAIL 1
32 #define WRITE_FAIL 2
33
34 /* Functions */
35 int scenarioA(int mode, int oflag, int expect[]);
36 int scenarioB(int mode, int oflag, int expect[]);
37 int scenarioC(int mode, int oflag, int expect[]);
38
39 /* Globals */
40
41 static char *filename = NULL;
42 char *buf = NULL;
43 int N = 100; /* used for scenario C loops */
44
45 /*
46 * Main test loop.
47 */
48
49 int
50 main(int argc, char **argv)
51 {
52 int i, j;
53 int ret = OK;
54 char *deleg, *scen, *mode_index, *oflag_index;
55 static int mode_set[] = {0600, 0400, 0200, 000},
56 oflag_set[] = {O_EXCL|O_RDWR, O_RDWR, O_WRONLY,
57 O_RDONLY};
58 static int expect[4][4][6] =
59 {
60 { {OK, OK, OK, OK, EAGAIN, EAGAIN},
61 {OK, OK, OK, OK, EAGAIN, EAGAIN},
62 {OK, OK, EBADF, OK, EBADF, EAGAIN},
63 {OK, OK, OK, EBADF, EAGAIN, EBADF}},
64 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
65 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
66 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
67 {OK, OK, OK, EBADF, EAGAIN, EBADF}},
68 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
69 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
70 {OK, OK, EBADF, OK, EBADF, EAGAIN},
71 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF}},
72 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
73 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
74 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
75 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF}}
76 };
77
78 if ((buf = malloc(256)) == NULL) {
79 perror("main()- malloc() for buf");
80 return (NOOK);
81 }
82
83 parse_args(argc, argv);
84
85 filename = lfilename;
86
87 dprint("Try to remove test files, to avoid errors.\n");
88 unlink_file(filename);
89 unlink_file("linkfile.txt");
90
91 /* modify name to include delgation policy */
92 if ((deleg = getenv("DELG")) != NULL) {
93 if (strcasecmp(deleg, "on") == 0) {
94 strcat(Testname, "_Deleg");
95 }
96 if (strcasecmp(deleg, "off") == 0) {
97 strcat(Testname, "_NoDeleg");
98 }
99 }
100
101 scen = getenv("SCENARIO");
102 if (!scen) {
103 printf("The scenario was not specified");
104 return (NOOK);
105 }
106
107 if ((mode_index = getenv("MODE_INDEX")) != NULL) {
108 i = atoi(mode_index);
109 if ((i > 3) && (strcmp(scen, "C") != 0)) {
110 printf("The mode index(%d) is more than 3 "\
111 "with scenario %s", i, scen);
112 return (NOOK);
113 } else if (i > 6) {
114 printf("The mode index(%d) is more than 6 "\
115 "with scenario %s", i, scen);
116 return (NOOK);
117 }
118 }
119
120 if ((oflag_index = getenv("OFLAG_INDEX")) != NULL) {
121 j = atoi(oflag_index);
122 if (j > 3) {
123 printf("The oflag index(%d) is more than 3 "\
124 "with scenario %s", i, scen);
125 return (NOOK);
126 }
127 }
128
129
130 /* run tests */
131 switch (*scen) {
132 case 'A':
133 ret = scenarioA(mode_set[i], oflag_set[j], expect[i][j]);
134 break;
135 case 'B':
136 ret = scenarioB(mode_set[i], oflag_set[j], expect[i][j]);
137 break;
138 case 'C':
139 scenarioC(0600, O_CREAT|O_TRUNC|O_RDWR, expect[0][1]);
140 break;
141 default:
142 printf("Set invalid scenario(%s)", scen);
143 return (NOOK);
144 }
145
146 if (buf != NULL)
147 free(buf);
148 if (GLOBdata != NULL)
149 free(GLOBdata);
150
151 exit_test(ret);
152 return (OK); /* unreachable, used to quiet lint */
153 }
154
155 int
156 scenarioA(int mode, int oflag, int expect[])
157 {
158 int fd1, fd2;
159 char *DD;
160 int flg = 0;
161 int expt;
162 int ret = OK;
163
164 scen = "ScenA";
165 scen_mode = mode;
166 scen_flag = oflag;
167 expecterr = expect[0];
168
169 fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and "\
170 "oflag = %s\n\n", mode, oflagstr(oflag));
171
172 DD = strbackup("#123456789");
173
174 if (create_10K_test_data_file(filename, mode) ||
175 link_file(filename, "linkfile.txt")) {
176 printf("The scenario initialization failed, "\
177 "and other subassertions won't run.\n\n");
178 exit_test(NOOK);
179 }
180
181 print("open a file on file desc fd1 and a hardlink to it on fd2.\n");
182
183 fd1 = open_file(filename, oflag, mode);
184 fd2 = open_file("linkfile.txt", oflag, mode);
185 if ((fd1 < 0) || (fd2 < 0)) {
186 if (expect[0] == OK) {
187 printf("scenarioA{rest}: open call\n");
188 printf("\t Test OTHER: unexpected open failure\n");
189 ret = NOOK;
190 }
191 print("Scenario A, skipping rest of scenario.\n");
192 goto clean_up;
193 }
194
195 /* initialize pipes and create the child */
196 initialize();
197
198 if (me == PARENT) {
199 /* assertion a) */
200 waitp();
201 assertion("a", "Parent read lock the file using fd2",
202 errtostr(expect[2]));
203 read_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
204 if (errno != OK) {
205 flg |= READ_FAIL;
206 }
207 tresult(expect[2], errno);
208 admerrors(ASSERT);
209 contch();
210 waitp();
211 }
212
213 if (me == CHILD) {
214 contp();
215 waitch();
216
217 /* assertion b) */
218 assertion("b", "Child read lock the file using fd1 & fd2,\n"
219 "then tries write lock using both fd1 & fd2",
220 "multiple");
221 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
222 if (errno != OK) {
223 flg |= READ_FAIL;
224 }
225 tresult(expect[2], errno);
226
227 read_file(fd1, filename, buf, 0, 10);
228 tresult(expect[2], errno);
229 read_file(fd2, "linkfile.txt", buf, 0, 10);
230 tresult(expect[2], errno);
231
232 write_file(fd1, filename, DD, 0, 10);
233 tresult(expect[3], errno);
234 write_file(fd2, "linkfile.txt", DD, 0, 10);
235 tresult(expect[3], errno);
236 admerrors(ASSERT);
237 contp();
238 waitch();
239 }
240
241 if (me == PARENT) {
242 /* assertion c) */
243 expt = expect[5];
244 if ((flg & READ_FAIL) != 0) {
245 expt = (expt == EAGAIN) ? OK : expt;
246 }
247 assertion("c", "Parent tries to write lock first 1 KB using "
248 "both fd1 & fd2", "multiple");
249 write_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
250 tresult(expt, errno);
251 write_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
252 tresult(expt, errno);
253 admerrors(ASSERT);
254 contch();
255 waitp();
256 }
257
258 if (me == CHILD) {
259 /* assertion d) */
260 assertion("d", "Child unlocks first 1 KB using both fd1 & fd2",
261 "multiple");
262 un_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
263 tresult(expect[1], errno);
264 un_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
265 tresult(expect[1], errno);
266 admerrors(ASSERT);
267 contp();
268 waitch();
269 }
270
271 if (me == PARENT) {
272 /* assertion e) */
273 assertion("e", "Parent retries write lock first 1 KB using "
274 "fd1 & fd2", "multiple");
275 write_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
276 tresult(expect[3], errno);
277 write_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
278 tresult(expect[3], errno);
279 admerrors(ASSERT);
280
281 /* assertion f) */
282 assertion("f", "Parent tries to read/write first 10 bytes "
283 "using both fd1 & fd2", "multiple");
284 read_file(fd1, filename, buf, 0, 10);
285 tresult(expect[2], errno);
286 read_file(fd2, "linkfile.txt", buf, 0, 10);
287 tresult(expect[2], errno);
288
289 write_file(fd1, filename, DD, 0, 10);
290 tresult(expect[3], errno);
291 write_file(fd2, "linkfile.txt", DD, 0, 10);
292 tresult(expect[3], errno);
293 admerrors(ASSERT);
294 contch();
295 waitp();
296 }
297
298 if (me == CHILD) {
299 /* assertion g) */
300 expt = expect[4];
301 if (oflag == O_RDONLY) {
302 expt = (expt == EAGAIN) ? OK : expt;
303 }
304 assertion("g", "Child read lock first 1 KB using both "
305 "fd1 & fd2", "multiple");
306 read_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
307 tresult(expt, errno);
308 read_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
309 tresult(expt, errno);
310 admerrors(ASSERT);
311
312 /* assertion h) */
313 assertion("h", "Child tries to write lock first 1 KB using "
314 "both fd1 & fd2", "multiple");
315 write_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
316 tresult(expect[5], errno);
317 write_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
318 tresult(expect[5], errno);
319 admerrors(ASSERT);
320
321 /* assertion i) */
322 expt = expect[5];
323 if ((flg & READ_FAIL) != 0) {
324 expt = (expt == EAGAIN) ? OK : expt;
325 }
326 assertion("i", "Child tries to write lock area from 1 KB + 1 to"
327 "2 KB using both fd1 & fd2", "multiple");
328 write_lock(fd1, MAND_NO, 1024+1, SEEK_SET, 2048);
329 tresult(expt, errno);
330 write_lock(fd2, MAND_NO, 1024+1, SEEK_SET, 2048);
331 tresult(expt, errno);
332 admerrors(ASSERT);
333 contp();
334 waitch();
335 }
336
337 if (me == PARENT) {
338 /* assertion j) */
339 assertion("j", "Parent tries to unlock area from 1 KB + 1 to "
340 "EOF using both fd1 & fd2", "multiple");
341 un_lock(fd1, MAND_NO, 1024+1, SEEK_SET, TO_EOF);
342 tresult(expect[1], errno);
343 un_lock(fd2, MAND_NO, 1024+1, SEEK_SET, TO_EOF);
344 tresult(expect[1], errno);
345 admerrors(ASSERT);
346 contch();
347 waitp();
348 }
349
350 if (me == CHILD) {
351 /* assertion k) */
352 assertion("k", "Child tries to read lock area from 1 KB + 1 to "
353 "2 KB using both fd1 & fd2", "multiple");
354 read_lock(fd1, MAND_NO, 1024+1, SEEK_SET, 2048);
355 tresult(expect[2], errno);
356 read_lock(fd2, MAND_NO, 1024+1, SEEK_SET, 2048);
357 tresult(expect[2], errno);
358 admerrors(ASSERT);
359
360 /* assertion l) */
361 assertion("l", "Child tries to write lock area from 1 KB + 1 "
362 "to 2 KB using both fd1 & fd2", "multiple");
363 write_lock(fd1, MAND_NO, 1024+1, SEEK_SET, 2048);
364 tresult(expect[3], errno);
365 write_lock(fd2, MAND_NO, 1024+1, SEEK_SET, 2048);
366 tresult(expect[3], errno);
367 admerrors(ASSERT);
368 contp();
369 waitch();
370 }
371
372 if (me == PARENT) {
373 /* assertion m) */
374 assertion("m", "Parent tries to read lock first 1 KB using "
375 "both fd1 & fd2", "multiple");
376 read_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
377 tresult(expect[2], errno);
378 read_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
379 tresult(expect[2], errno);
380 admerrors(ASSERT);
381 contch();
382 waitp();
383 }
384
385 if (me == CHILD) {
386 /* assertion n) */
387 assertion("n", "Child tries to write lock the file using "
388 "both fd1 & fd2", "multiple");
389 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
390 tresult(expect[5], errno);
391 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
392 tresult(expect[5], errno);
393 admerrors(ASSERT);
394
395 /* assertion o) */
396 assertion("o", "Child tries to read lock the file using "
397 "both fd1 & fd2", "multiple");
398 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
399 tresult(expect[2], errno);
400 read_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
401 tresult(expect[2], errno);
402 admerrors(ASSERT);
403 contp();
404 waitch();
405 }
406
407 if (me == PARENT) {
408 /* assertion p) */
409 assertion("p", "Parent unlocks the file using fd1 & fd2",
410 "multiple");
411 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
412 tresult(expect[1], errno);
413 un_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
414 tresult(expect[1], errno);
415 admerrors(ASSERT);
416 contch();
417 waitp();
418 }
419
420 if (me == CHILD) {
421 /* assertion q) */
422 assertion("q", "Child tries to write lock the file using both "
423 "fd1 & fd2", "multiple");
424 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
425 tresult(expect[3], errno);
426 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
427 tresult(expect[3], errno);
428 admerrors(ASSERT);
429 contp();
430 wait_send_cresult();
431
432 while (1)
433 sleep(1);
434 }
435
436 if (me == PARENT) {
437 /* assertion r) */
438 assertion("r", "Parent tries to write lock the file using both "
439 "fd1 & fd2,\n\tand kills the child process",
440 "multiple");
441 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
442 tresult(expect[5], errno);
443 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
444 tresult(expect[5], errno);
445 admerrors(ASSERT);
446
447 if (wait_get_cresult())
448 ret = NOOK;
449 kill_child(OK);
450
451 /* assertion s) */
452 assertion("s", "Parent tries to write lock the file using both "
453 "fd1 & fd2,\n\tand closes both files", "multiple");
454 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
455 tresult(expect[3], errno);
456 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
457 tresult(expect[3], errno);
458
459 close_file(fd1, filename);
460 tresult(expect[1], errno);
461 close_file(fd2, "linkfile.txt");
462 tresult(expect[1], errno);
463 admerrors(ASSERT);
464
465 /* assertion t) */
466 assertion("t", "Parent reopens both files and tries to write "
467 "lock both using fd1 & fd2", "multiple");
468 fd1 = open_file(filename, oflag, mode);
469 tresult(expect[0], errno);
470 fd2 = open_file("linkfile.txt", oflag, mode);
471 tresult(expect[0], errno);
472
473 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
474 tresult(expect[3], errno);
475 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
476 tresult(expect[3], errno);
477 admerrors(ASSERT);
478
479 /* assertion u) */
480 assertion("u", "Parent unlocks both files and closes them",
481 "multiple");
482 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
483 tresult(expect[1], errno);
484 un_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
485 tresult(expect[1], errno);
486
487 close_file(fd1, filename);
488 tresult(expect[1], errno);
489 close_file(fd2, "linkfile.txt");
490 tresult(expect[1], errno);
491 admerrors(ASSERT);
492 goto clean_up;
493 }
494
495 if (me == CHILD) {
496 print("ERROR: child should be dead. Quitting ...\n");
497 exit_test(NOOK);
498 }
499
500 clean_up:
501 unlink_file(filename);
502 unlink_file("linkfile.txt");
503
504 ret = admerrors(SCENARIO);
505 print("Scenario A finished.\n\n\n");
506 return (ret);
507 }
508
509 int
510 scenarioB(int mode, int oflag, int expect[])
511 {
512 int fd1, fd2, fd3;
513 char *DD;
514 int flg = 0;
515 int expt;
516 char tmp[512];
517 int ret = OK;
518
519 scen = "ScenB";
520 scen_mode = mode;
521 scen_flag = oflag;
522 expecterr = expect[0];
523
524 fprintf(stdout, "\n\nExecuting Scenario B, with mode = 0%o and "\
525 "oflag = %s\n\n", mode, oflagstr(oflag));
526
527 DD = strbackup("#123456789");
528
529 if (create_10K_test_data_file(filename, mode) ||
530 link_file(filename, "linkfile.txt")) {
531 printf("The scenario initialization failed, "\
532 "and other subassertions won't run.\n\n");
533 exit_test(NOOK);
534 }
535
536 print("open a file on file desc fd1 and a hardlink to it on fd2.\n");
537
538 fd1 = open_file(filename, oflag, mode);
539 fd2 = open_file("linkfile.txt", oflag, mode);
540 if ((fd1 < 0) || (fd2 < 0)) {
541 if (expect[0] == OK) {
542 printf("scenarioB{rest}: open call\n");
543 printf("\t Test OTHER: unexpected open failure\n");
544 ret = NOOK;
545 }
546 print("Scenario B, skipping rest of scenario.\n");
547 goto clean_up;
548 }
549
550 /* initialize pipes and create the child */
551 initialize();
552
553 if (me == PARENT) {
554 /* assertion a) */
555 waitp();
556 assertion("a", "Parent read lock the file using fd2",
557 errtostr(expect[2]));
558 read_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
559 if (errno != OK) {
560 flg |= READ_FAIL;
561 }
562 tresult(expect[2], errno);
563 admerrors(ASSERT);
564 contch();
565 waitp();
566 }
567
568 if (me == CHILD) {
569 /* assertion b) */
570 sprintf(tmp, "Child chages credentials to user %ld and group "
571 "%ld,\n\tthen read lock the file using fd1, and tries"
572 "to read/write first 10 bytes\n\tusing both fd1 & fd2",
573 uid2, gid2);
574 /*
575 * Mark the start of the assertion in debug mode, in a way that
576 * won't interfere with the summary gathering script
577 */
578 dprint("%s_%s_0%o_%s{%s}: %s, expect %s.\n", Testname, scen,
579 scen_mode, oflagstr(scen_flag), "b", tmp, "multiple");
580 if (Seteuid(0) < 0) {
581 print("Scenario B, seteuid(root) failed, skipping"\
582 " rest of scenario ...\n");
583 goto child_end;
584 }
585 if (Setegid(gid2) < 0) {
586 print("Scenario B, setegid(%d) failed, skipping"\
587 "rest of scenario ...\n", gid2);
588 goto child_end;
589 }
590
591 {
592 gid_t gid = gid2;
593
594 if (Setgroups(1, &gid) < 0) {
595 print("Scenario B, setgroups(1, %d) failed, "\
596 "skipping rest of scenario ...\n", gid);
597 goto child_end;
598 }
599
600 }
601 if (Seteuid(uid2) < 0) {
602 print("Scenario B, seteuid(%d) failed, skipping"\
603 " rest of scenario ...\n", uid2);
604 goto child_end;
605 }
606 contp();
607 waitch();
608
609 /* Now the real assertion message */
610 assertion("b", tmp, "multiple");
611
612 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
613 if (errno != OK) {
614 flg |= READ_FAIL;
615 }
616 tresult(expect[2], errno);
617
618 read_file(fd1, filename, buf, 0, 10);
619 tresult(expect[2], errno);
620 read_file(fd2, "linkfile.txt", buf, 0, 10);
621 tresult(expect[2], errno);
622
623 write_file(fd1, filename, DD, 0, 10);
624 tresult(expect[3], errno);
625 write_file(fd2, "linkfile.txt", DD, 0, 10);
626 tresult(expect[3], errno);
627 admerrors(ASSERT);
628 contp();
629 waitch();
630 }
631
632 if (me == PARENT) {
633 /* assertion c) */
634 expt = expect[5];
635 if ((flg & READ_FAIL) != 0) {
636 expt = (expt == EAGAIN) ? OK : expt;
637 }
638 assertion("c", "Parent tries to write lock first 1 KB using "
639 "both fd1 & fd2", "multiple");
640 write_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
641 tresult(expt, errno);
642 write_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
643 tresult(expt, errno);
644 admerrors(ASSERT);
645 contch();
646 waitp();
647 }
648
649 if (me == CHILD) {
650 /* assertion d) */
651 assertion("d", "Child unlock first 1 KB using both fd1 & fd2",
652 "multiple");
653 un_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
654 tresult(expect[1], errno);
655 un_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
656 tresult(expect[1], errno);
657 admerrors(ASSERT);
658 contp();
659 waitch();
660 }
661
662 if (me == PARENT) {
663 /* assertion e) */
664 assertion("e", "Parent retries write lock first 1 KB using "
665 "fd1 & fd2", "multiple");
666 write_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
667 tresult(expect[3], errno);
668 write_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
669 tresult(expect[3], errno);
670 admerrors(ASSERT);
671
672 /* assertion f) */
673 assertion("f", "Parent tries to read/write first 10 bytes "
674 "using both fd1 & fd2", "multiple");
675 read_file(fd1, filename, buf, 0, 10);
676 tresult(expect[2], errno);
677 read_file(fd2, "linkfile.txt", buf, 0, 10);
678 tresult(expect[2], errno);
679
680 write_file(fd1, filename, DD, 0, 10);
681 tresult(expect[3], errno);
682 write_file(fd2, "linkfile.txt", DD, 0, 10);
683 tresult(expect[3], errno);
684 admerrors(ASSERT);
685 contch();
686 waitp();
687 }
688
689 if (me == CHILD) {
690 /* assertion g) */
691 expt = expect[4];
692 if (oflag == O_RDONLY) {
693 expt = (expt == EAGAIN) ? OK : expt;
694 }
695 assertion("g", "Child read lock first 1 KB using both "
696 "fd1 & fd2", "multiple");
697 read_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
698 tresult(expt, errno);
699 read_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
700 tresult(expt, errno);
701 admerrors(ASSERT);
702
703 /* assertion h) */
704 assertion("h", "Child tries to write lock first 1 KB using "
705 "both fd1 & fd2", "multiple");
706 write_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
707 tresult(expect[5], errno);
708 write_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
709 tresult(expect[5], errno);
710 admerrors(ASSERT);
711
712 /* assertion i) */
713 expt = expect[5];
714 if ((flg & READ_FAIL) != 0) {
715 expt = (expt == EAGAIN) ? OK : expt;
716 }
717 assertion("i", "Child tries to write lock area from 1 KB + 1 to"
718 "2 KB using both fd1 & fd2", "multiple");
719 write_lock(fd1, MAND_NO, 1024+1, SEEK_SET, 2048);
720 tresult(expt, errno);
721 write_lock(fd2, MAND_NO, 1024+1, SEEK_SET, 2048);
722 tresult(expt, errno);
723 admerrors(ASSERT);
724 contp();
725 waitch();
726 }
727
728 if (me == PARENT) {
729 /* assertion j) */
730 assertion("j", "Parent tries to unlock area from 1 KB + 1 to "
731 "EOF using both fd1 & fd2", "multiple");
732 un_lock(fd1, MAND_NO, 1024+1, SEEK_SET, TO_EOF);
733 tresult(expect[1], errno);
734 un_lock(fd2, MAND_NO, 1024+1, SEEK_SET, TO_EOF);
735 tresult(expect[1], errno);
736 admerrors(ASSERT);
737 contch();
738 waitp();
739 }
740
741 if (me == CHILD) {
742 /* assertion k) */
743 assertion("k", "Child tries to read lock area from 1 KB + 1 to "
744 "2 KB using both fd1 & fd2", "multiple");
745 read_lock(fd1, MAND_NO, 1024+1, SEEK_SET, 2048);
746 tresult(expect[2], errno);
747 read_lock(fd2, MAND_NO, 1024+1, SEEK_SET, 2048);
748 tresult(expect[2], errno);
749 admerrors(ASSERT);
750
751 /* assertion l) */
752 assertion("l", "Child tries to write lock area from 1 KB + 1 "
753 "to 2 KB using both fd1 & fd2", "multiple");
754 write_lock(fd1, MAND_NO, 1024+1, SEEK_SET, 2048);
755 tresult(expect[3], errno);
756 write_lock(fd2, MAND_NO, 1024+1, SEEK_SET, 2048);
757 tresult(expect[3], errno);
758 admerrors(ASSERT);
759 contp();
760 waitch();
761 }
762
763 if (me == PARENT) {
764 /* assertion m) */
765 assertion("m", "Parent tries to read lock first 1 KB using "
766 "both fd1 & fd2", "multiple");
767 read_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
768 tresult(expect[2], errno);
769 read_lock(fd2, MAND_NO, 0, SEEK_SET, 1024);
770 tresult(expect[2], errno);
771 admerrors(ASSERT);
772 contch();
773 waitp();
774 }
775
776 if (me == CHILD) {
777 /* assertion n) */
778 assertion("n", "Child tries to write lock the file using "
779 "both fd1 & fd2", "multiple");
780 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
781 tresult(expect[5], errno);
782 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
783 tresult(expect[5], errno);
784 admerrors(ASSERT);
785
786 /* assertion o) */
787 assertion("o", "Child tries to read lock the file using "
788 "both fd1 & fd2", "multiple");
789 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
790 tresult(expect[2], errno);
791 read_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
792 tresult(expect[2], errno);
793 admerrors(ASSERT);
794 contp();
795 waitch();
796 }
797
798 if (me == PARENT) {
799 /* assertion p) */
800 assertion("p", "Parent unlocks the file using fd1 & fd2",
801 "multiple");
802 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
803 tresult(expect[1], errno);
804 un_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
805 tresult(expect[1], errno);
806 admerrors(ASSERT);
807 contch();
808 waitp();
809 }
810
811 if (me == CHILD) {
812 /* assertion q) */
813 assertion("q", "Child tries to write lock the file using both "
814 "fd1 & fd2", "multiple");
815 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
816 tresult(expect[3], errno);
817 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
818 tresult(expect[3], errno);
819 admerrors(ASSERT);
820 contp();
821 waitch();
822 }
823
824 if (me == PARENT) {
825 /* assertion r) */
826 assertion("r", "Parent tries to write lock the file using both "
827 "fd1 & fd2", "multiple");
828 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
829 tresult(expect[5], errno);
830 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
831 tresult(expect[5], errno);
832 admerrors(ASSERT);
833 contch();
834 waitp();
835 }
836
837 if (me == CHILD) {
838 /* assertion r1) */
839 assertion("r1", "Child closes both files", "multiple");
840 close_file(fd1, filename);
841 tresult(expect[1], errno);
842 close_file(fd2, "linkfile.txt");
843 tresult(expect[1], errno);
844 admerrors(ASSERT);
845 contp();
846 wait_send_cresult();
847
848 while (1)
849 sleep(1);
850 }
851
852 if (me == PARENT) {
853 /* assertion s) */
854 assertion("s", "Parent tries to write lock the file using both "
855 "fd1 & fd2,\n\tcloses both files and kills the child"
856 " process", "multiple");
857 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
858 tresult(expect[3], errno);
859 write_lock(fd2, MAND_NO, 0, SEEK_SET, TO_EOF);
860 tresult(expect[3], errno);
861
862 close_file(fd1, filename);
863 tresult(expect[1], errno);
864 close_file(fd2, "linkfile.txt");
865 tresult(expect[1], errno);
866 admerrors(ASSERT);
867
868 if (wait_get_cresult())
869 ret = NOOK;
870 kill_child(OK);
871
872 goto clean_up;
873 }
874
875 if (me == CHILD) {
876 print("ERROR: child should be dead. Quitting ...\n");
877 exit_test(NOOK);
878 }
879
880 child_end:
881 contp();
882 wait_send_cresult();
883 while (1)
884 sleep(1);
885
886 clean_up:
887 if (Seteuid(0) < 0) {
888 dprint("Scenario B, seteuid(root) failed\n");
889 }
890 unlink_file(filename);
891 unlink_file("linkfile.txt");
892 unlink_file("testfile2.txt");
893 if (Seteuid(uid) < 0) {
894 dprint("Scenario B, seteuid(%d) failed\n", uid);
895 }
896
897 ret = admerrors(SCENARIO);
898 print("Scenario B finished.\n\n\n");
899 return (ret);
900 }
901
902 int
903 scenarioC(int mode, int oflag, int expect[])
904 {
905 int fd1;
906 int i;
907 char *DD;
908 char tmp[512];
909 int ret = OK;
910
911 scen = "ScenC";
912 scen_mode = mode;
913 scen_flag = oflag;
914 expecterr = expect[0];
915
916 fprintf(stdout, "\n\nExecuting Scenario C, with mode = 0%o and "\
917 "oflag = %s\n\n", mode, oflagstr(oflag));
918
919 DD = strbackup("#123456789");
920
921 if (create_10K_test_data_file(filename, mode)) {
922 printf("The scenario initialization failed, "\
923 "and other subassertions won't run.\n\n");
924 exit_test(NOOK);
925 }
926
927 print("open a file on file desc fd.\n");
928
929 fd1 = open_file(filename, oflag, mode);
930 if (fd1 < 0) {
931 if (expect[0] == OK) {
932 printf("scenarioC{rest}: open call\n");
933 printf("\t Test OTHER: unexpected open failure\n");
934 ret = NOOK;
935 }
936 print("Scenario C, skipping rest of scenario.\n");
937 goto clean_up;
938 }
939
940 /* initialize pipes and create the child */
941 initialize();
942
943 if (me == PARENT) {
944 sleep(1); /* let child start */
945 contch();
946 waitp();
947 }
948
949 if (me == CHILD) {
950 waitch();
951 contp();
952 /* assertion a) */
953 sprintf(tmp, "Child read lock and unlock the file %d times"
954 "concurrently with next assertion",
955 N);
956 /*
957 * Mark the start of the assertion in debug mode, in a way that
958 * won't interfere with the summary gathering script
959 */
960 dprint("%s_%s_0%o_%s{%s}: %s, expect %s.\n", Testname, scen,
961 scen_mode, oflagstr(scen_flag), "a", tmp, "multiple");
962 for (i = 0; i < N; i++) {
963 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
964 tresult(expect[2], errno);
965 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
966 tresult(expect[1], errno);
967 }
968 /* now the real assertion message */
969 assertion("a", tmp, "multiple");
970 admerrors(ASSERT);
971 /* print parent assertion message and result */
972 contp();
973 waitch();
974 /* now continue with next assertion */
975 contp();
976 waitch();
977 }
978
979 if (me == PARENT) {
980 /* assertion b) */
981 sprintf(tmp, "Parent closes and reopens the file %d times, "
982 "then\n\tread locks the file", N);
983
984 /*
985 * Mark the start of the assertion in debug mode, in a way that
986 * won't interfere with the summary gathering script
987 */
988 dprint("%s_%s_0%o_%s{%s}: %s, expect %s.\n", Testname, scen,
989 scen_mode, oflagstr(scen_flag), "b", tmp, "multiple");
990 for (i = 0; i < N; i++) {
991 close_file(fd1, filename);
992 tresult(expect[1], errno);
993 fd1 = open_file(filename, oflag, mode);
994 tresult(expect[0], errno);
995 }
996 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
997 tresult(expect[2], errno);
998 /* wait for previous assertion to be printed */
999 waitp();
1000 /* Now print the real assertion message */
1001 assertion("b", tmp, "multiple");
1002 admerrors(ASSERT);
1003
1004 contch();
1005 waitp();
1006
1007 /* assertion c) */
1008 assertion("c", "Parent write locks the file",
1009 errtostr(expect[3]));
1010 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1011 tresult(expect[3], errno);
1012 admerrors(ASSERT);
1013 contch();
1014 waitp();
1015 }
1016
1017 if (me == CHILD) {
1018 /* assertion d) */
1019 assertion("d", "Child read locks the file",
1020 errtostr(expect[4]));
1021 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1022 tresult(expect[4], errno);
1023 admerrors(ASSERT);
1024 contp();
1025 waitch();
1026 }
1027
1028 if (me == PARENT) {
1029 /* assertion e) */
1030 sprintf(tmp, "Parent read locks the file, then unlocks and "
1031 "read locks it for %d times", N);
1032 assertion("e", tmp, "multiple");
1033 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1034 tresult(expect[2], errno);
1035 for (i = 0; i < N; i++) {
1036 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1037 tresult(expect[1], errno);
1038 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1039 tresult(expect[2], errno);
1040 }
1041 admerrors(ASSERT);
1042 contch();
1043 waitp();
1044 }
1045
1046 if (me == CHILD) {
1047 /* assertion f) */
1048 sprintf(tmp, "Child read locks the file, then unlocks and "
1049 "read locks it for %d times", N);
1050 assertion("f", tmp, "multiple");
1051 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1052 tresult(expect[2], errno);
1053 for (i = 0; i < N; i++) {
1054 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1055 tresult(expect[1], errno);
1056 read_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1057 tresult(expect[2], errno);
1058 }
1059 admerrors(ASSERT);
1060 contp();
1061 waitch();
1062 }
1063
1064 if (me == PARENT) {
1065 /* assertion g) */
1066 assertion("g", "Parent unlocks the file", errtostr(expect[1]));
1067 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1068 tresult(expect[1], errno);
1069 admerrors(ASSERT);
1070 contch();
1071 waitp();
1072 }
1073
1074 if (me == CHILD) {
1075 /* assertion h) */
1076 sprintf(tmp, "Child write locks the file and waits for the "
1077 "lease period (%d + 2 seconds) to expire", renew);
1078 assertion("h", tmp, errtostr(expect[3]));
1079 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1080 tresult(expect[3], errno);
1081 admerrors(ASSERT);
1082 contp();
1083
1084 sleep(renew + 2);
1085 }
1086
1087 if (me == PARENT) {
1088 /* assertion i) */
1089 assertion("i", "Parent read locks first 1 KB",
1090 errtostr(expect[4]));
1091 read_lock(fd1, MAND_NO, 0, SEEK_SET, 1024);
1092 tresult(expect[4], errno);
1093 admerrors(ASSERT);
1094 waitp();
1095 }
1096
1097 if (me == CHILD) {
1098 contp();
1099 waitch();
1100 }
1101
1102 if (me == PARENT) {
1103 /* assertion j) */
1104 assertion("j", "Parent unlocks the file", errtostr(expect[1]));
1105 un_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1106 tresult(expect[1], errno);
1107 admerrors(ASSERT);
1108 contch();
1109 waitp();
1110 }
1111
1112 if (me == CHILD) {
1113 /* assertion k) */
1114 assertion("k", "Child write locks the file",
1115 errtostr(expect[3]));
1116 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1117 tresult(expect[3], errno);
1118 admerrors(ASSERT);
1119 contp();
1120 wait_send_cresult();
1121
1122 while (1)
1123 sleep(1);
1124 }
1125
1126 if (me == PARENT) {
1127 if (wait_get_cresult())
1128 ret = NOOK;
1129 kill_child(OK);
1130
1131 /* assertion l) */
1132 assertion("l", "Parent kills the child process and write locks"
1133 " the file", errtostr(expect[3]));
1134 write_lock(fd1, MAND_NO, 0, SEEK_SET, TO_EOF);
1135 tresult(expect[3], errno);
1136 admerrors(ASSERT);
1137 goto clean_up;
1138 }
1139
1140 if (me == CHILD) {
1141 print("ERROR: child should be dead. Quitting ...\n");
1142 exit_test(NOOK);
1143 }
1144
1145
1146 clean_up:
1147 close_file(fd1, filename);
1148 unlink_file(filename);
1149 ret = admerrors(SCENARIO);
1150
1151 print("Scenario C finished.\n\n\n");
1152 return (ret);
1153 }