internals.c (xinetd-2.3.15) | : | internals.c (xinetd-2.3.15.4.tar.xz) | ||
---|---|---|---|---|
skipping to change at line 54 | skipping to change at line 54 | |||
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) | for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) | |||
svc_dump( SP( pset_pointer( SERVICES( ps ), u ) ), fd ) ; | svc_dump( SP( pset_pointer( SERVICES( ps ), u ) ), fd ) ; | |||
} | } | |||
void dump_internal_state(void) | void dump_internal_state(void) | |||
{ | { | |||
int dump_fd ; | int dump_fd ; | |||
const char *dump_file = DUMP_FILE ; | const char *dump_file = DUMP_FILE ; | |||
time_t current_time ; | time_t current_time ; | |||
int fd ; | int fd ; | |||
#ifdef HAVE_POLL | ||||
int *listed_fds; | ||||
#endif | ||||
unsigned u ; | unsigned u ; | |||
const char *func = "dump_internal_state" ; | const char *func = "dump_internal_state" ; | |||
if ( debug.on ) | if ( debug.on ) | |||
msg( LOG_DEBUG, func, "Dumping State" ) ; | msg( LOG_DEBUG, func, "Dumping State" ) ; | |||
dump_fd = open( dump_file, O_WRONLY | O_CREAT | O_APPEND, DUMP_FILE_MODE); | dump_fd = open( dump_file, O_WRONLY | O_CREAT | O_APPEND, DUMP_FILE_MODE); | |||
if ( dump_fd == -1 ) | if ( dump_fd == -1 ) | |||
{ | { | |||
msg( LOG_ERR, func, "failed to open %s: %m", dump_file ) ; | msg( LOG_ERR, func, "failed to open %s: %m", dump_file ) ; | |||
skipping to change at line 105 | skipping to change at line 108 | |||
Sputchar( dump_fd, '\n' ) ; | Sputchar( dump_fd, '\n' ) ; | |||
/* | /* | |||
* Dump the retry_table | * Dump the retry_table | |||
*/ | */ | |||
Sprint( dump_fd, "Retry table dump:\n" ) ; | Sprint( dump_fd, "Retry table dump:\n" ) ; | |||
for ( u = 0 ; u < pset_count( RETRIES( ps ) ) ; u++ ) | for ( u = 0 ; u < pset_count( RETRIES( ps ) ) ; u++ ) | |||
server_dump( SERP( pset_pointer( RETRIES( ps ), u ) ), dump_fd ) ; | server_dump( SERP( pset_pointer( RETRIES( ps ), u ) ), dump_fd ) ; | |||
Sputchar( dump_fd, '\n' ) ; | Sputchar( dump_fd, '\n' ) ; | |||
#ifdef HAVE_POLL | ||||
/* | ||||
* Dump the socket mask | ||||
*/ | ||||
listed_fds = (int *)calloc(sizeof(int),ps.ros.max_descriptors); | ||||
if (listed_fds != NULL) | ||||
{ | ||||
Sprint( dump_fd, "Socket mask:" ) ; | ||||
for ( fd = 0 ; fd < ps.rws.pfds_last ; fd++ ) | ||||
{ | ||||
listed_fds[ps.rws.pfd_array[fd].fd] = 1; | ||||
Sprint( dump_fd, " %d", ps.rws.pfd_array[fd].fd ) ; | ||||
} | ||||
Sputchar( dump_fd, '\n' ) ; | ||||
Sprint( dump_fd, "pfds_last = %d\n", ps.rws.pfds_last ) ; | ||||
/* | ||||
* Dump the descriptors that are open and are *not* in the socket list | ||||
*/ | ||||
Sprint( dump_fd, "Open descriptors (not in socket mask):" ) ; | ||||
for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ ) | ||||
{ | ||||
struct stat st ; | ||||
if ( !listed_fds[fd] && fstat( fd, &st ) != -1 ) | ||||
Sprint( dump_fd, " %d", fd ) ; | ||||
} | ||||
Sputchar( dump_fd, '\n' ) ; | ||||
Sputchar( dump_fd, '\n' ) ; | ||||
free(listed_fds); | ||||
} | ||||
else | ||||
Sprint( dump_fd, "Could not dump open descriptors, not enough memory!\n" ); | ||||
#else /* !HAVE_POLL */ | ||||
/* | /* | |||
* Dump the socket mask | * Dump the socket mask | |||
*/ | */ | |||
Sprint( dump_fd, "Socket mask:" ) ; | Sprint( dump_fd, "Socket mask:" ) ; | |||
for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ ) | for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ ) | |||
if ( FD_ISSET( fd, &ps.rws.socket_mask ) ) | if ( FD_ISSET( fd, &ps.rws.socket_mask ) ) | |||
Sprint( dump_fd, " %d", fd ) ; | Sprint( dump_fd, " %d", fd ) ; | |||
Sputchar( dump_fd, '\n' ) ; | Sputchar( dump_fd, '\n' ) ; | |||
Sprint( dump_fd, "mask_max = %d\n", ps.rws.mask_max ) ; | Sprint( dump_fd, "mask_max = %d\n", ps.rws.mask_max ) ; | |||
skipping to change at line 131 | skipping to change at line 169 | |||
struct stat st ; | struct stat st ; | |||
if ( FD_ISSET( fd, &ps.rws.socket_mask ) ) | if ( FD_ISSET( fd, &ps.rws.socket_mask ) ) | |||
continue ; | continue ; | |||
if ( fstat( fd, &st ) == -1 ) | if ( fstat( fd, &st ) == -1 ) | |||
continue ; | continue ; | |||
Sprint( dump_fd, " %d", fd ) ; | Sprint( dump_fd, " %d", fd ) ; | |||
} | } | |||
Sputchar( dump_fd, '\n' ) ; | Sputchar( dump_fd, '\n' ) ; | |||
Sputchar( dump_fd, '\n' ) ; | Sputchar( dump_fd, '\n' ) ; | |||
#endif /* !HAVE_POLL */ | ||||
Sprint( dump_fd, "active_services = %d\n", ps.rws.active_services ) ; | 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, "available_services = %d\n", ps.rws.available_services ) ; | |||
Sprint( dump_fd, "descriptors_free = %d\n", ps.rws.descriptors_free ) ; | Sprint( dump_fd, "descriptors_free = %d\n", ps.rws.descriptors_free ) ; | |||
Sprint( dump_fd, "running_servers = %d\n", pset_count( SERVERS( ps ) ) ) ; | Sprint( dump_fd, "running_servers = %d\n", pset_count( SERVERS( ps ) ) ) ; | |||
Sprint( dump_fd, "Logging service = %s\n", | Sprint( dump_fd, "Logging service = %s\n", | |||
LOG_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ; | LOG_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ; | |||
Sputchar( dump_fd, '\n' ) ; | Sputchar( dump_fd, '\n' ) ; | |||
Sprint( dump_fd, "max_descriptors = %d\n", (int)ps.ros.max_descriptors ) ; | Sprint( dump_fd, "max_descriptors = %d\n", (int)ps.ros.max_descriptors ) ; | |||
skipping to change at line 161 | skipping to change at line 200 | |||
} | } | |||
/* | /* | |||
* Types of consistency checks | * Types of consistency checks | |||
*/ | */ | |||
enum check_type { PERIODIC, USER_REQUESTED } ; | enum check_type { PERIODIC, USER_REQUESTED } ; | |||
static void consistency_check( enum check_type type ) | static void consistency_check( enum check_type type ) | |||
{ | { | |||
int fd ; | int fd ; | |||
fd_set socket_mask_copy ; | ||||
unsigned u ; | unsigned u ; | |||
int errors ; | int errors ; | |||
unsigned total_running_servers = 0 ; | unsigned total_running_servers = 0 ; | |||
unsigned total_retry_servers = 0 ; | unsigned total_retry_servers = 0 ; | |||
unsigned error_count = 0 ; | unsigned error_count = 0 ; | |||
bool_int service_count_check_failed = FALSE ; | bool_int service_count_check_failed = FALSE ; | |||
const char *func = "consistency_check" ; | const char *func = "consistency_check" ; | |||
#ifdef HAVE_POLL | ||||
struct pollfd *pfd_array_copy = calloc(sizeof(struct pollfd), ps.rws.pfds_last | ||||
); | ||||
if (pfd_array_copy == NULL) | ||||
{ | ||||
msg( LOG_ERR, func, "Could not run consistency check! Not enough memory!\n" | ||||
) ; | ||||
return; | ||||
} | ||||
memcpy(pfd_array_copy, ps.rws.pfd_array, ps.rws.pfds_last*sizeof(struct pollfd | ||||
)); | ||||
#else /* !HAVE_POLL */ | ||||
fd_set socket_mask_copy ; | ||||
socket_mask_copy = ps.rws.socket_mask ; | socket_mask_copy = ps.rws.socket_mask ; | |||
#endif /* HAVE_POLL */ | ||||
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) | for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) | |||
{ | { | |||
register struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ; | register struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ; | |||
char *sid = SVC_ID( sp ) ; | char *sid = SVC_ID( sp ) ; | |||
unsigned running_servers ; | unsigned running_servers ; | |||
unsigned retry_servers ; | unsigned retry_servers ; | |||
error_count += refcount_check( sp, &running_servers, &retry_servers ) ; | error_count += refcount_check( sp, &running_servers, &retry_servers ) ; | |||
if ( SVC_IS_AVAILABLE( sp ) || SVC_IS_DISABLED ( sp ) ) | if ( SVC_IS_AVAILABLE( sp ) || SVC_IS_DISABLED ( sp ) ) | |||
{ | { | |||
/* | /* | |||
* In this case, there may be some servers running | * In this case, there may be some servers running | |||
*/ | */ | |||
#ifdef HAVE_POLL | ||||
if ( pfd_array_copy[ SVC_POLLFD_OFF( sp ) ].events ) | ||||
{ | ||||
if ( SVC_IS_DISABLED( sp ) ) | ||||
{ | ||||
msg( LOG_ERR, func, | ||||
"fd of disabled service %s still in socket mask", sid ) ; | ||||
error_count++ ; | ||||
} | ||||
pfd_array_copy[ SVC_POLLFD_OFF( sp ) ].events = 0; | ||||
} | ||||
#else /* !HAVE_POLL */ | ||||
if ( FD_ISSET( SVC_FD( sp ), &socket_mask_copy ) ) | if ( FD_ISSET( SVC_FD( sp ), &socket_mask_copy ) ) | |||
{ | { | |||
if ( SVC_IS_DISABLED( sp ) ) | if ( SVC_IS_DISABLED( sp ) ) | |||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"fd of disabled service %s still in socket mask", sid ) ; | "fd of disabled service %s still in socket mask", sid ) ; | |||
error_count++ ; | error_count++ ; | |||
} | } | |||
FD_CLR( SVC_FD( sp ), &socket_mask_copy ) ; | FD_CLR( SVC_FD( sp ), &socket_mask_copy ) ; | |||
} | } | |||
error_count += thread_check( sp, running_servers, retry_servers ) ; | #endif /* HAVE_POLL */ | |||
error_count += thread_check( sp, running_servers, retry_servers ) ; | ||||
errors = service_count_check( sp, running_servers, retry_servers ) ; | errors = service_count_check( sp, running_servers, retry_servers ) ; | |||
if ( ! errors && ! service_count_check_failed ) | if ( ! errors && ! service_count_check_failed ) | |||
{ | { | |||
total_retry_servers += retry_servers ; | total_retry_servers += retry_servers ; | |||
total_running_servers += running_servers ; | total_running_servers += running_servers ; | |||
} | } | |||
if ( errors ) | if ( errors ) | |||
{ | { | |||
service_count_check_failed = TRUE ; | service_count_check_failed = TRUE ; | |||
error_count += errors ; | error_count += errors ; | |||
skipping to change at line 247 | skipping to change at line 310 | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"total retry servers (%d) != number of retry servers (%d)", | "total retry servers (%d) != number of retry servers (%d)", | |||
total_retry_servers, pset_count( RETRIES( ps ) ) ) ; | total_retry_servers, pset_count( RETRIES( ps ) ) ) ; | |||
error_count++ ; | error_count++ ; | |||
} | } | |||
} | } | |||
/* | /* | |||
* Check if there are any descriptors set in socket_mask_copy | * Check if there are any descriptors set in socket_mask_copy | |||
*/ | */ | |||
#ifdef HAVE_POLL | ||||
for ( fd = 0 ; fd < ps.rws.pfds_last ; fd++) | ||||
if ( pfd_array_copy[fd].events && pfd_array_copy[fd].fd != signals_pending[ | ||||
0] && | ||||
pfd_array_copy[fd].fd != signals_pending[1] ) | ||||
{ | ||||
msg( LOG_ERR, func, | ||||
"descriptor %d set in socket mask but there is no service for it", | ||||
fd ) ; | ||||
error_count++ ; | ||||
} | ||||
free(pfd_array_copy); | ||||
#else /* !HAVE_POLL */ | ||||
for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ ) | for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ ) | |||
if ( FD_ISSET( fd, &socket_mask_copy ) && ((fd != signals_pending[0]) && f d != signals_pending[1])) | if ( FD_ISSET( fd, &socket_mask_copy ) && ((fd != signals_pending[0]) && f d != signals_pending[1])) | |||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"descriptor %d set in socket mask but there is no service for it", | "descriptor %d set in socket mask but there is no service for it", | |||
fd ) ; | fd ) ; | |||
error_count++ ; | error_count++ ; | |||
} | } | |||
#endif /* !HAVE_POLL */ | ||||
if ( error_count != 0 ) | if ( error_count != 0 ) | |||
msg( LOG_WARNING, func, | msg( LOG_WARNING, func, | |||
"Consistency check detected %d errors", error_count ) ; | "Consistency check detected %d errors", error_count ) ; | |||
else | else | |||
if ( type == USER_REQUESTED || debug.on ) | if ( type == USER_REQUESTED || debug.on ) | |||
msg( LOG_INFO, func, "Consistency check passed" ) ; | msg( LOG_INFO, func, "Consistency check passed" ) ; | |||
if( type == PERIODIC ) | if( type == PERIODIC ) | |||
if ( xtimer_add( periodic_check, ps.ros.cc_interval ) == -1 ) | if ( xtimer_add( periodic_check, ps.ros.cc_interval ) == -1 ) | |||
skipping to change at line 313 | skipping to change at line 389 | |||
* if the descriptor is set in the socket mask, there must | * if the descriptor is set in the socket mask, there must | |||
* be a server running (or to be retried) | * be a server running (or to be retried) | |||
* If the service is multi-threaded: | * If the service is multi-threaded: | |||
* the descriptor must be always set | * the descriptor must be always set | |||
*/ | */ | |||
static unsigned thread_check( struct service *sp, | static unsigned thread_check( struct service *sp, | |||
unsigned running_servers, | unsigned running_servers, | |||
unsigned retry_servers ) | unsigned retry_servers ) | |||
{ | { | |||
unsigned error_count = 0 ; | unsigned error_count = 0 ; | |||
#ifdef HAVE_POLL | ||||
struct pollfd *pfd= SVC_POLLFD( sp ) ; | ||||
#else | ||||
int sd = SVC_FD( sp ) ; | int sd = SVC_FD( sp ) ; | |||
#endif | ||||
char *sid = SVC_ID( sp ) ; | char *sid = SVC_ID( sp ) ; | |||
const char *func = "thread_check" ; | const char *func = "thread_check" ; | |||
if ( SVC_WAITS( sp ) ) | if ( SVC_WAITS( sp ) ) | |||
{ | { | |||
bool_int has_servers = ( running_servers + retry_servers != 0 ) ; | bool_int has_servers = ( running_servers + retry_servers != 0 ) ; | |||
#ifdef HAVE_POLL | ||||
if ( has_servers && pfd->events ) | ||||
#else | ||||
if ( has_servers && FD_ISSET( sd, &ps.rws.socket_mask ) ) | if ( has_servers && FD_ISSET( sd, &ps.rws.socket_mask ) ) | |||
#endif | ||||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"Active single-threaded service %s: server running, descriptor set", sid ) ; | "Active single-threaded service %s: server running, descriptor set", sid ) ; | |||
error_count++ ; | error_count++ ; | |||
} | } | |||
#ifdef HAVE_POLL | ||||
if ( !has_servers && !pfd->events ) | ||||
#else | ||||
if ( !has_servers && !FD_ISSET( sd, &ps.rws.socket_mask ) ) | if ( !has_servers && !FD_ISSET( sd, &ps.rws.socket_mask ) ) | |||
#endif | ||||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"Active single-threaded service %s: no server running, descriptor not set", | "Active single-threaded service %s: no server running, descriptor not set", | |||
sid ) ; | sid ) ; | |||
error_count++ ; | error_count++ ; | |||
} | } | |||
} | } | |||
else | else | |||
#ifdef HAVE_POLL | ||||
if ( ! pfd->events ) | ||||
#else | ||||
if ( ! FD_ISSET( sd, &ps.rws.socket_mask ) ) | if ( ! FD_ISSET( sd, &ps.rws.socket_mask ) ) | |||
#endif | ||||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"Active multi-threaded service %s: descriptor not set", sid ) ; | "Active multi-threaded service %s: descriptor not set", sid ) ; | |||
error_count++ ; | error_count++ ; | |||
} | } | |||
if ( error_count && debug.on ) | if ( error_count && debug.on ) | |||
msg( LOG_DEBUG, func, "%s: %d errors detected", sid, error_count ) ; | msg( LOG_DEBUG, func, "%s: %d errors detected", sid, error_count ) ; | |||
return( error_count ) ; | return( error_count ) ; | |||
End of changes. 20 change blocks. | ||||
2 lines changed or deleted | 98 lines changed or added |