Commit 513ef596d43cc35a72ae21170075136855641493

Authored by David Teigland
1 parent af3a3ab296

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>

Showing 1 changed file with 20 additions and 8 deletions Side-by-side Diff

... ... @@ -142,6 +142,7 @@
142 142  
143 143 static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
144 144 static int dlm_local_count;
  145 +static int dlm_allow_conn;
145 146  
146 147 /* Work queues */
147 148 static struct workqueue_struct *recv_workqueue;
... ... @@ -710,6 +711,13 @@
710 711 struct connection *newcon;
711 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 721 memset(&peeraddr, 0, sizeof(peeraddr));
714 722 result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
715 723 IPPROTO_TCP, &newsock);
... ... @@ -1503,6 +1511,7 @@
1503 1511 socket activity.
1504 1512 */
1505 1513 mutex_lock(&connections_lock);
  1514 + dlm_allow_conn = 0;
1506 1515 foreach_conn(stop_conn);
1507 1516 mutex_unlock(&connections_lock);
1508 1517  
... ... @@ -1530,7 +1539,7 @@
1530 1539 if (!dlm_local_count) {
1531 1540 error = -ENOTCONN;
1532 1541 log_print("no local IP address has been set");
1533   - goto out;
  1542 + goto fail;
1534 1543 }
1535 1544  
1536 1545 error = -ENOMEM;
1537 1546  
... ... @@ -1538,8 +1547,14 @@
1538 1547 __alignof__(struct connection), 0,
1539 1548 NULL);
1540 1549 if (!con_cache)
1541   - goto out;
  1550 + goto fail;
1542 1551  
  1552 + error = work_start();
  1553 + if (error)
  1554 + goto fail_destroy;
  1555 +
  1556 + dlm_allow_conn = 1;
  1557 +
1543 1558 /* Start listening */
1544 1559 if (dlm_config.ci_protocol == 0)
1545 1560 error = tcp_listen_for_all();
1546 1561  
1547 1562  
1548 1563  
... ... @@ -1548,21 +1563,18 @@
1548 1563 if (error)
1549 1564 goto fail_unlisten;
1550 1565  
1551   - error = work_start();
1552   - if (error)
1553   - goto fail_unlisten;
1554   -
1555 1566 return 0;
1556 1567  
1557 1568 fail_unlisten:
  1569 + dlm_allow_conn = 0;
1558 1570 con = nodeid2con(0,0);
1559 1571 if (con) {
1560 1572 close_connection(con, false);
1561 1573 kmem_cache_free(con_cache, con);
1562 1574 }
  1575 +fail_destroy:
1563 1576 kmem_cache_destroy(con_cache);
1564   -
1565   -out:
  1577 +fail:
1566 1578 return error;
1567 1579 }