Import TBBT (NFS trace replay).
[bluesky.git] / TBBT / trace_play / sfs_m_snc.c
diff --git a/TBBT/trace_play/sfs_m_snc.c b/TBBT/trace_play/sfs_m_snc.c
new file mode 100644 (file)
index 0000000..8a8f2e2
--- /dev/null
@@ -0,0 +1,456 @@
+#ifndef lint
+static char sccsid[] = "@(#)sfs_m_snc.c        2.1     97/10/23";
+#endif
+
+/*
+ *   Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
+ *     All rights reserved.
+ *             Standard Performance Evaluation Corporation (SPEC)
+ *             6585 Merchant Place, Suite 100
+ *             Warrenton, VA 20187
+ *
+ *     This product contains benchmarks acquired from several sources who
+ *     understand and agree with SPEC's goal of creating fair and objective
+ *     benchmarks to measure computer performance.
+ *
+ *     This copyright notice is placed here only to protect SPEC in the
+ *     event the source is misused in any manner that is contrary to the
+ *     spirit, the goals and the intent of SPEC.
+ *
+ *     The source code is provided to the user or company under the license
+ *     agreement for the SPEC Benchmark Suite for this product.
+ */
+
+/*****************************************************************
+ *                                                               *
+ *     Copyright 1991,1992  Legato Systems, Inc.                *
+ *     Copyright 1991,1992  Auspex Systems, Inc.                *
+ *     Copyright 1991,1992  Data General Corporation            *
+ *     Copyright 1991,1992  Digital Equipment Corporation       *
+ *     Copyright 1991,1992  Interphase Corporation              *
+ *     Copyright 1991,1992  Sun Microsystems, Inc.              *
+ *                                                               *
+ *****************************************************************/
+
+/*
+ *.Exported_routines
+ *     None.
+ *
+ *.Local_routines
+ *     void sfs_syncprog_1(struct svc_req *, SVCXPRT *)
+ *     int * signal_sync_sfs_1(struct sync_string *)
+ *     void lad_syncd_cleanup(int)
+ *
+ *.Revision_history
+ *      04-Dec-91      Keith   Include sfs_def.h for SYSV/SVR4 mem*
+ *                             functions. Include string.h for SYSV/SVR4.
+ *     28-Nov-91       Teeluckingh     Fixed 'multiple signals to sfs'
+ *                             problem.  Uses a 'transaction id' field in
+ *                             the sync rpc xdr structure to compare
+ *                             previous rpc, if the current transaction id
+ *                             matches the previous one then sfs_syncd
+ *                             just return 'success' to the client. If the
+ *                             transaction ids do not match, the actions
+ *                             are performed and the transaction id value
+ *                             is saved.
+ *     17-Jun-91       Teelucksingh    Creation - multi-client
+ *                             synchronization server sfs_syncd.
+ *                             Processes the sfs sync rpcs between systems.
+ */
+
+
+/*
+ * -------------------------  Include Files  -------------------------
+ */
+
+/*
+ * ANSI C headers
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h> 
+
+#include <sys/signal.h>
+#include <sys/file.h>
+
+#include "sfs_c_def.h"
+#include "sfs_m_def.h"
+
+
+/*
+ * -----------------------  External Definitions  -----------------------
+ */
+
+/* forward definitions for local routines */
+static void sfs_syncprog_1(struct svc_req *, SVCXPRT *);
+static int * signal_sync_sfs_1(struct sync_string *);
+static void lad_syncd_cleanup(int);
+
+/*
+ * -----------------------  Static Definitions  -----------------------
+ */
+
+int Debug_level = 0;            /* flag indicates prime client debug mode */
+char *sfs_Myname;                   /* program name */
+
+static char previous_transaction[MAX_STR1_LEN];        /* to hold transaction id */
+
+
+/*
+ * -------------------  Multi-client Synchronization  -------------------
+ */
+
+
+/*ARGSUSED*/
+int
+main(
+    int                argc,
+    char *     argv[])
+{
+    char       *nameptr;
+    SVCXPRT *  transp;
+    FILE       *pid_fp;
+#if (defined(_XOPEN_SOURCE) || defined(USE_POSIX_SIGNALS))
+    struct sigaction sig_act, old_sig_act;
+#endif /* USE_POSIX_SIGNALS */
+
+    /* 
+     * Place pid in pid log file 
+     */   
+    if ((pid_fp = fopen(SFS_SYNCD_PID, "a+")) == NULL) { 
+        perror(SFS_SYNCD_PID);  
+        (void) unlink(SFS_SYNCD_PID); 
+        exit(1); 
+    } 
+    (void) fprintf(pid_fp, "%d\n", getpid()); 
+    (void) fclose(pid_fp);
+
+    sfs_Myname = argv[0];
+
+    if ((nameptr = strrchr(argv[0], '/')) != NULL)
+        sfs_Myname = ++nameptr;
+
+#if (defined(_XOPEN_SOURCE) || defined(USE_POSIX_SIGNALS))
+    /* use XOPEN signal handling */
+    sig_act.sa_handler = generic_catcher;
+    (void)sigemptyset(&sig_act.sa_mask);
+    sig_act.sa_flags = 0;
+
+    /* signals handlers for signals used by sfs_prime */
+    sig_act.sa_handler = lad_syncd_cleanup;
+    if (sigaction(SIGINT,&sig_act,&old_sig_act) != 0) {
+               perror("sigaction failed: SIGINT");
+               (void) unlink(SFS_SYNCD_PID); 
+               exit(4);
+    }
+#else
+    /* set up SIGINT signal handler */
+    (void) signal(SIGINT, lad_syncd_cleanup);
+#endif /* USE_POSIX_SIGNALS */
+
+    (void) fprintf(stderr,"--------------------\n");
+    (void) fprintf(stderr,"Start of sfs run.\n");
+
+    (void) pmap_unset(SFS_SYNCPROG, SFS_SYNCVERS);
+
+    transp = svcudp_create(RPC_ANYSOCK);
+    if (transp == ((SVCXPRT *) NULL)) {
+       (void) fprintf(stderr, "%s: cannot create udp service.\n", sfs_Myname);
+               (void) unlink(SFS_SYNCD_PID); 
+       exit(5);
+    }
+    if (!svc_register(transp, SFS_SYNCPROG, SFS_SYNCVERS,
+                    sfs_syncprog_1, IPPROTO_UDP)) {
+       (void) fprintf(stderr,
+           "%s: unable to register (SFS_SYNCPROG,SFS_SYNCVERS, udp).\n",
+           sfs_Myname);
+               (void) unlink(SFS_SYNCD_PID); 
+       exit(6);
+    }
+
+    transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+    if (transp == ((SVCXPRT *) NULL)) {
+       (void) fprintf(stderr, "%s: cannot create tcp service.\n", sfs_Myname);
+               (void) unlink(SFS_SYNCD_PID); 
+       exit(6);
+    }
+    if (!svc_register(transp, SFS_SYNCPROG, SFS_SYNCVERS,
+                     sfs_syncprog_1, IPPROTO_TCP)) {
+       (void) fprintf(stderr,
+           "%s: unable to register (SFS_SYNCPROG, SFS_SYNCVERS, tcp).\n",
+           sfs_Myname);
+               (void) unlink(SFS_SYNCD_PID); 
+       exit(7);
+    }
+
+    svc_run();
+    (void) fprintf(stderr, "%s: svc_run returned\n", sfs_Myname);
+    return(1);
+
+} /* main */
+
+
+static void
+sfs_syncprog_1(
+    struct svc_req *   rqstp,
+    SVCXPRT *          transp)
+{
+    union {
+       sync_string     signal_sync_sfs_1_arg;
+    } argument;
+    char *             result;
+    bool_t             (*xdr_argument)(), (*xdr_result)();
+    char *             (*local)();
+
+    switch (rqstp->rq_proc) {
+       case SIGNAL_NULLPROC:
+           (void) svc_sendreply(transp, xdr_void, (char *)NULL);
+           return;
+
+       case SIGNAL_SFS:
+           xdr_argument = xdr_sync_string;
+           xdr_result = xdr_int;
+           local = (char * (*)()) signal_sync_sfs_1;
+           break;
+
+       default:
+           svcerr_noproc(transp);
+           return;
+    }
+    (void) memset((char *) &argument, '\0', sizeof(argument));
+    if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
+       svcerr_decode(transp);
+       return;
+    }
+    result = (*local)(&argument);
+    if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
+       svcerr_systemerr(transp);
+    }
+    if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
+       (void) fprintf(stderr, "%s: unable to free arguments\n", sfs_Myname);
+               (void) unlink(SFS_SYNCD_PID); 
+       exit(8);
+    }
+
+} /* sfs_syncprog_1 */
+
+
+/*
+ * signal_sync_sfs_1 - multi-client synch RPC
+ * Provides interface between sfs program running
+ * on multiple clients and the controlling sfs_prime program.
+ */
+static int *
+signal_sync_sfs_1(
+    struct sync_string *       sfs_signal)
+{
+    static int                 result = 0 ;    /* return status - failure */
+    FILE *                     fp;
+    int                                sfs_pid;        /* sfs parent process pid */
+    char                       datafile[SFS_MAXPATHLEN]; /* results file */
+    char                       CL_Logname[SFS_MAXPATHLEN];
+
+    result = 0;
+    /* if a duplicate transactions then just return success to calling client */
+    if (strcmp(sfs_signal->clnt_transaction, previous_transaction) == 0) {
+       (void) fprintf(stderr,"%s: Got a duplicate signal - %s\n",
+                       sfs_Myname, sfs_signal->clnt_transaction);
+       result = 1;
+       return(&result);
+    }
+
+    if (strcmp(sfs_signal->clnt_type,"CLIENT_SIGNAL") == 0) {
+
+       /*
+        * message from parent sfs process on client to Prime-client
+        * (sfs_prime).
+        *
+        * Append client id to Prime client sync logfile
+        */
+       fp = fopen(SFS_PRIME_SYNC_LOG, "a");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, SFS_PRIME_SYNC_LOG);
+           return (&result);
+       }
+       (void) fwrite((char *)&sfs_signal->clnt_id,
+                       sizeof(sfs_signal->clnt_id), 1, fp);
+       (void) fclose(fp);
+       result = 1;
+       (void) sprintf(previous_transaction, sfs_signal->clnt_transaction);
+       (void) fprintf(stderr,"%s: Got Client_SIGNAL - %s\n",
+                       sfs_Myname, sfs_signal->clnt_transaction);
+       return (&result); /* success */
+
+    } else if (strcmp(sfs_signal->clnt_type,"CLIENT_DATA") == 0) {
+
+       /*
+        * message from parent sfs process on client to Prime-client
+        * completed run, here are my results. Write it to file and let
+        * Prime client know about it.
+        */
+       (void) sprintf(datafile,"%s%d",
+                       PRIME_RESULTS_LOG, sfs_signal->clnt_id);
+       fp = fopen(datafile, "w");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, datafile);
+           return (&result);
+       }
+       (void) fprintf(fp,"%s",sfs_signal->clnt_data);
+       (void) fclose(fp);
+
+       /* after writing data write client id to sync log */
+       fp = fopen(SFS_PRIME_SYNC_LOG, "a");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, SFS_PRIME_SYNC_LOG);
+           return (&result);
+       }
+       (void) fwrite((char *)&sfs_signal->clnt_id,
+                               sizeof(sfs_signal->clnt_id), 1, fp);
+       (void) fclose(fp);
+
+       /* let the remote process know success */
+       result = 1;
+       (void) sprintf(previous_transaction, sfs_signal->clnt_transaction);
+       (void) fprintf(stderr,"%s: Got Client_DATA - %s\n",
+                       sfs_Myname, sfs_signal->clnt_transaction);
+       return (&result);
+
+    } else if (strcmp(sfs_signal->clnt_type,"CLIENT_STOP") == 0) {
+
+       /*
+        * message from parent sfs process on client to Prime-client
+        * (sfs_prime) to stop due to error.
+        */
+       fp = fopen(SFS_PRIME_SYNC_LOG, "a");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, SFS_PRIME_SYNC_LOG);
+           return (&result);
+       }
+       /*
+        * Write out client id 1000 times to fool prime into thinking
+        * all clients have responded and will get an error when it
+        * tries to communicate to it.
+        */
+       for (result = 0; result < 1000; result++)
+               (void) fwrite((char *)&sfs_signal->clnt_id,
+                       sizeof(sfs_signal->clnt_id), 1, fp);
+       (void) fclose(fp);
+       result = 1;
+       (void) sprintf(previous_transaction, sfs_signal->clnt_transaction);
+       (void) fprintf(stderr,"%s: Got Client_STOP - %s\n",
+                       sfs_Myname, sfs_signal->clnt_transaction);
+       return (&result); /* success */
+
+    } else if (strcmp(sfs_signal->clnt_type,"PRIME_SIGNAL") == 0) {
+
+       /*
+        * message from the Prime client (sfs_prime)
+        * send SIGUSR1 signal to parent sfs process on
+        * client - signals it to proceed
+        */
+       (void) sprintf(CL_Logname,"%s%d",
+                       SFS_CLIENT_SYNC_LOG, sfs_signal->clnt_id);
+       fp = fopen(CL_Logname, "r");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, CL_Logname);
+           return(&result);
+       }
+       if (fscanf(fp,"%d",&sfs_pid) != 1)
+           return (&result);
+       if ((int) generic_kill(sfs_pid, SIGUSR1) == 0) {
+           result = 1;
+           (void) sprintf(previous_transaction,
+                          sfs_signal->clnt_transaction);
+           (void) fprintf(stderr,"%s: Got PRIME_SIGNAL(SIGUSR1) - %s\n",
+                           sfs_Myname, sfs_signal->clnt_transaction);
+           (void) fprintf(stderr,"   Sent SIGUSR1\n");
+           return (&result); /* success */
+       } else
+           return (&result);
+
+    } else if (strcmp(sfs_signal->clnt_type,"PRIME_ALARM") == 0) {
+
+       /*
+        * message from the Prime client (sfs_prime)
+        * send SIGALRM signal to parent sfs process on
+        * client - tell it to wake up and finish execution at this time
+        */
+
+       (void) sprintf(CL_Logname,"%s%d",
+                       SFS_CLIENT_SYNC_LOG, sfs_signal->clnt_id);
+       fp = fopen(CL_Logname, "r");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, CL_Logname);
+           return (&result);
+       }
+       if (fscanf(fp,"%d",&sfs_pid) != 1)
+           return (&result);
+       if ((int) generic_kill(sfs_pid, SIGALRM) == 0) {
+           result = 1;
+           (void) sprintf(previous_transaction,
+                          sfs_signal->clnt_transaction);
+           (void) fprintf(stderr,"%s: Got PRIME_ALARM(SIGALRM) - %s\n",
+                               sfs_Myname, sfs_signal->clnt_transaction);
+           (void) fprintf(stderr,"   Sent SIGALRM\n");
+           return (&result); /* success */
+       } else
+           return (&result);
+
+    } else if (strcmp(sfs_signal->clnt_type,"PRIME_STOP") == 0) {
+
+       /*
+        * message from Prime-client
+        * sent SIGINT signal to sfs parent process
+        * to tell it to terminate experiment now
+        */
+       (void) sprintf(CL_Logname,"%s%d",
+                       SFS_CLIENT_SYNC_LOG, sfs_signal->clnt_id);
+       fp = fopen(CL_Logname, "r");
+       if (fp == NULL) {
+           (void) fprintf(stderr,"%s: Cannot open %s\n",
+               sfs_Myname, CL_Logname);
+           return (&result);
+       }
+       if (fscanf(fp,"%d",&sfs_pid) != 1)
+           return (&result);
+       if ((int) generic_kill(sfs_pid, SIGINT) == 0) {
+           result = 1;
+           (void) sprintf(previous_transaction,
+                          sfs_signal->clnt_transaction);
+           (void) fprintf(stderr,"%s: Got PRIME_STOP(SIGSTOP) - %s\n",
+                               sfs_Myname, sfs_signal->clnt_transaction);
+           (void) fprintf(stderr,"   Sent SIGINT\n");
+           return (&result); /* success */
+       } else
+           return (&result);
+
+    } else
+       return (&result); /* failure */
+
+} /* signal_sync_sfs_1 */
+
+/* ARGSUSED */
+static void
+lad_syncd_cleanup(
+    int         sig_id)
+{
+    (void) pmap_unset(SFS_SYNCPROG, SFS_SYNCVERS);
+    (void) fprintf(stderr, "Unregistered sfs_syncd.\n");
+    (void) unlink(SFS_SYNCD_PID); 
+    exit(0);
+
+} /* lad_syncd_cleanup */
+
+/* sfs_m_snc.c */