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:
Joachim Nilsson
2018-01-10 02:10:14 +01:00
parent 89a9d92d6c
commit 68ef6ec108
4 changed files with 19 additions and 11 deletions
+14 -6
View File
@@ -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
View File
@@ -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);
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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);