home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1992 by Panagiotis Tsirigotis
- * All rights reserved. The file named COPYRIGHT specifies the terms
- * and conditions for redistribution.
- */
-
- static char RCSid[] = "$Id: internals.c,v 5.1 1992/11/01 00:01:21 panos Exp $" ;
-
- #include <sys/types.h>
- #include <signal.h>
- #include <time.h>
- #include <fcntl.h>
- #include <syslog.h>
-
- #include "sio.h"
-
- #include "config.h"
- #include "service.h"
- #include "server.h"
- #include "state.h"
- #include "conf.h"
-
- extern char program_version[] ;
-
- void msg() ;
-
- time_t time() ;
-
- void dump_internal_state()
- {
- int dump_fd ;
- char *dump_file = DUMP_FILE ;
- time_t current_time ;
- register int fd ;
- register unsigned u ;
- char *func = "dump_internal_state" ;
-
- dump_fd = open( dump_file, O_WRONLY + O_CREAT + O_APPEND, DUMP_FILE_MODE ) ;
- if ( dump_fd == -1 )
- {
- msg( LOG_ERR, func, "failed to open %s: %m", dump_file ) ;
- return ;
- }
- Sbuftype( dump_fd, SIO_LINEBUF ) ;
-
- /*
- * Print the program name, version, and timestamp.
- * Note that the program_version variable contains the program name.
- */
- (void) time( ¤t_time ) ;
- Sprint( dump_fd, "INTERNAL STATE DUMP: %s\n", program_version ) ;
- Sprint( dump_fd, "Current time: %s\n", ctime( ¤t_time ) ) ;
-
- /*
- * Dump the current configuration (services + defaults)
- */
- Sprint( dump_fd, "Services + defaults:\n" ) ;
- dump_current_configuration( dump_fd ) ;
-
- /*
- * Dump the server table
- */
- Sprint( dump_fd, "Server table dump:\n" ) ;
- for ( u = 0 ; u < pset_count( ps.rws.servers ) ; u++ )
- server_dump( SERP( pset_pointer( ps.rws.servers, u ) ), dump_fd ) ;
- Sputchar( dump_fd, '\n' ) ;
-
- /*
- * Dump the retry_table
- */
- Sprint( dump_fd, "Retry table dump:\n" ) ;
- for ( u = 0 ; u < pset_count( ps.rws.retries ) ; u++ )
- server_dump( SERP( pset_pointer( ps.rws.retries, u ) ), dump_fd ) ;
- Sputchar( dump_fd, '\n' ) ;
-
- /*
- * Dump the socket mask
- */
- Sprint( dump_fd, "Socket mask:" ) ;
- for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ )
- if ( FD_ISSET( fd, &ps.rws.socket_mask ) )
- Sprint( dump_fd, " %d", fd ) ;
- Sputchar( dump_fd, '\n' ) ;
- Sprint( dump_fd, "mask_max = %d\n", ps.rws.mask_max ) ;
- Sputchar( dump_fd, '\n' ) ;
-
- Sprint( dump_fd, "active_services = %d\n", ps.rws.active_services ) ;
- Sprint( dump_fd, "available_services = %d\n", ps.rws.available_services ) ;
- Sprint( dump_fd, "descriptors_free = %d\n", ps.rws.descriptors_free ) ;
- Sprint( dump_fd, "running_servers = %d\n", pset_count( ps.rws.servers ) ) ;
- Sprint( dump_fd, "Logging service = %s\n",
- LOG_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ;
- Sprint( dump_fd, "Shutdown service = %s\n",
- SHUTDOWN_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ;
- Sputchar( dump_fd, '\n' ) ;
-
- Sprint( dump_fd, "max_descriptors = %d\n", ps.ros.max_descriptors ) ;
- Sprint( dump_fd, "process_limit = %d\n", ps.ros.process_limit ) ;
- Sprint( dump_fd, "config_file = %s\n", ps.ros.config_file ) ;
- if ( debug.on )
- Sprint( dump_fd, "debug_fd = %d\n", debug.fd ) ;
- Sputchar( dump_fd, '\n' ) ;
-
- Sprint( dump_fd, "END OF DUMP\n\n" ) ;
- Sclose( dump_fd ) ;
-
- msg( LOG_INFO, func, "generated state dump in file %s", dump_file ) ;
- }
-
-
-
-
- void consistency_check()
- {
- register int fd ;
- fd_set socket_mask_copy ;
- register unsigned u ;
- unsigned total_running_servers = 0 ;
- unsigned total_retry_servers = 0 ;
- unsigned error_count = 0 ;
- int errors ;
- bool_int service_count_check_failed = FALSE ;
- char *func = "consistency_check" ;
- unsigned thread_check() ;
- unsigned get_server_count() ;
-
- socket_mask_copy = ps.rws.socket_mask ;
-
- for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
- {
- register struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
- register struct service_data *sdp = SDATA( sp ) ;
- struct service_config *scp = CONF( sp ) ;
- unsigned running_servers = get_server_count( ps.rws.servers, sp ) ;
- unsigned retry_servers = get_server_count( ps.rws.retries, sp ) ;
-
- switch ( sp->state )
- {
- case SVC_NOT_STARTED:
- msg( LOG_ERR, func, "service %s not started", scp->id ) ;
- error_count++ ;
- break ;
-
- case SVC_ACTIVE:
- case SVC_DISABLED:
- FD_CLR( sdp->service_fd, &socket_mask_copy ) ;
- error_count += thread_check( sp, running_servers, retry_servers ) ;
-
- errors = service_count_check( sp, running_servers, retry_servers ) ;
- if ( ! errors && ! service_count_check_failed )
- {
- total_retry_servers += retry_servers ;
- total_running_servers += running_servers ;
- }
- if ( errors )
- {
- service_count_check_failed = TRUE ;
- error_count += errors ;
- }
-
- if ( sp->state == SVC_DISABLED && sdp->running_servers == 0 )
- {
- msg( LOG_ERR, func,
- "disabled service %s has 0 running servers\n", scp->id ) ;
- error_count++ ;
- continue ;
- }
- break ;
-
- default:
- msg( LOG_ERR, func,
- "bad state for service %s: %d", scp->id, (int)sp->state ) ;
- error_count++ ;
- }
- }
-
- if ( ! service_count_check_failed )
- {
- if ( total_running_servers != pset_count( ps.rws.servers ) )
- {
- msg( LOG_ERR, func,
- "total running servers (%d) != number of running servers (%d)",
- total_running_servers, pset_count( ps.rws.servers ) ) ;
- error_count++ ;
- }
- if ( total_retry_servers != pset_count( ps.rws.retries ) )
- {
- msg( LOG_ERR, func,
- "total retry servers (%d) != number of retry servers (%d)",
- total_retry_servers, pset_count( ps.rws.retries ) ) ;
- error_count++ ;
- }
- }
-
- /*
- * Check if there are any descriptors set in socket_mask_copy
- */
- for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ )
- if ( FD_ISSET( fd, &socket_mask_copy ) )
- {
- msg( LOG_ERR, func,
- "descriptor %d set in socket mask but there is no service for it",
- fd ) ;
- error_count++ ;
- }
-
- if ( error_count == 0 )
- msg( LOG_INFO, func, "Consistency check passed" ) ;
- else
- msg( LOG_INFO, func,
- "Consistency check detected %d errors", error_count ) ;
- }
-
-
- PRIVATE int service_count_check( sp, running_servers, retry_servers )
- register
- struct service *sp ;
- unsigned running_servers ;
- unsigned retry_servers ;
- {
- register struct service_data *sdp = SDATA( sp ) ;
- register char *sid = CONF( sp )->id ;
- int error_count = 0 ;
- char *func = "service_count_check" ;
-
- if ( sdp->running_servers != running_servers )
- {
- msg( LOG_ERR, func,
- "service %s: actual running servers = %d, known running servers = %d",
- sid, running_servers, sdp->running_servers ) ;
- error_count++ ;
- }
- if ( sdp->retry_servers != retry_servers )
- {
- msg( LOG_ERR, func,
- "service %s: actual retry servers = %d, known retry servers = %d",
- sid, retry_servers, sdp->retry_servers ) ;
- error_count++ ;
- }
- return( error_count ) ;
- }
-
-
-
- /*
- * If the service is single-threaded:
- * if the descriptor is set in the socket mask, there must
- * be a server running (or to be retried)
- * If the service is multi-threaded:
- * the descriptor must be always set
- */
- PRIVATE unsigned thread_check( sp, running_servers, retry_servers )
- struct service *sp ;
- unsigned running_servers ;
- unsigned retry_servers ;
- {
- struct service_config *scp = CONF( sp ) ;
- struct service_data *sdp = SDATA( sp ) ;
- unsigned error_count = 0 ;
- char *func = "thread_check" ;
-
- if ( scp->wait == YES )
- {
- bool_int has_servers = ( running_servers + retry_servers > 0 ) ;
-
- if ( has_servers && FD_ISSET( sdp->service_fd, &ps.rws.socket_mask ) )
- {
- msg( LOG_ERR, func,
- "Active single-threaded service %s: server running, descriptor set",
- scp->id ) ;
- error_count++ ;
- }
- if ( !has_servers && !FD_ISSET( sdp->service_fd, &ps.rws.socket_mask ) )
- {
- msg( LOG_ERR, func,
- "Active single-threaded service %s: no server running, descriptor not set",
- scp->id ) ;
- error_count++ ;
- }
- }
- else
- if ( ! FD_ISSET( sdp->service_fd, &ps.rws.socket_mask ) )
- {
- msg( LOG_ERR, func,
- "Active multi-threaded service %s: descriptor not set", scp->id ) ;
- error_count++ ;
- }
- return( error_count ) ;
- }
-
-
-
- /*
- * Count the number of servers for the specified service.
- */
- PRIVATE unsigned get_server_count( servers, sp )
- pset_h servers ;
- register struct service *sp ;
- {
- register unsigned u ;
- register unsigned count = 0 ;
-
- for ( u = 0 ; u < pset_count( servers ) ; u++ )
- if ( SERP( pset_pointer( servers, u ) )->sp == sp )
- count++ ;
- return( count ) ;
- }
-
-