Commit | Line | Data |
---|---|---|
fc4ef1d0 C |
1 | /* dsa.c - Main routine for QUIPU DSA process */ |
2 | ||
3 | #ifndef lint | |
4 | static 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 | ||
78 | PS opt; | |
79 | static int debug = 1; | |
80 | static int nbits = FD_SETSIZE; | |
81 | ||
82 | extern LLog * log_dsap; | |
83 | ||
84 | static char *myname; | |
85 | ||
86 | void adios (), advise (); | |
87 | static envinit (), setdsauid(); | |
88 | SFD attempt_restart(); | |
89 | extern int print_parse_errors; | |
90 | extern int parse_line; | |
91 | struct task_act * task_select(); | |
92 | extern time_t time(); | |
93 | ||
94 | extern SFP abort_vector; | |
95 | ||
96 | #ifndef NO_STATS | |
97 | extern LLog *log_stat; | |
98 | #endif | |
99 | ||
100 | /* | |
101 | * Basic data structure of the DSA server. | |
102 | */ | |
103 | char * mydsaname = "undefined"; | |
104 | struct PSAPaddr * mydsaaddr = NULLPA; | |
105 | struct PSAPaddr * dsaladdr = NULLPA; | |
106 | struct connection * connlist; | |
107 | int conns_used; | |
108 | struct connection * connwaitlist; | |
109 | struct di_block * deferred_dis = NULL_DI_BLOCK; | |
110 | struct oper_act * get_edb_ops; | |
111 | ||
112 | char ** sargv; | |
113 | ||
114 | main(argc, argv) | |
115 | int argc; | |
116 | char **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 | ||
261 | dsa_abort(isfatal) | |
262 | int 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 | ||
282 | SFD stop_dsa (sig) | |
283 | int 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 | ||
296 | SFD list_status (sig) | |
297 | int 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 | ||
329 | static 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 | ||
351 | fork_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 | |
408 | void adios (va_alist) | |
409 | va_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 | ||
427 | void adios (what, fmt) | |
428 | char *what, | |
429 | *fmt; | |
430 | { | |
431 | adios (what, fmt); | |
432 | } | |
433 | #endif | |
434 | ||
435 | #ifndef lint | |
436 | void advise (va_alist) | |
437 | va_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 | ||
453 | void advise (code, what, fmt) | |
454 | char *what, | |
455 | *fmt; | |
456 | int code; | |
457 | { | |
458 | advise (code, what, fmt); | |
459 | } | |
460 | #endif | |
461 | ||
462 | ||
463 | ||
464 | static setdsauid () | |
465 | { | |
466 | struct stat buf; | |
467 | extern 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 | ||
483 | SFD attempt_restart (sig) | |
484 | int sig; | |
485 | { | |
486 | int fpid, sd; | |
487 | unsigned int secs; | |
488 | extern 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 |