Initial revision
[nfs-utils.git] / utils / statd / simulate.c
1 /*
2  * Copyright (C) 1995-1997, 1999 Jeffrey A. Uphoff
3  *
4  * NSM for Linux.
5  */
6
7 #include "config.h"
8 #ifndef SIMULATIONS
9 # error How the hell did we get here?
10 #endif
11
12 /* If we're running the simulator, we're debugging.  Pretty simple. */
13 #ifndef DEBUG
14 # define DEBUG
15 #endif
16
17 #include <signal.h>
18 #include <string.h>
19 #include <rpc/rpc.h>
20 #include <rpc/pmap_clnt.h>
21 #include "statd.h"
22 #include "sim_sm_inter.h"
23
24 static void daemon_simulator (void);
25 static void sim_killer (int sig);
26 static void simulate_crash (char *);
27 static void simulate_mon (char *, char *, char *, char *, char *);
28 static void simulate_stat (char *, char *);
29 static void simulate_unmon (char *, char *, char *, char *);
30 static void simulate_unmon_all (char *, char *, char *);
31
32 static int sim_port = 0;
33
34 extern void sim_sm_prog_1 (struct svc_req *, register SVCXPRT);
35 extern void svc_exit (void);
36
37 void
38 simulator (int argc, char **argv)
39 {
40   log_enable (1);
41
42   if (argc == 2)
43     if (!strcasecmp (*argv, "crash"))
44       simulate_crash (*(&argv[1]));
45
46   if (argc == 3) {
47     if (!strcasecmp (*argv, "stat"))
48       simulate_stat (*(&argv[1]), *(&argv[2]));
49   }
50   if (argc == 4) {
51     if (!strcasecmp (*argv, "unmon_all"))
52       simulate_unmon_all (*(&argv[1]), *(&argv[2]), *(&argv[3]));
53   }
54   if (argc == 5) {
55     if (!strcasecmp (*argv, "unmon"))
56       simulate_unmon (*(&argv[1]), *(&argv[2]), *(&argv[3]), *(&argv[4]));
57   }
58   if (argc == 6) {
59     if (!strcasecmp (*argv, "mon"))
60       simulate_mon (*(&argv[1]), *(&argv[2]), *(&argv[3]), *(&argv[4]),
61                     *(&argv[5]));
62   }
63   die ("WTF?  Give me something I can use!");
64 }
65
66 static void
67 simulate_mon (char *calling, char *monitoring, char *as, char *proggy,
68               char *fool)
69 {
70   CLIENT *client;
71   sm_stat_res *result;
72   mon mon;
73
74   dprintf (L_DEBUG, "Calling %s (as %s) to monitor %s", calling, as,
75            monitoring);
76
77   if ((client = clnt_create (calling, SM_PROG, SM_VERS, "udp")) == NULL)
78     die ("%s", clnt_spcreateerror ("clnt_create"));
79
80   memcpy (mon.priv, fool, SM_PRIV_SIZE);
81   mon.mon_id.my_id.my_name = xstrdup (as);
82   sim_port = atoi (proggy) * SIM_SM_PROG;
83   mon.mon_id.my_id.my_prog = sim_port; /* Pseudo-dummy */
84   mon.mon_id.my_id.my_vers = SIM_SM_VERS;
85   mon.mon_id.my_id.my_proc = SIM_SM_MON;
86   mon.mon_id.mon_name = monitoring;
87
88   if (!(result = sm_mon_1 (&mon, client)))
89     die ("%s", clnt_sperror (client, "sm_mon_1"));
90
91   free (mon.mon_id.my_id.my_name);
92
93   if (result->res_stat != STAT_SUCC) {
94     log (L_FATAL, "SM_MON request failed, state: %d", result->state);
95     exit (0);
96   } else {
97     dprintf (L_DEBUG, "SM_MON result successful, state: %d\n", result->state);
98     dprintf (L_DEBUG, "Waiting for callback.");
99     daemon_simulator ();
100     exit (0);
101   }
102 }
103
104 static void
105 simulate_unmon (char *calling, char *unmonitoring, char *as, char *proggy)
106 {
107   CLIENT *client;
108   sm_stat *result;
109   mon_id mon_id;
110
111   dprintf (L_DEBUG, "Calling %s (as %s) to unmonitor %s", calling, as,
112            unmonitoring);
113
114   if ((client = clnt_create (calling, SM_PROG, SM_VERS, "udp")) == NULL)
115     die ("%s", clnt_spcreateerror ("clnt_create"));
116
117   mon_id.my_id.my_name = xstrdup (as);
118   mon_id.my_id.my_prog = atoi (proggy) * SIM_SM_PROG;
119   mon_id.my_id.my_vers = SIM_SM_VERS;
120   mon_id.my_id.my_proc = SIM_SM_MON;
121   mon_id.mon_name = unmonitoring;
122
123   if (!(result = sm_unmon_1 (&mon_id, client)))
124     die ("%s", clnt_sperror (client, "sm_unmon_1"));
125
126   free (mon_id.my_id.my_name);
127   dprintf (L_DEBUG, "SM_UNMON request returned state: %d\n", result->state);
128   exit (0);
129 }
130
131 static void
132 simulate_unmon_all (char *calling, char *as, char *proggy)
133 {
134   CLIENT *client;
135   sm_stat *result;
136   my_id my_id;
137
138   dprintf (L_DEBUG, "Calling %s (as %s) to unmonitor all hosts", calling, as);
139
140   if ((client = clnt_create (calling, SM_PROG, SM_VERS, "udp")) == NULL)
141     die ("%s", clnt_spcreateerror ("clnt_create"));
142
143   my_id.my_name = xstrdup (as);
144   my_id.my_prog = atoi (proggy) * SIM_SM_PROG;
145   my_id.my_vers = SIM_SM_VERS;
146   my_id.my_proc = SIM_SM_MON;
147
148   if (!(result = sm_unmon_all_1 (&my_id, client)))
149     die ("%s", clnt_sperror (client, "sm_unmon_all_1"));
150
151   free (my_id.my_name);
152   dprintf (L_DEBUG, "SM_UNMON_ALL request returned state: %d\n", result->state);
153   exit (0);
154 }
155
156 static void
157 simulate_crash (char *host)
158 {
159   CLIENT *client;
160
161   if ((client = clnt_create (host, SM_PROG, SM_VERS, "udp")) == NULL)
162     die ("%s", clnt_spcreateerror ("clnt_create"));
163
164   if (!sm_simu_crash_1 (NULL, client))
165     die ("%s", clnt_sperror (client, "sm_simu_crash_1"));
166
167   exit (0);
168 }
169
170 static void
171 simulate_stat (char *calling, char *monitoring)
172 {
173   CLIENT *client;
174   sm_name checking;
175   sm_stat_res *result;
176   
177   if ((client = clnt_create (calling, SM_PROG, SM_VERS, "udp")) == NULL)
178     die ("%s", clnt_spcreateerror ("clnt_create"));
179
180   checking.mon_name = monitoring;
181
182   if (!(result = sm_stat_1 (&checking, client)))
183     die ("%s", clnt_sperror (client, "sm_stat_1"));
184
185   if (result->res_stat == STAT_SUCC)
186     dprintf (L_DEBUG, "STAT_SUCC from %s for %s, state: %d", calling,
187              monitoring, result->state);
188   else
189     dprintf (L_DEBUG, "STAT_FAIL from %s for %s, state: %d", calling,
190              monitoring, result->state);
191
192   exit (0);
193 }
194
195 static void
196 sim_killer (int sig)
197 {
198   log (L_FATAL, "Simulator caught signal %d, un-registering and exiting.", sig);
199   pmap_unset (sim_port, SIM_SM_VERS);
200   exit (0);
201 }
202
203 static void
204 daemon_simulator (void)
205 {
206   signal (SIGHUP, sim_killer);
207   signal (SIGINT, sim_killer);
208   signal (SIGTERM, sim_killer);
209   pmap_unset (sim_port, SIM_SM_VERS);
210   do_regist (sim_port, sim_sm_prog_1);
211 /*   do_regist (sim_port, (__dispatch_fn_t)sim_sm_prog_1); */
212   svc_run ();
213   pmap_unset (sim_port, SIM_SM_VERS);
214 }
215
216 void *
217 sim_sm_mon_1_svc (struct status *argp, struct svc_req *rqstp)
218 {
219   static char *result;
220
221   dprintf (L_DEBUG, "Recieved state %d for mon_name %s (opaque \"%s\")",
222            argp->state, argp->mon_name, argp->priv);
223   svc_exit ();
224   return ((void *)&result);
225 }