Ensure control socket is closed first, and wait for it to close.

This commit is contained in:
Patrick J Cherry
2018-12-07 16:32:58 +00:00
parent 5839a36ab1
commit 842e7d362d
3 changed files with 22 additions and 6 deletions

View File

@@ -78,6 +78,14 @@ void control_destroy(struct control *control)
free(control); free(control);
} }
void control_wait_for_close(struct control *control)
{
NULLCHECK(control);
while (!fd_is_closed(control->control_fd)) {
usleep(10000);
}
}
struct control_client *control_client_create(struct flexnbd *flexnbd, struct control_client *control_client_create(struct flexnbd *flexnbd,
int client_fd, int client_fd,
struct mbox *state_mbox) struct mbox *state_mbox)

View File

@@ -47,6 +47,7 @@ struct control_client {
struct control *control_create(struct flexnbd *, struct control *control_create(struct flexnbd *,
const char *control_socket_name); const char *control_socket_name);
void control_signal_close(struct control *); void control_signal_close(struct control *);
void control_wait_for_close(struct control *control);
void control_destroy(struct control *); void control_destroy(struct control *);
void *control_runner(void *); void *control_runner(void *);

View File

@@ -820,14 +820,21 @@ void serve_cleanup(struct server *params,
void *status; void *status;
info("cleaning up"); info("cleaning up");
if (params->server_fd) { /* Close the control socket, and wait for it to close before proceeding.
close(params->server_fd); * If we do not wait, we risk a race condition with the tail supervisor
} * sending a status command, and deadlocking the mirroring. */
/* close the control socket too */
if (params->flexnbd && params->flexnbd->control) { if (params->flexnbd && params->flexnbd->control) {
debug("closing control socket");
control_signal_close(params->flexnbd->control); control_signal_close(params->flexnbd->control);
debug("waiting for control socket to close");
control_wait_for_close(params->flexnbd->control);
}
if (params->server_fd) {
debug("closing server_fd");
close(params->server_fd);
} }
/* need to stop background build if we're killed very early on */ /* need to stop background build if we're killed very early on */