mirror of
https://github.com/troglobit/finit.git
synced 2026-10-08 08:24:43 +07:00
Fix v3.1 regression, segfault when inetd service connection exits
The service_step() function may call svc_del() on an svc from the service_monitor(), so we need a way to tell the latter that it no longer can dereference the pointer. This regression is limited to v3.1, due to the introduction of the new non-shared-memory store of svc_t. Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
+14
-6
@@ -786,11 +786,12 @@ void service_monitor(pid_t lost)
|
||||
|
||||
/* No longer running, update books. */
|
||||
svc->start_time = svc->pid = 0;
|
||||
service_step(svc);
|
||||
|
||||
/* Clean out any bootstrap tasks, they've had their time in the sun. */
|
||||
if (svc_clean_bootstrap(svc))
|
||||
_d("collected bootstrap task %s(%d), removing.", svc->cmd, lost);
|
||||
if (!service_step(svc)) {
|
||||
/* Clean out any bootstrap tasks, they've had their time in the sun. */
|
||||
if (svc_clean_bootstrap(svc))
|
||||
_d("collected bootstrap task %s(%d), removing.", svc->cmd, lost);
|
||||
}
|
||||
|
||||
sm_step(&sm);
|
||||
}
|
||||
@@ -841,7 +842,12 @@ static void svc_set_state(svc_t *svc, svc_state_t new)
|
||||
}
|
||||
}
|
||||
|
||||
void service_step(svc_t *svc)
|
||||
/*
|
||||
* Transition inetd/task/run/service
|
||||
*
|
||||
* Returns: non-zero if the @svc is no longer valid (removed)
|
||||
*/
|
||||
int service_step(svc_t *svc)
|
||||
{
|
||||
int err;
|
||||
char *restart_cnt = (char *)&svc->restart_cnt;
|
||||
@@ -871,7 +877,7 @@ restart:
|
||||
service_step(svc->inetd.svc);
|
||||
}
|
||||
service_unregister(svc);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (svc_is_changed(svc))
|
||||
@@ -1027,6 +1033,8 @@ restart:
|
||||
_d("%20s(%4d): -> %8s", svc->cmd, svc->pid, svc_status(svc));
|
||||
goto restart;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void service_step_all(int types)
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ void service_unregister (svc_t *svc);
|
||||
void service_runtask_clean (void);
|
||||
void service_reload_dynamic (void);
|
||||
|
||||
void service_step (svc_t *svc);
|
||||
int service_step (svc_t *svc);
|
||||
void service_step_all (int types);
|
||||
|
||||
void service_bootstrap_cb (uev_t *w, void *arg, int events);
|
||||
|
||||
@@ -205,7 +205,7 @@ svc_t *svc_job_iterator(svc_t **iter, int first, int job)
|
||||
* svc_foreach - Run a callback for each registered service
|
||||
* @cb: Callback to run for each service
|
||||
*/
|
||||
void svc_foreach(void (*cb)(svc_t *))
|
||||
void svc_foreach(int (*cb)(svc_t *))
|
||||
{
|
||||
svc_t *svc, *iter = NULL;
|
||||
|
||||
@@ -222,7 +222,7 @@ void svc_foreach(void (*cb)(svc_t *))
|
||||
* @types: Mask of service types
|
||||
* @cb: Callback to run for each matching type
|
||||
*/
|
||||
void svc_foreach_type(int types, void (*cb)(svc_t *))
|
||||
void svc_foreach_type(int types, int (*cb)(svc_t *))
|
||||
{
|
||||
svc_t *svc, *iter = NULL;
|
||||
|
||||
|
||||
@@ -142,8 +142,8 @@ svc_t *svc_inetd_iterator (svc_t **iter, int first);
|
||||
svc_t *svc_named_iterator (svc_t **iter, int first, char *cmd);
|
||||
svc_t *svc_job_iterator (svc_t **iter, int first, int job);
|
||||
|
||||
void svc_foreach (void (*cb)(svc_t *));
|
||||
void svc_foreach_type (int types, void (*cb)(svc_t *));
|
||||
void svc_foreach (int (*cb)(svc_t *));
|
||||
void svc_foreach_type (int types, int (*cb)(svc_t *));
|
||||
|
||||
svc_t *svc_stop_completed (void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user