Ensure control socket is closed first, and wait for it to close.
This commit is contained in:
@@ -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)
|
||||
|
@@ -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 *);
|
||||
|
@@ -821,13 +821,20 @@ void serve_cleanup(struct server *params,
|
||||
|
||||
info("cleaning up");
|
||||
|
||||
if (params->server_fd) {
|
||||
close(params->server_fd);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* close the control socket too */
|
||||
if (params->flexnbd && params->flexnbd->control) {
|
||||
control_signal_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 */
|
||||
|
Reference in New Issue
Block a user