/* dsa.c - Main routine for QUIPU DSA process */
static char *rcsid
= "$Header: /f/osi/quipu/RCS/dsa.c,v 7.9 91/03/09 11:56:48 mrose Exp $";
* $Header: /f/osi/quipu/RCS/dsa.c,v 7.9 91/03/09 11:56:48 mrose Exp $
* Revision 7.9 91/03/09 11:56:48 mrose
* Revision 7.8 91/02/22 09:39:04 mrose
* Revision 7.7 90/11/20 15:28:47 mrose
* Revision 7.6 90/10/17 11:54:00 mrose
* Revision 7.5 90/07/09 14:45:56 mrose
* Revision 7.4 90/03/15 11:18:57 mrose
* Revision 7.3 90/01/11 23:55:57 mrose
* Revision 7.2 90/01/11 18:37:21 mrose
* Revision 7.1 89/12/19 16:53:08 mrose
* Revision 7.0 89/11/23 22:17:19 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
#include "quipu/connection.h"
static int nbits
= FD_SETSIZE
;
void adios (), advise ();
static envinit (), setdsauid();
extern int print_parse_errors
;
struct task_act
* task_select();
* Basic data structure of the DSA server.
char * mydsaname
= "undefined";
struct PSAPaddr
* mydsaaddr
= NULLPA
;
struct PSAPaddr
* dsaladdr
= NULLPA
;
struct connection
* connlist
;
struct connection
* connwaitlist
;
struct di_block
* deferred_dis
= NULL_DI_BLOCK
;
struct oper_act
* get_edb_ops
;
extern char startup_update
;
char start_buf
[LINESIZE
];
* Function to stop DSA server.
if (myname
= rindex (argv
[0], '/'))
if (myname
== NULL
|| *myname
== NULL
)
dsa_sys_init(&argc
, &argv
);
print_parse_errors
= FALSE
;
ll_hdinit (log_stat
,myname
);
if ((opt
= ps_alloc (std_open
)) == NULLPS
)
fatal (-12,"ps_alloc failed");
if (std_setup (opt
,stdout
) == NOTOK
)
fatal (-13,"std_setup failed");
DLOG (log_dsap
,LLOG_DEBUG
,( "About to dsa_init()"));
fatal(-14,"Couldn't initialise the DSA!!");
fatal(-15,"Couldn't start the DSA!!");
/* Will generate a list of EDB operations! */
(void) sprintf (filebuf
, "%s/PID", treedir
);
if (fp
= fopen (filebuf
, "w")) {
(void) fprintf (fp
, "%d\n", getpid ());
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("Can't open PID file %s",filebuf
));
* Do stop_dsa() on receiving a Ctrl-C
(void) signal (SIGINT
, stop_dsa
);
(void) signal (SIGTERM
,stop_dsa
);
(void) signal (SIGHUP
, stop_dsa
);
/* now started don't stop on core dumps !!! */
(void) signal (SIGQUIT
, attempt_restart
);
(void) signal (SIGILL
, attempt_restart
);
(void) signal (SIGBUS
, attempt_restart
);
(void) signal (SIGSEGV
, attempt_restart
);
(void) signal (SIGSYS
, attempt_restart
);
(void) signal (SIGPIPE
, attempt_restart
);
(void) signal (SIGUSR1
, list_status
);
abort_vector
= attempt_restart
;
(void) sprintf (start_buf
,"DSA %s has started on %s",mydsaname
,
paddr2str(dsaladdr
,NULLNA
));
LLOG (log_dsap
,LLOG_NOTICE
,(start_buf
));
LLOG (log_stat
,LLOG_NOTICE
,(start_buf
));
(void) fprintf (stderr
,"%s\n",start_buf
);
start_malloc_trace (NULLCP
);
proc_size
= (unsigned) sbrk(0);
if((task
= task_select(&secs
)) == NULLTASK
)
/* Only if we are idle ! */
new_size
= (unsigned) sbrk(0);
if ( new_size
> proc_size
) {
LLOG (log_dsap
, LLOG_NOTICE
, ("Process grown by %d bytes", new_size
- proc_size
));
dsa_wait(secs
); /* Check network with timeout of secs */
dsa_work(task
); /* Process the DSA task selected */
struct DSAPindication di_s
;
struct DSAPindication
* di
= &di_s
;
for(cn
=connlist
; cn
!=NULLCONN
; cn
=cn
->cn_next
)
if (cn
-> cn_ad
!= NOTOK
) {
if (isfatal
|| (! cn
-> cn_initiator
))
(void) close (cn
-> cn_ad
);
(void) DUAbortRequest(cn
->cn_ad
, di
);
watch_dog ("stop_listeners");
(void) signal (sig
, SIG_DFL
); /* to stop recursion */
LLOG (log_dsap
,LLOG_FATAL
,("*** Stopping on signal %d ***",sig
));
(void) fprintf (stderr
,"DSA %s has Stopped\n",mydsaname
);
register struct connection
*cn
;
(void) signal (SIGUSR1
, list_status
);
for (fd
= getdtablesize () - 1; fd
>= 0; fd
--)
if (fstat (fd
, &st
) != NOTOK
)
LLOG (log_dsap
, LLOG_EXCEPTIONS
,
("fd %d: fmt=0%o", fd
, st
.st_mode
& S_IFMT
));
LLOG (log_dsap
, LLOG_EXCEPTIONS
, ("logs dsap=%d stat=%d",
log_dsap
-> ll_fd
, log_stat
-> ll_fd
));
LLOG (log_dsap
, LLOG_EXCEPTIONS
, ("logs dsap=%d", log_dsap
-> ll_fd
));
for (cn
= connlist
; cn
; cn
= cn
-> cn_next
)
if (cn
-> cn_ad
!= NOTOK
)
LLOG (log_dsap
, LLOG_EXCEPTIONS
,
("cn %d: init=%d used=%ld release=%ld",
cn
-> cn_ad
, cn
-> cn_initiator
,
(long) now
- cn
-> cn_last_used
,
(long) now
- cn
-> cn_last_release
));
nbits
= getdtablesize ();
if (!(debug
= isatty (2))) {
for (i
= 0; i
< 5; i
++) {
if ((sd
= open ("/dev/null", O_RDWR
)) == NOTOK
)
adios ("/dev/null", "unable to read");
(void) dup2 (sd
, 0), (void) close (sd
);
advise (LLOG_EXCEPTIONS
, "failed", "setsid");
if ((sd
= open ("/dev/tty", O_RDWR
)) != NOTOK
) {
(void) ioctl (sd
, TIOCNOTTY
, NULLCP
);
(void) signal (SIGINT
, SIG_IGN
);
(void) signal (SIGQUIT
, SIG_IGN
);
/* "Normal" ISODE behavior of full logging only without DEBUG */
ll_dbinit (log_dsap
, myname
);
#ifndef sun /* damn YP... */
for (sd
= 3; sd
< nbits
; sd
++) {
if (log_dsap
-> ll_fd
== sd
)
if (log_stats
-> ll_fd
== sd
)
(void) signal (SIGPIPE
, SIG_IGN
);
ll_hdinit (log_dsap
, myname
);
advise (LLOG_TRACE
, NULLCP
, "starting");
_ll_log (log_dsap
, LLOG_FATAL
, ap
);
(void) fprintf (stderr
,"adios exit - see dsap.log\n");
(void) _ll_log (log_dsap
, code
, ap
);
void advise (code
, what
, fmt
)
advise (code
, what
, fmt
);
(void) stat (treedir
,&buf
);
if (setgid (buf
.st_gid
) == -1)
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("Can't set gid %d (database directory \"%s\")",buf
.st_uid
,treedir
));
if (setuid (buf
.st_uid
) == -1)
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("Can't set uid %d (database directory \"%s\")",buf
.st_uid
,treedir
));
#define RESTART_TIME 30 /* for connections to clear... */
#define CLEAR_TIME 300 /* .. */
SFD
attempt_restart (sig
)
(void) signal (sig
, SIG_DFL
); /* to stop recursion */
(void) fprintf (stderr
,"DSA %s has a problem\n",mydsaname
);
secs
= sig
!= NOTOK
? CLEAR_TIME
: RESTART_TIME
;
for (sd
= 3; sd
< nbits
; sd
++) {
if (log_dsap
-> ll_fd
== sd
)
if (log_stats
-> ll_fd
== sd
)
if ( sig
== -2 || (fpid
= fork()) == 0) {
if (sig
== -2) { /* restart due to congestion... */
LLOG (log_dsap
,LLOG_FATAL
, ("*** in-situ restart attempted ***"));
LLOG (log_stat
,LLOG_NOTICE
,("RESTARTING (%s)",mydsaname
));
sleep (secs
); /* give connections time to clear */
(void) execv (isodefile(sargv
[0], 1),sargv
);
log_dsap
-> ll_syslog
= LLOG_FATAL
;
LLOG (log_dsap
,LLOG_FATAL
,("Quipu restart attempted in %d seconds (sig %d)", secs
,sig
));
LLOG (log_stat
,LLOG_NOTICE
,("RESTARTING with pid %d (%s)",fpid
,mydsaname
));
LLOG (log_stat
,LLOG_NOTICE
,("PANIC (%s)",mydsaname
));
LLOG (log_dsap
,LLOG_FATAL
,("Quipu aborting - sig (%d)",sig
));
(void) signal (SIGIOT
, SIG_DFL
);
exit (-20); /* abort should not return */