Skip to content

Commit

Permalink
dlm: prevent connections during shutdown
Browse files Browse the repository at this point in the history
During lowcomms shutdown, a new connection could possibly
be created, and attempt to use a workqueue that's been
destroyed.  Similarly, during startup, a new connection
could attempt to use a workqueue that's not been set up
yet.  Add a global variable to indicate when new connections
are allowed.

Based on patch by: Christine Caulfield <ccaulfie@redhat.com>

Reported-by: dann frazier <dann.frazier@canonical.com>
Reviewed-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: David Teigland <teigland@redhat.com>
  • Loading branch information
teigland committed Apr 26, 2012
1 parent af3a3ab commit 513ef59
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions fs/dlm/lowcomms.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ struct writequeue_entry {

static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
static int dlm_local_count;
static int dlm_allow_conn;

/* Work queues */
static struct workqueue_struct *recv_workqueue;
Expand Down Expand Up @@ -710,6 +711,13 @@ static int tcp_accept_from_sock(struct connection *con)
struct connection *newcon;
struct connection *addcon;

mutex_lock(&connections_lock);
if (!dlm_allow_conn) {
mutex_unlock(&connections_lock);
return -1;
}
mutex_unlock(&connections_lock);

memset(&peeraddr, 0, sizeof(peeraddr));
result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
IPPROTO_TCP, &newsock);
Expand Down Expand Up @@ -1503,6 +1511,7 @@ void dlm_lowcomms_stop(void)
socket activity.
*/
mutex_lock(&connections_lock);
dlm_allow_conn = 0;
foreach_conn(stop_conn);
mutex_unlock(&connections_lock);

Expand Down Expand Up @@ -1530,15 +1539,21 @@ int dlm_lowcomms_start(void)
if (!dlm_local_count) {
error = -ENOTCONN;
log_print("no local IP address has been set");
goto out;
goto fail;
}

error = -ENOMEM;
con_cache = kmem_cache_create("dlm_conn", sizeof(struct connection),
__alignof__(struct connection), 0,
NULL);
if (!con_cache)
goto out;
goto fail;

error = work_start();
if (error)
goto fail_destroy;

dlm_allow_conn = 1;

/* Start listening */
if (dlm_config.ci_protocol == 0)
Expand All @@ -1548,20 +1563,17 @@ int dlm_lowcomms_start(void)
if (error)
goto fail_unlisten;

error = work_start();
if (error)
goto fail_unlisten;

return 0;

fail_unlisten:
dlm_allow_conn = 0;
con = nodeid2con(0,0);
if (con) {
close_connection(con, false);
kmem_cache_free(con_cache, con);
}
fail_destroy:
kmem_cache_destroy(con_cache);

out:
fail:
return error;
}

0 comments on commit 513ef59

Please sign in to comment.