aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2012-03-30 12:46:08 -0400
committerDavid Teigland <teigland@redhat.com>2012-04-26 16:35:38 -0400
commit513ef596d43cc35a72ae21170075136855641493 (patch)
tree89a73567803e4cdc910849af388a934923625345 /fs/dlm
parentaf3a3ab2966112c0d0a44df7eeb1e95fe32d4495 (diff)
dlm: prevent connections during shutdown
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>
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/lowcomms.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 133ef6dc7cb7..5c1b0e38c7a4 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -142,6 +142,7 @@ struct writequeue_entry {
142 142
143static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT]; 143static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
144static int dlm_local_count; 144static int dlm_local_count;
145static int dlm_allow_conn;
145 146
146/* Work queues */ 147/* Work queues */
147static struct workqueue_struct *recv_workqueue; 148static struct workqueue_struct *recv_workqueue;
@@ -710,6 +711,13 @@ static int tcp_accept_from_sock(struct connection *con)
710 struct connection *newcon; 711 struct connection *newcon;
711 struct connection *addcon; 712 struct connection *addcon;
712 713
714 mutex_lock(&connections_lock);
715 if (!dlm_allow_conn) {
716 mutex_unlock(&connections_lock);
717 return -1;
718 }
719 mutex_unlock(&connections_lock);
720
713 memset(&peeraddr, 0, sizeof(peeraddr)); 721 memset(&peeraddr, 0, sizeof(peeraddr));
714 result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM, 722 result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
715 IPPROTO_TCP, &newsock); 723 IPPROTO_TCP, &newsock);
@@ -1503,6 +1511,7 @@ void dlm_lowcomms_stop(void)
1503 socket activity. 1511 socket activity.
1504 */ 1512 */
1505 mutex_lock(&connections_lock); 1513 mutex_lock(&connections_lock);
1514 dlm_allow_conn = 0;
1506 foreach_conn(stop_conn); 1515 foreach_conn(stop_conn);
1507 mutex_unlock(&connections_lock); 1516 mutex_unlock(&connections_lock);
1508 1517
@@ -1530,7 +1539,7 @@ int dlm_lowcomms_start(void)
1530 if (!dlm_local_count) { 1539 if (!dlm_local_count) {
1531 error = -ENOTCONN; 1540 error = -ENOTCONN;
1532 log_print("no local IP address has been set"); 1541 log_print("no local IP address has been set");
1533 goto out; 1542 goto fail;
1534 } 1543 }
1535 1544
1536 error = -ENOMEM; 1545 error = -ENOMEM;
@@ -1538,7 +1547,13 @@ int dlm_lowcomms_start(void)
1538 __alignof__(struct connection), 0, 1547 __alignof__(struct connection), 0,
1539 NULL); 1548 NULL);
1540 if (!con_cache) 1549 if (!con_cache)
1541 goto out; 1550 goto fail;
1551
1552 error = work_start();
1553 if (error)
1554 goto fail_destroy;
1555
1556 dlm_allow_conn = 1;
1542 1557
1543 /* Start listening */ 1558 /* Start listening */
1544 if (dlm_config.ci_protocol == 0) 1559 if (dlm_config.ci_protocol == 0)
@@ -1548,20 +1563,17 @@ int dlm_lowcomms_start(void)
1548 if (error) 1563 if (error)
1549 goto fail_unlisten; 1564 goto fail_unlisten;
1550 1565
1551 error = work_start();
1552 if (error)
1553 goto fail_unlisten;
1554
1555 return 0; 1566 return 0;
1556 1567
1557fail_unlisten: 1568fail_unlisten:
1569 dlm_allow_conn = 0;
1558 con = nodeid2con(0,0); 1570 con = nodeid2con(0,0);
1559 if (con) { 1571 if (con) {
1560 close_connection(con, false); 1572 close_connection(con, false);
1561 kmem_cache_free(con_cache, con); 1573 kmem_cache_free(con_cache, con);
1562 } 1574 }
1575fail_destroy:
1563 kmem_cache_destroy(con_cache); 1576 kmem_cache_destroy(con_cache);
1564 1577fail:
1565out:
1566 return error; 1578 return error;
1567} 1579}