Commit 513ef596d43cc35a72ae21170075136855641493
1 parent
af3a3ab296
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
fs/dlm/lowcomms.c
... | ... | @@ -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 | } |