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 /*
28 * This proram is used by open_downgrade.ksh script to generate a scenario
29 * where OPEN_DOWNGRADE operation is performed on a stale file handler.
30 *
31 * In the comments on 6282664, Eric suggested a way to generate the scenario:
32 *
33 * 1) client# mount server:/expor
34 * 2) client# fd1 = open(file, RD_ONLY)
35 * 3) client# fd2 = open(file, WR_ONLY)
36 * 4) server# rm /export/file
37 * 5) server# unshare /export
38 * 6) server# share /export
39 * 7) client# close(fd1)
40 *
41 * This program does step 2, 3, and 7. open_downgrade.ksh does step 1, 4, 5,
42 * and 6.
43 */
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <fcntl.h>
50 #include <signal.h>
51 #include <unistd.h>
52 #include <errno.h>
53
54 int fd1, fd2;
55
56 void
57 handler(int sig)
58 {
59 switch (sig) {
60 case SIGUSR1:
61 /* close fd1 */
62 if (close(fd1) < 0 && errno == ESTALE) {
63 printf("Received NFS4ERR_STALE on close(fd1)\n");
64 fflush(stdout);
65 }
66 fd1 = 0;
67
68 break;
69 case SIGUSR2:
70 /* close fd2 */
71 if (close(fd2) < 0 && errno == ESTALE) {
72 printf("Received NFS4ERR_STALE on close(fd2)\n");
73 fflush(stdout);
74 }
75 fd2 = 0;
76
77 break;
78 default:
79 /* shouldn't be reached */
80 exit(1);
81 }
82 }
83
84 int
85 main(int argc, char **argv)
86 {
87 if (argc != 2) {
88 printf("Usage: %s <filename>\n", argv[0]);
89 exit(1);
90 }
91
92 (void) signal(SIGUSR1, handler);
93 (void) signal(SIGUSR2, handler);
94
95 /* open file with O_RDONLY */
96 fd1 = open(argv[1], O_RDONLY);
97
98 if (fd1 < 0) {
99 perror("open(file, O_RDONLY)");
100 exit(1);
101 }
102
103 /* open the same file with O_WRONLY */
104 fd2 = open(argv[1], O_WRONLY);
105
106 if (fd2 < 0) {
107 perror("open(file, O_WRONLY)");
108 exit(1);
109 }
110
111 printf("fd1 and fd2 were opened.\n");
112 fflush(stdout);
113
114 /* sleep until further notification */
115 while (fd1 != 0 || fd2 != 0) {
116 pause();
117 }
118
119 return (errno);
120 }