From 842e7d362d0c6231ba71341b07b51dc5cdcc0914 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Fri, 7 Dec 2018 16:32:58 +0000 Subject: [PATCH] Ensure control socket is closed first, and wait for it to close. --- src/server/control.c | 8 ++++++++ src/server/control.h | 1 + src/server/serve.c | 19 +++++++++++++------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/server/control.c b/src/server/control.c index 394854e..51e58e9 100644 --- a/src/server/control.c +++ b/src/server/control.c @@ -78,6 +78,14 @@ void control_destroy(struct control *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, int client_fd, struct mbox *state_mbox) diff --git a/src/server/control.h b/src/server/control.h index 017611d..551265f 100644 --- a/src/server/control.h +++ b/src/server/control.h @@ -47,6 +47,7 @@ struct control_client { struct control *control_create(struct flexnbd *, const char *control_socket_name); void control_signal_close(struct control *); +void control_wait_for_close(struct control *control); void control_destroy(struct control *); void *control_runner(void *); diff --git a/src/server/serve.c b/src/server/serve.c index 28970aa..c262189 100644 --- a/src/server/serve.c +++ b/src/server/serve.c @@ -820,14 +820,21 @@ void serve_cleanup(struct server *params, void *status; info("cleaning up"); - - if (params->server_fd) { - close(params->server_fd); - } - - /* close the control socket too */ + + /* Close the control socket, and wait for it to close before proceeding. + * If we do not wait, we risk a race condition with the tail supervisor + * sending a status command, and deadlocking the mirroring. */ if (params->flexnbd && params->flexnbd->control) { + debug("closing control socket"); 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 */