2
* (c) Copyright 1992 by Panagiotis Tsirigotis
3
* (c) Sections Copyright 1998-2001 by Rob Braun
4
* All rights reserved. The file named COPYRIGHT specifies the terms
5
* and conditions for redistribution.
19
#include "connection.h"
25
static int retry_timer_running ;
26
static void cancel_retry(struct server * serp );
27
static void stop_retry_timer(void) ;
28
static void start_retry_timer(void) ;
32
* Attempt to start all servers in the retry table
34
static void server_retry(void)
36
unsigned servers_started = 0 ;
38
const char *func = "server_retry" ;
40
for ( u = 0 ; u < pset_count( RETRIES( ps ) ) ; u++ )
42
struct server *retry = SERP( pset_pointer( RETRIES( ps ), u ) ) ;
43
struct service *sp = SERVER_SERVICE( retry ) ;
44
connection_s *cp = SERVER_CONNECTION( retry ) ;
47
* Drop the retry if access control fails or we have
48
* a memory allocation problem
50
if ( svc_parent_access_control( sp, cp ) == FAILED ||
51
svc_child_access_control (sp, cp) == FAILED ||
52
pset_add( SERVERS( ps ), retry ) == NULL )
54
cancel_retry( retry ) ;
55
pset_pointer( RETRIES( ps ), u ) = NULL ;
59
if ( server_start( retry ) == OK )
62
SVC_DEC_RETRIES( sp ) ;
63
if ( !SVC_WAITS( sp ) )
65
pset_pointer( RETRIES( ps ), u ) = NULL ;
70
pset_remove( SERVERS( ps ), retry ) ;
71
if ( SERVER_FORKLIMIT( retry ) )
77
"service %s: too many consecutive fork failures", SVC_ID(sp) ) ;
78
svc_log_failure( sp, cp, AC_FORK ) ;
79
cancel_retry( retry ) ;
80
pset_pointer( RETRIES( ps ), u ) = NULL ;
87
"fork failed for service %s. Retrying...", SVC_ID( sp ) ) ;
92
pset_compact( RETRIES( ps ) ) ;
96
"%d servers started, %d left to retry",
97
servers_started, pset_count( RETRIES( ps ) ) ) ;
99
/* If there's more, start another callback */
100
if ( pset_count( RETRIES( ps ) ) > 0 ) {
101
if ((retry_timer_running=xtimer_add(server_retry, RETRY_INTERVAL)) == -1)
103
msg( LOG_ERR, func, "xtimer_add: %m" ) ;
104
retry_timer_running = 0;
108
retry_timer_running = 0;
113
* Schedule a retry by inserting the struct server in the retry table
114
* and starting the timer if necessary
116
status_e schedule_retry( struct server *serp )
118
struct service *sp = SERVER_SERVICE( serp ) ;
119
const char *func = "schedule_retry" ;
121
if ( pset_add( RETRIES( ps ), serp ) == NULL )
123
out_of_memory( func ) ;
126
SVC_INC_RETRIES( sp ) ;
127
start_retry_timer() ;
129
msg( LOG_DEBUG, func, "Scheduled retry attempt for %s", SVC_ID( sp ) ) ;
135
* This function should not be called for servers that correspond to
136
* services not in the service table because server_release will result
137
* in releasing all memory associated with the service (since the ref
138
* count will drop to 0).
140
static void cancel_retry( struct server *serp )
142
struct service *sp = SERVER_SERVICE( serp ) ;
144
conn_free( SERVER_CONNECTION( serp ), 1 ) ;
145
SVC_DEC_RETRIES( sp ) ;
146
server_release( serp ) ;
152
* Cancel all retry attempts for the specified service
154
void cancel_service_retries( struct service *sp )
157
const char *func = "cancel_service_retries" ;
159
if ( SVC_RETRIES( sp ) == 0 )
163
while ( u < pset_count( RETRIES( ps ) ) )
165
struct server *serp ;
167
serp = SERP( pset_pointer( RETRIES( ps ), u ) ) ;
168
if ( SERVER_SERVICE( serp ) == sp )
170
msg( LOG_NOTICE, func,
171
"dropping retry attempt for service %s", SVC_ID( sp ) ) ;
172
cancel_retry( serp ) ;
173
pset_remove_index( RETRIES( ps ), u ) ;
179
if ( pset_count( RETRIES( ps ) ) == 0 )
184
static void start_retry_timer(void)
186
const char *func = "start_retry_timer" ;
189
* Enable timer if necessary.
192
if ( retry_timer_running == 0 )
193
if((retry_timer_running=xtimer_add(server_retry, RETRY_INTERVAL)) == -1 ){
194
msg( LOG_ERR, func, "xtimer_add: %m" ) ;
195
retry_timer_running = 0;
200
static void stop_retry_timer(void)
202
if ( retry_timer_running != 0)
204
xtimer_remove(retry_timer_running);
205
retry_timer_running = 0 ;