summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Klishin <klishinm@vmware.com>2021-08-19 18:52:33 +0300
committerGitHub <noreply@github.com>2021-08-19 18:52:33 +0300
commit416953173d9e88f09f100d1e9556df49aa85433c (patch)
treee6f08b97f27e7fe45a453cc6099e085b8e3eeac7
parent074a567dfd00f7c70fc3aa79fca7ec3d63742aee (diff)
parent0b1942bdc0938cb6018ef0e8eede164a0d4e4644 (diff)
downloadrabbitmq-server-git-416953173d9e88f09f100d1e9556df49aa85433c.tar.gz
Merge pull request #3324 from rabbitmq/fix-race-condition-in-connection-channel-tracking-list-function
rabbit_{connection,channel}_tracking: Fix race condition in list()
-rw-r--r--deps/rabbit/src/rabbit_channel_tracking.erl13
-rw-r--r--deps/rabbit/src/rabbit_connection_tracking.erl16
2 files changed, 27 insertions, 2 deletions
diff --git a/deps/rabbit/src/rabbit_channel_tracking.erl b/deps/rabbit/src/rabbit_channel_tracking.erl
index dc93cd9afa..106e95cf1e 100644
--- a/deps/rabbit/src/rabbit_channel_tracking.erl
+++ b/deps/rabbit/src/rabbit_channel_tracking.erl
@@ -179,7 +179,18 @@ list() ->
lists:foldl(
fun (Node, Acc) ->
Tab = tracked_channel_table_name_for(Node),
- Acc ++ mnesia:dirty_match_object(Tab, #tracked_channel{_ = '_'})
+ try
+ Acc ++
+ mnesia:dirty_match_object(Tab, #tracked_channel{_ = '_'})
+ catch
+ exit:{aborted, {no_exists, [Tab, _]}} ->
+ %% The table might not exist yet (or is already gone)
+ %% between the time rabbit_nodes:all_running() runs and
+ %% returns a specific node, and
+ %% mnesia:dirty_match_object() is called for that node's
+ %% table.
+ Acc
+ end
end, [], rabbit_nodes:all_running()).
-spec list_of_user(rabbit_types:username()) -> [rabbit_types:tracked_channel()].
diff --git a/deps/rabbit/src/rabbit_connection_tracking.erl b/deps/rabbit/src/rabbit_connection_tracking.erl
index 7213f10645..2ec96e621f 100644
--- a/deps/rabbit/src/rabbit_connection_tracking.erl
+++ b/deps/rabbit/src/rabbit_connection_tracking.erl
@@ -351,7 +351,18 @@ list() ->
lists:foldl(
fun (Node, Acc) ->
Tab = tracked_connection_table_name_for(Node),
- Acc ++ mnesia:dirty_match_object(Tab, #tracked_connection{_ = '_'})
+ try
+ Acc ++
+ mnesia:dirty_match_object(Tab, #tracked_connection{_ = '_'})
+ catch
+ exit:{aborted, {no_exists, [Tab, _]}} ->
+ %% The table might not exist yet (or is already gone)
+ %% between the time rabbit_nodes:all_running() runs and
+ %% returns a specific node, and
+ %% mnesia:dirty_match_object() is called for that node's
+ %% table.
+ Acc
+ end
end, [], rabbit_nodes:all_running()).
-spec count() -> non_neg_integer().
@@ -360,6 +371,9 @@ count() ->
lists:foldl(
fun (Node, Acc) ->
Tab = tracked_connection_table_name_for(Node),
+ %% mnesia:table_info() returns 0 if the table doesn't exist. We
+ %% don't need the same kind of protection as the list() function
+ %% above.
Acc + mnesia:table_info(Tab, size)
end, 0, rabbit_nodes:all_running()).