~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
cvs/emstar/fusd/test/torturetest.c


  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   torturetest.c
 35 
 36   tests device creation and open, to test for memory leaks and locking
 37   problems
 38 
 39  */
 40 
 41 #include <stdio.h>
 42 #include <stdlib.h>
 43 #include <unistd.h>
 44 #include <fcntl.h>
 45 #include <errno.h>
 46 #include <string.h>
 47 #include <sys/time.h>
 48 #include <sys/wait.h>
 49 #include <signal.h>
 50 
 51 #include "fusd.h"
 52 
 53 /* open call fails every 100th time. */
 54 int _open(struct fusd_file_info *file)
 55 {
 56   static int counter = 0;
 57   if (counter++ % 100) return 0;
 58   return -81;
 59 }
 60 
 61 
 62 int _close(struct fusd_file_info *file)
 63 {
 64   return 0;
 65 }
 66 
 67 
 68 #define HANDLEERROR(fd) \
 69 if (((fd) < 0) && (errno != 81)) \
 70 {fprintf(stderr, "%s: open error: %s\n", name, strerror(errno));exit(1);}
 71 
 72 #define CLOSE(fd) \
 73 if ((fd) >= 0) \
 74 if (close(fd)<0) \
 75 {fprintf(stderr, "%s: close error: %s\n", name, strerror(errno));exit(1);}
 76 
 77 int main(int argc, char *argv[])
 78 {
 79   int i, j;
 80   int num;
 81   int retval;
 82   char **devs;
 83   pid_t *pids;
 84 
 85   // init function table
 86   fusd_file_operations_t
 87     fops = {_open, 
 88             _close,
 89             NULL,
 90             NULL,
 91             NULL,
 92             NULL,
 93             NULL};
 94 
 95   if (argc != 2) {
 96     fprintf(stderr, "usage: %s <number-devices-to-create>\n", argv[0]);
 97     exit(0);
 98   }
 99 
100   num = atoi(argv[1]);
101 
102   devs = (char**)malloc(sizeof(char *)*num);
103   pids = (pid_t *)malloc(sizeof(pid_t)*num);
104 
105 
106   // create device names
107   for (i=0; i<num; i++) {
108     char dev[30];
109     sprintf(dev,"/dev/fusd-test/test%d",i);
110     devs[i] = strdup(dev);
111   }
112 
113   /* create devices; 2 devices handled per process */
114   for (i=0; i<num; i+=2) {
115     int fork2 = fork();
116 
117     if (fork2 == 0) {
118 
119       if (fusd_register(devs[i], 0666, 0, &fops) < 0) {
120         perror("Register failed");
121         exit(1);
122       } else {
123         printf("pid %d: serving %s\n", getpid(), devs[i]);
124       }
125 
126       i++;
127 
128       if (i < num) {
129         if (fusd_register(devs[i], 0666, 0, &fops) < 0) {
130           perror("Register failed");
131           exit(1);
132         } else {
133           printf("pid %d: serving %s\n", getpid(), devs[i]);
134         }
135       }
136       
137       /* run the devices */
138       fusd_run();
139     }
140     
141   }
142 
143 
144   /* clients */
145   for (i=0; i<num; i++) {
146     int fork2 = fork();
147 
148     if (fork2 > 0) {
149       pids[i] = fork2;
150     } else if (fork2 == 0) {
151       int fd, *fds;
152       struct timeval tv;
153       char name[50];
154 
155 
156       if ((fds = (int*)malloc(sizeof(int)*num)) == NULL) {
157         fprintf(stderr, "malloc failure");
158         exit(1);
159       }
160 
161       //      sleep((1+num/10) * (2+i/5));
162       sleep(10);
163       printf("pid %d: client starting...\n", getpid());
164       sprintf(name, "client (pid %d)", getpid());
165       
166       // randomize
167       gettimeofday(&tv, NULL);
168       srandom(tv.tv_usec);
169       for (i=0; i<num*5; i++) {
170         int j = random() % num;
171         char *tmp = devs[j];
172         devs[j] = devs[0];
173         devs[0] = tmp;
174       }
175       
176       
177       for (j=0; j<num; j++) {
178         printf("loop (%d) %d\n", getpid(), j);
179         
180         /* open and close each device */
181         for (i=0; i<num; i++) {
182           //printf("opening %s\n", sdevs[i]);
183           fd = open(devs[i], O_RDWR);
184           HANDLEERROR(fd);
185           CLOSE(fd);
186           if (random() % 2) usleep(20000);
187         }      
188         
189         /* open random device num x */
190         for (i=0; i<num; i++) {
191           fds[i] = open(devs[0], O_RDWR);
192           HANDLEERROR(fds[i]);
193           if (random() % 2) usleep(20000);
194         }      
195         
196         /* CLOSE that device, open a new one */
197         for (i=0; i<num; i++) {
198           CLOSE(fds[i]);
199           fds[i] = open(devs[i], O_RDWR);
200           HANDLEERROR(fds[i]);
201           if (random() % 2) usleep(20000);
202         }      
203         
204         /* open and close each device */
205         for (i=num-1; i>=0; i--) {
206           fd = open(devs[i], O_RDWR);
207           HANDLEERROR(fd);
208           CLOSE(fd);
209           CLOSE(fds[i]);
210           if (random() % 2) usleep(20000);
211         }      
212         
213       }
214       
215       // leave some stuff open..
216       /* open random device num x */
217       for (i=0; i<num; i++) {
218         fd = open(devs[i], O_RDWR);
219         HANDLEERROR(fd);
220         fd = open(devs[0], O_RDWR);
221         HANDLEERROR(fd);
222       }      
223       
224       printf("done (%d) well, we finished..\n", getpid());
225       exit(0);
226     }
227     
228   }
229 
230   /* now wait for all the clients to finish */
231   retval = 1;
232 
233   for (;;) {
234     int pid, status;
235     int i, j;
236 
237     for (i = 0; i < num; i++) {
238       pid = wait(&status);
239 
240       for (j = 0; j < num; j++) {
241         if (pids[j] == pid) {
242           pids[j] = -1;
243           fprintf(stderr, "master: pid %d finished\n", pid);
244           break;
245         }
246       }
247 
248       if (j >= num) {
249         fprintf(stderr, "master: nonclient pid %d exited\n", pid);
250         goto done;
251       }
252 
253       if (WEXITSTATUS(status)) {
254         fprintf(stderr, "master: uh oh, client %d reported retval %d\n",
255                 pid, WEXITSTATUS(status));
256         goto done;
257       }
258 
259     }
260 
261     fprintf(stderr, "master: all clients exited successfully\n");
262     retval = 0;
263     goto done;
264   }
265 
266  done:
267   signal(SIGINT, SIG_IGN);
268   kill(0, SIGINT);
269   exit(retval);
270 }
271 
272 
273 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.