summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Mazzoli <francesco@rabbitmq.com>2012-05-23 12:05:27 +0100
committerFrancesco Mazzoli <francesco@rabbitmq.com>2012-05-23 12:05:27 +0100
commitb8793d4d03433b1ad7d026365d68a6fc58f2cf8d (patch)
treee34ee80fbbc2d3613e5289949eaa11405d2f9ea2
parent166124e8c12a2b2dbdd93210b14c43b5dbe67d21 (diff)
downloadrabbitmq-server-git-b8793d4d03433b1ad7d026365d68a6fc58f2cf8d.tar.gz
stricter cluster consistency check
Now checking for matching OTP & rabbit version
-rw-r--r--src/rabbit_mnesia.erl67
1 files changed, 47 insertions, 20 deletions
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index 882f154dc9..b64d85d0f0 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -30,7 +30,7 @@
-export([table_names/0]).
%% Used internally in rpc calls, see `discover_nodes/1'
--export([cluster_status_if_running/0]).
+-export([cluster_status_if_running/0, node_info/0]).
%% create_tables/0 exported for helping embed RabbitMQ in or alongside
%% other mnesia-using Erlang applications, such as ejabberd
@@ -327,6 +327,10 @@ cluster_status_if_running() ->
mnesia:system_info(running_db_nodes)}}
end.
+node_info() ->
+ {erlang:system_info(otp_release), application:get_env(rabbit, vsn),
+ cluster_status_if_running()}.
+
is_disc_node() -> mnesia:system_info(use_dir).
dir() -> mnesia:system_info(directory).
@@ -524,28 +528,51 @@ should_be_disc_node(DiscNodes) ->
DiscNodes == [] orelse lists:member(node(), DiscNodes).
%% This does not guarantee us much, but it avoids some situations that will
-%% definitely end in disaster (a node starting and trying to merge its schema
-%% to another node which is not clustered with it).
+%% definitely end up badly
check_cluster_consistency() ->
- ThisNode = node(),
+ CheckVsn = fun (This, This, _) ->
+ ok;
+ (This, Remote, Name) ->
+ throw({error,
+ {inconsistent_cluster,
+ rabbit_misc:format(
+ "~s version mismatch: local node is ~s, "
+ "remote node ~s", [Name, This, Remote])}})
+ end,
+ CheckOTP =
+ fun (OTP) -> CheckVsn(erlang:system_info(otp_release), OTP, "OTP") end,
+ CheckRabbit =
+ fun (Rabbit) ->
+ CheckVsn(application:get_env(rabbit, vsn), Rabbit, "Rabbit")
+ end,
+
+ CheckNodes = fun (Node, AllNodes) ->
+ ThisNode = node(),
+ case lists:member(ThisNode, AllNodes) of
+ true ->
+ ok;
+ false ->
+ throw({error,
+ {inconsistent_cluster,
+ rabbit_misc:format(
+ "Node ~p thinks it's clustered "
+ "with node ~p, but ~p disagrees",
+ [ThisNode, Node, Node])}})
+ end
+ end,
+
lists:foreach(
fun(Node) ->
- case rpc:call(Node, rabbit_mnesia, cluster_status_if_running, [])
- of
- {badrpc, _Reason} -> ok;
- error -> ok;
- {ok, {AllNodes, _, _}} ->
- case lists:member(ThisNode, AllNodes) of
- true ->
- ok;
- false ->
- throw({error,
- {inconsistent_cluster,
- rabbit_misc:format(
- "Node ~p thinks it's clustered with "
- "node ~p, but ~p disagrees",
- [ThisNode, Node, Node])}})
- end
+ case rpc:call(Node, rabbit_mnesia, node_info, []) of
+ {badrpc, _Reason} ->
+ ok;
+ {OTP, Rabbit, error} ->
+ CheckOTP(OTP),
+ CheckRabbit(Rabbit);
+ {OTP, Rabbit, {ok, {AllNodes, _, _}}} ->
+ CheckOTP(OTP),
+ CheckRabbit(Rabbit),
+ CheckNodes(Node, AllNodes)
end
end, all_clustered_nodes()).