diff --git a/include/haproxy/mworker.h b/include/haproxy/mworker.h index 0e166ac09..09d6d587e 100644 --- a/include/haproxy/mworker.h +++ b/include/haproxy/mworker.h @@ -42,5 +42,6 @@ int mworker_ext_launch_all(void); void mworker_kill_max_reloads(int sig); void mworker_free_child(struct mworker_proc *); +void mworker_cleanup_proc(); #endif /* _HAPROXY_MWORKER_H_ */ diff --git a/src/haproxy.c b/src/haproxy.c index 601387535..70ce708f3 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -673,6 +673,7 @@ static void mworker_reexec() #endif setenv("HAPROXY_MWORKER_REEXEC", "1", 1); + mworker_cleanup_proc(); mworker_proc_list_to_env(); /* put the children description in the env */ /* ensure that we close correctly every listeners before reexecuting */ diff --git a/src/mworker.c b/src/mworker.c index 8b0b06ba0..fa3c1a25d 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -457,6 +457,36 @@ void mworker_cleanlisteners() } } +/* Upon a configuration loading error some mworker_proc and FDs/server were + * assigned but the worker was never forked, we must close the FDs and + * remove the server + */ +void mworker_cleanup_proc() +{ + struct mworker_proc *child, *it; + + list_for_each_entry_safe(child, it, &proc_list, list) { + + if (child->pid == -1) { + /* Close the socketpair master side. We don't need to + * close the worker side, because it's stored in the + * GLOBAL cli listener which was supposed to be in the + * worker and which will be closed in + * mworker_cleanlisteners() + */ + if (child->ipc_fd[0] > -1) + close(child->ipc_fd[0]); + if (child->srv) { + /* only exists if we created a master CLI listener */ + srv_drop(child->srv); + } + LIST_DELETE(&child->list); + mworker_free_child(child); + } + } +} + + /* Displays workers and processes */ static int cli_io_handler_show_proc(struct appctx *appctx) {