Start development on 386BSD 0.0
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / contrib / isode / quipu / dsa.c
CommitLineData
fc4ef1d0
C
1/* dsa.c - Main routine for QUIPU DSA process */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/quipu/RCS/dsa.c,v 7.9 91/03/09 11:56:48 mrose Exp $";
5#endif
6
7/*
8 * $Header: /f/osi/quipu/RCS/dsa.c,v 7.9 91/03/09 11:56:48 mrose Exp $
9 *
10 *
11 * $Log: dsa.c,v $
12 * Revision 7.9 91/03/09 11:56:48 mrose
13 * update
14 *
15 * Revision 7.8 91/02/22 09:39:04 mrose
16 * Interim 6.8
17 *
18 * Revision 7.7 90/11/20 15:28:47 mrose
19 * cjr
20 *
21 * Revision 7.6 90/10/17 11:54:00 mrose
22 * sync
23 *
24 * Revision 7.5 90/07/09 14:45:56 mrose
25 * sync
26 *
27 * Revision 7.4 90/03/15 11:18:57 mrose
28 * quipu-sync
29 *
30 * Revision 7.3 90/01/11 23:55:57 mrose
31 * lint
32 *
33 * Revision 7.2 90/01/11 18:37:21 mrose
34 * real-sync
35 *
36 * Revision 7.1 89/12/19 16:53:08 mrose
37 * dgram
38 *
39 * Revision 7.0 89/11/23 22:17:19 mrose
40 * Release 6.0
41 *
42 */
43
44/*
45 * NOTICE
46 *
47 * Acquisition, use, and distribution of this module and related
48 * materials are subject to the restrictions of a license agreement.
49 * Consult the Preface in the User's Manual for the full terms of
50 * this agreement.
51 *
52 */
53
54
55#include <signal.h>
56#include <stdio.h>
57#include <varargs.h>
58#include "rosap.h"
59#include "tsap.h"
60#include "logger.h"
61#include "tailor.h"
62#include "quipu/util.h"
63#include "quipu/connection.h"
64#include <sys/ioctl.h>
65#include <sys/stat.h>
66#ifdef BSD42
67#include <sys/file.h>
68#endif
69#ifdef SYS5
70#include <fcntl.h>
71#endif
72
73#include "dgram.h"
74#ifdef TCP
75#include "internet.h"
76#endif
77
78PS opt;
79static int debug = 1;
80static int nbits = FD_SETSIZE;
81
82extern LLog * log_dsap;
83
84static char *myname;
85
86void adios (), advise ();
87static envinit (), setdsauid();
88SFD attempt_restart();
89extern int print_parse_errors;
90extern int parse_line;
91struct task_act * task_select();
92extern time_t time();
93
94extern SFP abort_vector;
95
96#ifndef NO_STATS
97extern LLog *log_stat;
98#endif
99
100/*
101* Basic data structure of the DSA server.
102*/
103char * mydsaname = "undefined";
104struct PSAPaddr * mydsaaddr = NULLPA;
105struct PSAPaddr * dsaladdr = NULLPA;
106struct connection * connlist;
107int conns_used;
108struct connection * connwaitlist;
109struct di_block * deferred_dis = NULL_DI_BLOCK;
110struct oper_act * get_edb_ops;
111
112char ** sargv;
113
114main(argc, argv)
115int argc;
116char **argv;
117{
118#ifdef DEBUG
119 unsigned proc_size = 0;
120 unsigned new_size;
121 extern caddr_t sbrk();
122#endif
123 extern char * mydsaname;
124 extern char startup_update;
125 extern time_t timenow;
126 struct task_act * task;
127 int secs;
128 char start_buf [LINESIZE];
129 /*
130 * Function to stop DSA server.
131 */
132 SFD stop_dsa();
133#ifdef SIGUSR1
134 SFD list_status ();
135#endif
136
137 sargv = argv;
138
139 if (myname = rindex (argv[0], '/'))
140 myname++;
141 if (myname == NULL || *myname == NULL)
142 myname = argv[0];
143
144 isodetailor (myname,0);
145
146 envinit(); /* detach */
147
148 quipu_syntaxes ();
149 dsa_sys_init(&argc, &argv);
150 setdsauid();
151
152 print_parse_errors = FALSE;
153
154#ifndef NO_STATS
155 ll_hdinit (log_stat,myname);
156#endif
157
158 if ((opt = ps_alloc (std_open)) == NULLPS)
159 fatal (-12,"ps_alloc failed");
160 if (std_setup (opt,stdout) == NOTOK)
161 fatal (-13,"std_setup failed");
162
163 DLOG (log_dsap,LLOG_DEBUG,( "About to dsa_init()"));
164
165 if(dsa_init() == NOTOK)
166 {
167 fatal(-14,"Couldn't initialise the DSA!!");
168 }
169
170
171 if(net_init() == NOTOK)
172 {
173 fatal(-15,"Couldn't start the DSA!!");
174 }
175
176
177 if (startup_update)
178 {
179 /* Will generate a list of EDB operations! */
180 (void) time (&timenow);
181 slave_update();
182 }
183
184 {
185 extern char *treedir;
186 char filebuf[BUFSIZ];
187 FILE *fp;
188
189 (void) sprintf (filebuf, "%s/PID", treedir);
190 if (fp = fopen (filebuf, "w")) {
191 (void) fprintf (fp, "%d\n", getpid ());
192 (void) fclose (fp);
193 }
194 else
195 LLOG (log_dsap,LLOG_EXCEPTIONS,("Can't open PID file %s",filebuf));
196 }
197
198 /*
199 * Do stop_dsa() on receiving a Ctrl-C
200 */
201
202 (void) signal (SIGINT, stop_dsa);
203 (void) signal (SIGTERM,stop_dsa);
204 (void) signal (SIGHUP, stop_dsa);
205
206 /* now started don't stop on core dumps !!! */
207 (void) signal (SIGQUIT, attempt_restart);
208 (void) signal (SIGILL, attempt_restart);
209 (void) signal (SIGBUS, attempt_restart);
210 (void) signal (SIGSEGV, attempt_restart);
211 (void) signal (SIGSYS, attempt_restart);
212 (void) signal (SIGPIPE, attempt_restart);
213#ifdef SIGUSR1
214 (void) signal (SIGUSR1, list_status);
215#endif
216
217 abort_vector = attempt_restart;
218 parse_line = 0;
219
220 (void) sprintf (start_buf,"DSA %s has started on %s",mydsaname,
221 paddr2str(dsaladdr,NULLNA));
222
223 LLOG (log_dsap,LLOG_NOTICE,(start_buf));
224#ifndef NO_STATS
225 LLOG (log_stat,LLOG_NOTICE,(start_buf));
226#endif
227
228 if (debug)
229 (void) fprintf (stderr,"%s\n",start_buf);
230
231 start_malloc_trace (NULLCP);
232
233#ifdef DEBUG
234 proc_size = (unsigned) sbrk(0);
235#endif
236
237 for(;;)
238 {
239 if((task = task_select(&secs)) == NULLTASK)
240 {
241#ifdef DEBUG
242 if ( secs != 0 ) {
243 /* Only if we are idle ! */
244 new_size = (unsigned) sbrk(0);
245 if ( new_size > proc_size) {
246 LLOG (log_dsap, LLOG_NOTICE, ("Process grown by %d bytes", new_size - proc_size));
247 proc_size = new_size;
248 }
249 }
250#endif
251 dsa_wait(secs); /* Check network with timeout of secs */
252 }
253 else
254 {
255 dsa_work(task); /* Process the DSA task selected */
256 dsa_wait(0);
257 }
258 } /* forever */
259} /* main */
260
261dsa_abort(isfatal)
262int isfatal;
263{
264 struct connection * cn;
265 struct DSAPindication di_s;
266 struct DSAPindication * di = &di_s;
267
268 for(cn=connlist; cn!=NULLCONN; cn=cn->cn_next)
269 if (cn -> cn_ad != NOTOK) {
270 if (isfatal || (! cn -> cn_initiator))
271 (void) close (cn -> cn_ad);
272 else {
273 (void) DUAbortRequest(cn->cn_ad, di);
274 }
275 }
276
277 watch_dog ("stop_listeners");
278 stop_listeners();
279 watch_dog_reset();
280}
281
282SFD stop_dsa (sig)
283int sig;
284{
285 (void) signal (sig, SIG_DFL); /* to stop recursion */
286 LLOG (log_dsap,LLOG_FATAL,("*** Stopping on signal %d ***",sig));
287 if (debug)
288 (void) fprintf (stderr,"DSA %s has Stopped\n",mydsaname);
289 dsa_abort(0);
290 exit (0);
291}
292
293#ifdef SIGUSR1
294/* ARGSUSED */
295
296SFD list_status (sig)
297int sig;
298{
299 int fd;
300 struct stat st;
301 register struct connection *cn;
302 time_t now;
303
304#ifndef BSD42
305 (void) signal (SIGUSR1, list_status);
306#endif
307
308 for (fd = getdtablesize () - 1; fd >= 0; fd--)
309 if (fstat (fd, &st) != NOTOK)
310 LLOG (log_dsap, LLOG_EXCEPTIONS,
311 ("fd %d: fmt=0%o", fd, st.st_mode & S_IFMT));
312#ifndef NO_STATS
313 LLOG (log_dsap, LLOG_EXCEPTIONS, ("logs dsap=%d stat=%d",
314 log_dsap -> ll_fd, log_stat -> ll_fd));
315#else
316 LLOG (log_dsap, LLOG_EXCEPTIONS, ("logs dsap=%d", log_dsap -> ll_fd));
317#endif
318 (void) time (&now);
319 for (cn = connlist; cn; cn = cn -> cn_next)
320 if (cn -> cn_ad != NOTOK)
321 LLOG (log_dsap, LLOG_EXCEPTIONS,
322 ("cn %d: init=%d used=%ld release=%ld",
323 cn -> cn_ad, cn -> cn_initiator,
324 (long) now - cn -> cn_last_used,
325 (long) now - cn -> cn_last_release));
326}
327#endif
328
329static envinit () {
330 int i,
331 sd;
332
333 nbits = getdtablesize ();
334
335 if (!(debug = isatty (2))) {
336 for (i = 0; i < 5; i++) {
337 switch (fork ()) {
338 case NOTOK:
339 sleep (5);
340 continue;
341
342 case OK:
343 goto fork_ok;
344
345 default:
346 _exit (0);
347 }
348 break;
349 }
350
351fork_ok:;
352 (void) chdir ("/");
353
354 if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
355 adios ("/dev/null", "unable to read");
356 if (sd != 0)
357 (void) dup2 (sd, 0), (void) close (sd);
358 (void) dup2 (0, 1);
359 (void) dup2 (0, 2);
360
361#ifdef SETSID
362 if (setsid () == NOTOK)
363 advise (LLOG_EXCEPTIONS, "failed", "setsid");
364#endif
365#ifdef TIOCNOTTY
366 if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
367 (void) ioctl (sd, TIOCNOTTY, NULLCP);
368 (void) close (sd);
369 }
370#else
371#ifdef SYS5
372 (void) setpgrp ();
373 (void) signal (SIGINT, SIG_IGN);
374 (void) signal (SIGQUIT, SIG_IGN);
375#endif
376#endif
377 }
378#ifndef DEBUG
379 /* "Normal" ISODE behavior of full logging only without DEBUG */
380 else
381 ll_dbinit (log_dsap, myname);
382#endif
383
384#ifndef sun /* damn YP... */
385 for (sd = 3; sd < nbits; sd++) {
386 if (log_dsap -> ll_fd == sd)
387 continue;
388#ifdef NO_STATS
389 if (log_stats -> ll_fd == sd)
390 continue;
391#endif
392 (void) close (sd);
393 }
394#endif
395
396 (void) signal (SIGPIPE, SIG_IGN);
397
398 ll_hdinit (log_dsap, myname);
399#ifdef DEBUG
400 advise (LLOG_TRACE, NULLCP, "starting");
401#endif
402}
403
404
405/* \f ERRORS */
406
407#ifndef lint
408void adios (va_alist)
409va_dcl
410{
411 va_list ap;
412
413 va_start (ap);
414
415 _ll_log (log_dsap, LLOG_FATAL, ap);
416
417 va_end (ap);
418
419 if (debug)
420 (void) fprintf (stderr,"adios exit - see dsap.log\n");
421 dsa_abort(1);
422 _exit (-18);
423}
424#else
425/* VARARGS */
426
427void adios (what, fmt)
428char *what,
429 *fmt;
430{
431 adios (what, fmt);
432}
433#endif
434
435#ifndef lint
436void advise (va_alist)
437va_dcl
438{
439 int code;
440 va_list ap;
441
442 va_start (ap);
443
444 code = va_arg (ap, int);
445
446 (void) _ll_log (log_dsap, code, ap);
447
448 va_end (ap);
449}
450#else
451/* VARARGS */
452
453void advise (code, what, fmt)
454char *what,
455 *fmt;
456int code;
457{
458 advise (code, what, fmt);
459}
460#endif
461
462
463
464static setdsauid ()
465{
466struct stat buf;
467extern char * treedir;
468
469 (void) stat (treedir,&buf);
470
471 if (setgid (buf.st_gid) == -1)
472 LLOG (log_dsap,LLOG_EXCEPTIONS,("Can't set gid %d (database directory \"%s\")",buf.st_uid,treedir));
473
474 if (setuid (buf.st_uid) == -1)
475 LLOG (log_dsap,LLOG_EXCEPTIONS,("Can't set uid %d (database directory \"%s\")",buf.st_uid,treedir));
476}
477
478
479
480#define RESTART_TIME 30 /* for connections to clear... */
481#define CLEAR_TIME 300 /* .. */
482
483SFD attempt_restart (sig)
484int sig;
485{
486int fpid, sd;
487unsigned int secs;
488extern char * mydsaname;
489
490 if (sig > 0)
491 (void) signal (sig, SIG_DFL); /* to stop recursion */
492
493 if (sig >= 0 && debug)
494 (void) fprintf (stderr,"DSA %s has a problem\n",mydsaname);
495
496 dsa_abort(sig != NOTOK);
497 secs = sig != NOTOK ? CLEAR_TIME : RESTART_TIME;
498
499 for (sd = 3; sd < nbits; sd++) {
500 if (log_dsap -> ll_fd == sd)
501 continue;
502#ifdef NO_STATS
503 if (log_stats -> ll_fd == sd)
504 continue;
505#endif
506 (void) close (sd);
507 }
508
509 if ( sig == -2 || (fpid = fork()) == 0) {
510 if (sig == -2) { /* restart due to congestion... */
511 LLOG (log_dsap,LLOG_FATAL, ("*** in-situ restart attempted ***"));
512#ifndef NO_STATS
513 LLOG (log_stat,LLOG_NOTICE,("RESTARTING (%s)",mydsaname));
514#endif
515 }
516
517 sleep (secs); /* give connections time to clear */
518 (void) execv (isodefile(sargv[0], 1),sargv);
519 exit (-19);
520 }
521
522 log_dsap -> ll_syslog = LLOG_FATAL;
523
524 if (fpid != -1) {
525 LLOG (log_dsap,LLOG_FATAL,("Quipu restart attempted in %d seconds (sig %d)", secs,sig));
526#ifndef NO_STATS
527 LLOG (log_stat,LLOG_NOTICE,("RESTARTING with pid %d (%s)",fpid,mydsaname));
528#endif
529 } else {
530#ifndef NO_STATS
531 LLOG (log_stat,LLOG_NOTICE,("PANIC (%s)",mydsaname));
532#endif
533 LLOG (log_dsap,LLOG_FATAL,("Quipu aborting - sig (%d)",sig));
534 }
535
536 (void) signal (SIGIOT, SIG_DFL);
537 abort ();
538 exit (-20); /* abort should not return */
539}
540