1 /*
2 *
3 * Copyright (c) 2003 The Regents of the University of California. All
4 * rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * - Neither the name of the University nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31
32 /*
33 *
34 * openrace.c: A test program as part of FUSD.
35 *
36 * This regression test program tries to exercise the FUSD race
37 * condition between a device provider closing (and unregistering a
38 * device), and clients trying to open that device.
39 *
40 * It should run for less than 30 seconds, then exit, saying ALL TESTS
41 * PASSED. If it freezes, or processes get stuck in the D state, or
42 * you end up with zombie devices (in /dev/fusd/status), then there is
43 * a problem.
44 *
45 * $Id: openrace.c,v 1.5 2004-04-28 18:40:07 girod Exp $
46 */
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <fcntl.h>
52 #include <errno.h>
53 #include <sys/wait.h>
54 #include <signal.h>
55 #include <string.h>
56
57 #include "fusd.h"
58
59 #define DEVNAME "/dev/testfusd/openrace"
60
61 #define ITERATIONS 1
62
63 #define FORK \
64 tmp = fork(); \
65 if (tmp < 0) { perror("can't fork"); exit(1); } \
66 if (tmp == 0)
67
68 int n;
69
70 void done(int signo)
71 {
72 static int num_done = 0;
73 int status;
74 pid_t pid;
75
76 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
77 printf("pid [%d] done\n", pid);
78 num_done++;
79 }
80
81 /* if all N clients, plus the server, are done... we're done */
82 if (num_done == n+1) {
83 printf("test complete\n");
84 exit(0);
85 }
86 }
87
88
89 int main(int argc, char *argv[])
90 {
91 int tmp, i;
92
93 if (argc != 2 || (n = atoi(argv[1])) <= 0) {
94 fprintf(stderr, "usage: %s <number-of-clients> (use at least 10 or 20)\n", argv[0]);
95 exit(0);
96 }
97
98 printf("master is pid %d\n", getpid());
99 signal(SIGCHLD, done);
100
101 /* fork server */
102 FORK {
103 fusd_file_operations_t fops = { };
104 int fd;
105
106 if ((fd = fusd_register(DEVNAME, 0666, 0, &fops)) < 0) {
107 perror("Register failed");
108 exit(1);
109 }
110 printf("register succeeded, trying to unregister...\n");
111 fusd_unregister(fd);
112 printf("now unregistered\n");
113 exit(0);
114 }
115
116 sleep(3);
117
118 for (i = 0; i < n; i++) {
119 FORK {
120 int j;
121 int enomem=0, enoent=0, epipe=0, eother=0;
122
123 printf("launched client %d, pid %d\n", i, getpid());
124
125 for (j = 0; j < ITERATIONS; j++) {
126 printf("[%d] trying to open\n", getpid());
127 open(DEVNAME, O_RDWR);
128
129 switch (errno) {
130 case ENOMEM:
131 enomem++;
132 break;
133 case ENOENT:
134 enoent++;
135 break;
136 case EPIPE:
137 epipe++;
138 break;
139 default:
140 eother++;
141 printf("[%d] got strange retval %d (%m)\n", getpid(), errno);
142 break;
143 }
144 }
145
146 printf("[%d] done; %d nomem, %d noent, %d pipe, %d other\n", getpid(),
147 enomem, enoent, epipe, eother);
148 exit(0);
149 }
150 }
151
152 /* parent: wait for children to all exit */
153 while (1)
154 pause();
155 }
156
157
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.