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 ;