Add proper per-file copyright notices/licenses and top-level license.
[bluesky.git] / TBBT / trace_play / sfs_m_snc.c
1 #ifndef lint
2 static char sccsid[] = "@(#)sfs_m_snc.c 2.1     97/10/23";
3 #endif
4
5 /*
6  *   Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
7  *      All rights reserved.
8  *              Standard Performance Evaluation Corporation (SPEC)
9  *              6585 Merchant Place, Suite 100
10  *              Warrenton, VA 20187
11  *
12  *      This product contains benchmarks acquired from several sources who
13  *      understand and agree with SPEC's goal of creating fair and objective
14  *      benchmarks to measure computer performance.
15  *
16  *      This copyright notice is placed here only to protect SPEC in the
17  *      event the source is misused in any manner that is contrary to the
18  *      spirit, the goals and the intent of SPEC.
19  *
20  *      The source code is provided to the user or company under the license
21  *      agreement for the SPEC Benchmark Suite for this product.
22  */
23
24 /*****************************************************************
25  *                                                               *
26  *      Copyright 1991,1992  Legato Systems, Inc.                *
27  *      Copyright 1991,1992  Auspex Systems, Inc.                *
28  *      Copyright 1991,1992  Data General Corporation            *
29  *      Copyright 1991,1992  Digital Equipment Corporation       *
30  *      Copyright 1991,1992  Interphase Corporation              *
31  *      Copyright 1991,1992  Sun Microsystems, Inc.              *
32  *                                                               *
33  *****************************************************************/
34
35 /*
36  *.Exported_routines
37  *     None.
38  *
39  *.Local_routines
40  *     void sfs_syncprog_1(struct svc_req *, SVCXPRT *)
41  *     int * signal_sync_sfs_1(struct sync_string *)
42  *     void lad_syncd_cleanup(int)
43  *
44  *.Revision_history
45  *      04-Dec-91       Keith   Include sfs_def.h for SYSV/SVR4 mem*
46  *                              functions. Include string.h for SYSV/SVR4.
47  *      28-Nov-91       Teeluckingh     Fixed 'multiple signals to sfs'
48  *                              problem.  Uses a 'transaction id' field in
49  *                              the sync rpc xdr structure to compare
50  *                              previous rpc, if the current transaction id
51  *                              matches the previous one then sfs_syncd
52  *                              just return 'success' to the client. If the
53  *                              transaction ids do not match, the actions
54  *                              are performed and the transaction id value
55  *                              is saved.
56  *      17-Jun-91       Teelucksingh    Creation - multi-client
57  *                              synchronization server sfs_syncd.
58  *                              Processes the sfs sync rpcs between systems.
59  */
60
61
62 /*
63  * -------------------------  Include Files  -------------------------
64  */
65
66 /*
67  * ANSI C headers
68  */
69 #include <stdio.h>
70 #include <stdlib.h>
71 #include <unistd.h>
72 #include <string.h>
73 #include <errno.h>
74 #include <signal.h>
75  
76 #include <sys/types.h>
77 #include <sys/stat.h> 
78
79 #include <sys/signal.h>
80 #include <sys/file.h>
81
82 #include "sfs_c_def.h"
83 #include "sfs_m_def.h"
84
85
86 /*
87  * -----------------------  External Definitions  -----------------------
88  */
89
90 /* forward definitions for local routines */
91 static void sfs_syncprog_1(struct svc_req *, SVCXPRT *);
92 static int * signal_sync_sfs_1(struct sync_string *);
93 static void lad_syncd_cleanup(int);
94
95 /*
96  * -----------------------  Static Definitions  -----------------------
97  */
98
99 int Debug_level = 0;            /* flag indicates prime client debug mode */
100 char *sfs_Myname;                   /* program name */
101
102 static char previous_transaction[MAX_STR1_LEN]; /* to hold transaction id */
103
104
105 /*
106  * -------------------  Multi-client Synchronization  -------------------
107  */
108
109
110 /*ARGSUSED*/
111 int
112 main(
113     int         argc,
114     char *      argv[])
115 {
116     char        *nameptr;
117     SVCXPRT *   transp;
118     FILE        *pid_fp;
119 #if (defined(_XOPEN_SOURCE) || defined(USE_POSIX_SIGNALS))
120     struct sigaction sig_act, old_sig_act;
121 #endif /* USE_POSIX_SIGNALS */
122
123     /* 
124      * Place pid in pid log file 
125      */   
126     if ((pid_fp = fopen(SFS_SYNCD_PID, "a+")) == NULL) { 
127         perror(SFS_SYNCD_PID);  
128         (void) unlink(SFS_SYNCD_PID); 
129         exit(1); 
130     } 
131     (void) fprintf(pid_fp, "%d\n", getpid()); 
132     (void) fclose(pid_fp);
133
134     sfs_Myname = argv[0];
135
136     if ((nameptr = strrchr(argv[0], '/')) != NULL)
137         sfs_Myname = ++nameptr;
138
139 #if (defined(_XOPEN_SOURCE) || defined(USE_POSIX_SIGNALS))
140     /* use XOPEN signal handling */
141     sig_act.sa_handler = generic_catcher;
142     (void)sigemptyset(&sig_act.sa_mask);
143     sig_act.sa_flags = 0;
144
145     /* signals handlers for signals used by sfs_prime */
146     sig_act.sa_handler = lad_syncd_cleanup;
147     if (sigaction(SIGINT,&sig_act,&old_sig_act) != 0) {
148                 perror("sigaction failed: SIGINT");
149                 (void) unlink(SFS_SYNCD_PID); 
150                 exit(4);
151     }
152 #else
153     /* set up SIGINT signal handler */
154     (void) signal(SIGINT, lad_syncd_cleanup);
155 #endif /* USE_POSIX_SIGNALS */
156
157     (void) fprintf(stderr,"--------------------\n");
158     (void) fprintf(stderr,"Start of sfs run.\n");
159
160     (void) pmap_unset(SFS_SYNCPROG, SFS_SYNCVERS);
161
162     transp = svcudp_create(RPC_ANYSOCK);
163     if (transp == ((SVCXPRT *) NULL)) {
164         (void) fprintf(stderr, "%s: cannot create udp service.\n", sfs_Myname);
165         (void) unlink(SFS_SYNCD_PID); 
166         exit(5);
167     }
168     if (!svc_register(transp, SFS_SYNCPROG, SFS_SYNCVERS,
169                      sfs_syncprog_1, IPPROTO_UDP)) {
170         (void) fprintf(stderr,
171             "%s: unable to register (SFS_SYNCPROG,SFS_SYNCVERS, udp).\n",
172             sfs_Myname);
173         (void) unlink(SFS_SYNCD_PID); 
174         exit(6);
175     }
176
177     transp = svctcp_create(RPC_ANYSOCK, 0, 0);
178     if (transp == ((SVCXPRT *) NULL)) {
179         (void) fprintf(stderr, "%s: cannot create tcp service.\n", sfs_Myname);
180         (void) unlink(SFS_SYNCD_PID); 
181         exit(6);
182     }
183     if (!svc_register(transp, SFS_SYNCPROG, SFS_SYNCVERS,
184                       sfs_syncprog_1, IPPROTO_TCP)) {
185         (void) fprintf(stderr,
186             "%s: unable to register (SFS_SYNCPROG, SFS_SYNCVERS, tcp).\n",
187             sfs_Myname);
188         (void) unlink(SFS_SYNCD_PID); 
189         exit(7);
190     }
191
192     svc_run();
193     (void) fprintf(stderr, "%s: svc_run returned\n", sfs_Myname);
194     return(1);
195
196 } /* main */
197
198
199 static void
200 sfs_syncprog_1(
201     struct svc_req *    rqstp,
202     SVCXPRT *           transp)
203 {
204     union {
205         sync_string     signal_sync_sfs_1_arg;
206     } argument;
207     char *              result;
208     bool_t              (*xdr_argument)(), (*xdr_result)();
209     char *              (*local)();
210
211     switch (rqstp->rq_proc) {
212         case SIGNAL_NULLPROC:
213             (void) svc_sendreply(transp, xdr_void, (char *)NULL);
214             return;
215
216         case SIGNAL_SFS:
217             xdr_argument = xdr_sync_string;
218             xdr_result = xdr_int;
219             local = (char * (*)()) signal_sync_sfs_1;
220             break;
221
222         default:
223             svcerr_noproc(transp);
224             return;
225     }
226     (void) memset((char *) &argument, '\0', sizeof(argument));
227     if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
228         svcerr_decode(transp);
229         return;
230     }
231     result = (*local)(&argument);
232     if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
233         svcerr_systemerr(transp);
234     }
235     if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
236         (void) fprintf(stderr, "%s: unable to free arguments\n", sfs_Myname);
237         (void) unlink(SFS_SYNCD_PID); 
238         exit(8);
239     }
240
241 } /* sfs_syncprog_1 */
242
243
244 /*
245  * signal_sync_sfs_1 - multi-client synch RPC
246  * Provides interface between sfs program running
247  * on multiple clients and the controlling sfs_prime program.
248  */
249 static int *
250 signal_sync_sfs_1(
251     struct sync_string *        sfs_signal)
252 {
253     static int                  result = 0 ;    /* return status - failure */
254     FILE *                      fp;
255     int                         sfs_pid;        /* sfs parent process pid */
256     char                        datafile[SFS_MAXPATHLEN]; /* results file */
257     char                        CL_Logname[SFS_MAXPATHLEN];
258
259     result = 0;
260     /* if a duplicate transactions then just return success to calling client */
261     if (strcmp(sfs_signal->clnt_transaction, previous_transaction) == 0) {
262         (void) fprintf(stderr,"%s: Got a duplicate signal - %s\n",
263                         sfs_Myname, sfs_signal->clnt_transaction);
264         result = 1;
265         return(&result);
266     }
267
268     if (strcmp(sfs_signal->clnt_type,"CLIENT_SIGNAL") == 0) {
269
270         /*
271          * message from parent sfs process on client to Prime-client
272          * (sfs_prime).
273          *
274          * Append client id to Prime client sync logfile
275          */
276         fp = fopen(SFS_PRIME_SYNC_LOG, "a");
277         if (fp == NULL) {
278             (void) fprintf(stderr,"%s: Cannot open %s\n",
279                 sfs_Myname, SFS_PRIME_SYNC_LOG);
280             return (&result);
281         }
282         (void) fwrite((char *)&sfs_signal->clnt_id,
283                         sizeof(sfs_signal->clnt_id), 1, fp);
284         (void) fclose(fp);
285         result = 1;
286         (void) sprintf(previous_transaction, sfs_signal->clnt_transaction);
287         (void) fprintf(stderr,"%s: Got Client_SIGNAL - %s\n",
288                         sfs_Myname, sfs_signal->clnt_transaction);
289         return (&result); /* success */
290
291     } else if (strcmp(sfs_signal->clnt_type,"CLIENT_DATA") == 0) {
292
293         /*
294          * message from parent sfs process on client to Prime-client
295          * completed run, here are my results. Write it to file and let
296          * Prime client know about it.
297          */
298         (void) sprintf(datafile,"%s%d",
299                         PRIME_RESULTS_LOG, sfs_signal->clnt_id);
300         fp = fopen(datafile, "w");
301         if (fp == NULL) {
302             (void) fprintf(stderr,"%s: Cannot open %s\n",
303                 sfs_Myname, datafile);
304             return (&result);
305         }
306         (void) fprintf(fp,"%s",sfs_signal->clnt_data);
307         (void) fclose(fp);
308
309         /* after writing data write client id to sync log */
310         fp = fopen(SFS_PRIME_SYNC_LOG, "a");
311         if (fp == NULL) {
312             (void) fprintf(stderr,"%s: Cannot open %s\n",
313                 sfs_Myname, SFS_PRIME_SYNC_LOG);
314             return (&result);
315         }
316         (void) fwrite((char *)&sfs_signal->clnt_id,
317                                 sizeof(sfs_signal->clnt_id), 1, fp);
318         (void) fclose(fp);
319
320         /* let the remote process know success */
321         result = 1;
322         (void) sprintf(previous_transaction, sfs_signal->clnt_transaction);
323         (void) fprintf(stderr,"%s: Got Client_DATA - %s\n",
324                         sfs_Myname, sfs_signal->clnt_transaction);
325         return (&result);
326
327     } else if (strcmp(sfs_signal->clnt_type,"CLIENT_STOP") == 0) {
328
329         /*
330          * message from parent sfs process on client to Prime-client
331          * (sfs_prime) to stop due to error.
332          */
333         fp = fopen(SFS_PRIME_SYNC_LOG, "a");
334         if (fp == NULL) {
335             (void) fprintf(stderr,"%s: Cannot open %s\n",
336                 sfs_Myname, SFS_PRIME_SYNC_LOG);
337             return (&result);
338         }
339         /*
340          * Write out client id 1000 times to fool prime into thinking
341          * all clients have responded and will get an error when it
342          * tries to communicate to it.
343          */
344         for (result = 0; result < 1000; result++)
345                 (void) fwrite((char *)&sfs_signal->clnt_id,
346                         sizeof(sfs_signal->clnt_id), 1, fp);
347         (void) fclose(fp);
348         result = 1;
349         (void) sprintf(previous_transaction, sfs_signal->clnt_transaction);
350         (void) fprintf(stderr,"%s: Got Client_STOP - %s\n",
351                         sfs_Myname, sfs_signal->clnt_transaction);
352         return (&result); /* success */
353
354     } else if (strcmp(sfs_signal->clnt_type,"PRIME_SIGNAL") == 0) {
355
356         /*
357          * message from the Prime client (sfs_prime)
358          * send SIGUSR1 signal to parent sfs process on
359          * client - signals it to proceed
360          */
361         (void) sprintf(CL_Logname,"%s%d",
362                         SFS_CLIENT_SYNC_LOG, sfs_signal->clnt_id);
363         fp = fopen(CL_Logname, "r");
364         if (fp == NULL) {
365             (void) fprintf(stderr,"%s: Cannot open %s\n",
366                 sfs_Myname, CL_Logname);
367             return(&result);
368         }
369         if (fscanf(fp,"%d",&sfs_pid) != 1)
370             return (&result);
371         if ((int) generic_kill(sfs_pid, SIGUSR1) == 0) {
372             result = 1;
373             (void) sprintf(previous_transaction,
374                            sfs_signal->clnt_transaction);
375             (void) fprintf(stderr,"%s: Got PRIME_SIGNAL(SIGUSR1) - %s\n",
376                             sfs_Myname, sfs_signal->clnt_transaction);
377             (void) fprintf(stderr,"   Sent SIGUSR1\n");
378             return (&result); /* success */
379         } else
380             return (&result);
381
382     } else if (strcmp(sfs_signal->clnt_type,"PRIME_ALARM") == 0) {
383
384         /*
385          * message from the Prime client (sfs_prime)
386          * send SIGALRM signal to parent sfs process on
387          * client - tell it to wake up and finish execution at this time
388          */
389
390         (void) sprintf(CL_Logname,"%s%d",
391                         SFS_CLIENT_SYNC_LOG, sfs_signal->clnt_id);
392         fp = fopen(CL_Logname, "r");
393         if (fp == NULL) {
394             (void) fprintf(stderr,"%s: Cannot open %s\n",
395                 sfs_Myname, CL_Logname);
396             return (&result);
397         }
398         if (fscanf(fp,"%d",&sfs_pid) != 1)
399             return (&result);
400         if ((int) generic_kill(sfs_pid, SIGALRM) == 0) {
401             result = 1;
402             (void) sprintf(previous_transaction,
403                            sfs_signal->clnt_transaction);
404             (void) fprintf(stderr,"%s: Got PRIME_ALARM(SIGALRM) - %s\n",
405                                 sfs_Myname, sfs_signal->clnt_transaction);
406             (void) fprintf(stderr,"   Sent SIGALRM\n");
407             return (&result); /* success */
408         } else
409             return (&result);
410
411     } else if (strcmp(sfs_signal->clnt_type,"PRIME_STOP") == 0) {
412
413         /*
414          * message from Prime-client
415          * sent SIGINT signal to sfs parent process
416          * to tell it to terminate experiment now
417          */
418         (void) sprintf(CL_Logname,"%s%d",
419                         SFS_CLIENT_SYNC_LOG, sfs_signal->clnt_id);
420         fp = fopen(CL_Logname, "r");
421         if (fp == NULL) {
422             (void) fprintf(stderr,"%s: Cannot open %s\n",
423                 sfs_Myname, CL_Logname);
424             return (&result);
425         }
426         if (fscanf(fp,"%d",&sfs_pid) != 1)
427             return (&result);
428         if ((int) generic_kill(sfs_pid, SIGINT) == 0) {
429             result = 1;
430             (void) sprintf(previous_transaction,
431                            sfs_signal->clnt_transaction);
432             (void) fprintf(stderr,"%s: Got PRIME_STOP(SIGSTOP) - %s\n",
433                                 sfs_Myname, sfs_signal->clnt_transaction);
434             (void) fprintf(stderr,"   Sent SIGINT\n");
435             return (&result); /* success */
436         } else
437             return (&result);
438
439     } else
440         return (&result); /* failure */
441
442 } /* signal_sync_sfs_1 */
443
444 /* ARGSUSED */
445 static void
446 lad_syncd_cleanup(
447     int         sig_id)
448 {
449     (void) pmap_unset(SFS_SYNCPROG, SFS_SYNCVERS);
450     (void) fprintf(stderr, "Unregistered sfs_syncd.\n");
451     (void) unlink(SFS_SYNCD_PID); 
452     exit(0);
453
454 } /* lad_syncd_cleanup */
455
456 /* sfs_m_snc.c */