diff options
| author | Francesco Mazzoli <francesco@rabbitmq.com> | 2012-08-22 17:17:44 +0100 |
|---|---|---|
| committer | Francesco Mazzoli <francesco@rabbitmq.com> | 2012-08-22 17:17:44 +0100 |
| commit | 52b0976b830b637611086523910d5dc66d35ebab (patch) | |
| tree | c7e711f863df4b0aa30daa0d5b9ebe28e8e2824e /src | |
| parent | d1a918746225d04f0a155f00764c70118ccb8b30 (diff) | |
| download | rabbitmq-server-git-52b0976b830b637611086523910d5dc66d35ebab.tar.gz | |
get nodes and whether the node should be disc or ram from config if virgin node
The first suitable node is picked from the list in the configuration, no
consistency check is done - we might want to do that?
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_mnesia.erl | 80 | ||||
| -rw-r--r-- | src/rabbit_node_monitor.erl | 36 |
2 files changed, 86 insertions, 30 deletions
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl index a67c0fe9ad..5cfdd5e05c 100644 --- a/src/rabbit_mnesia.erl +++ b/src/rabbit_mnesia.erl @@ -125,14 +125,37 @@ prepare() -> init() -> ensure_mnesia_running(), ensure_mnesia_dir(), - DiscNode = is_disc_node(), - init_db_and_upgrade(all_clustered_nodes(), DiscNode, DiscNode), + case is_virgin_node() of + true -> init_from_config(); + false -> normal_init(is_disc_node(), all_clustered_nodes()) + end, %% We intuitively expect the global name server to be synced when %% Mnesia is up. In fact that's not guaranteed to be the case - let's %% make it so. ok = global:sync(), ok. +normal_init(DiscNode, AllNodes) -> + DiscNode = is_disc_node(), + init_db_and_upgrade(AllNodes, DiscNode, DiscNode). + +init_from_config() -> + {ok, {TryNodes, DiscNode}} = + application:get_env(rabbit, cluster_nodes), + case find_good_node(TryNodes -- [node()]) of + {ok, Node} -> + rabbit_log:info("Node '~p' selected for clustering from " + "configuration~n", [Node]), + {ok, {_, DiscNodes, _}} = discover_cluster(Node), + init_db_and_upgrade(DiscNodes, DiscNode, false), + rabbit_node_monitor:notify_joined_cluster(); + none -> + rabbit_log:warning("Could not find any suitable node amongst the " + "ones provided in the configuration: ~p~n", + [TryNodes]), + normal_init(DiscNode, [node()]) + end. + %% Make the node join a cluster. The node will be reset automatically before we %% actually cluster it. The nodes provided will be used to find out about the %% nodes in the cluster. @@ -428,10 +451,10 @@ running_clustered_disc_nodes() -> mnesia_nodes() -> case mnesia:system_info(is_running) of no -> {error, mnesia_not_running}; - yes -> %% If the tables are not present, it means that `init_db/3' hasn't - %% been run yet. In other words, either we are a virgin node or a - %% restarted RAM node. In both cases we're not interested in what - %% mnesia has to say. + yes -> %% If the tables are not present, it means that `init_db/3' + %% hasn't been run yet. In other words, either we are a virgin + %% node or a restarted RAM node. In both cases we're not + %% interested in what mnesia has to say. IsDiscNode = mnesia:system_info(use_dir), Tables = mnesia:system_info(tables), {Table, _} = case table_definitions(case IsDiscNode of @@ -690,10 +713,8 @@ check_cluster_consistency() -> {error, Error}; {OTP, Rabbit, Res} -> rabbit_misc:sequence_error( - [check_version_consistency( - erlang:system_info(otp_release), OTP, "OTP"), - check_version_consistency( - rabbit_misc:version(), Rabbit, "Rabbit"), + [check_otp_consistency(OTP), + check_rabbit_consistency(Rabbit), case Res of {ok, Status} -> check_nodes_consistency(Node, Status); @@ -701,8 +722,7 @@ check_cluster_consistency() -> {error, Error} end]) end; - (_Node, {ok, Status}) -> - {ok, Status} + (_Node, {ok, Status}) -> {ok, Status} end, {error, no_nodes}, AllNodes) of {ok, Status = {RemoteAllNodes, _, _}} -> @@ -1130,3 +1150,39 @@ check_version_consistency(This, Remote, Name) -> {error, {inconsistent_cluster, rabbit_misc:format("~s version mismatch: local node is ~s, " "remote node ~s", [Name, This, Remote])}}. + +check_otp_consistency(Remote) -> + check_version_consistency(erlang:system_info(otp_release), Remote, "OTP"). + +check_rabbit_consistency(Remote) -> + check_version_consistency(rabbit_misc:version(), Remote, "Rabbit"). + +%% This is fairly tricky. We want to know if the node is in the state that a +%% `reset' would leave it in. We cannot simply check if the mnesia tables +%% aren't there because restarted RAM nodes won't have tables while still being +%% non-virgin. What we do instead is to check if the mnesia directory is non +%% existant or empty, with the exception of the cluster status file, which will +%% be there thanks to `rabbit_node_monitor:prepare_cluster_status_file/0'. +is_virgin_node() -> + case rabbit_file:list_dir(dir()) of + {error, enoent} -> true; + {ok, []} -> true; + {ok, [File]} -> (dir() ++ "/" ++ File) =:= + rabbit_node_monitor:cluster_status_file_name(); + {ok, Files} -> false + end. + +find_good_node([]) -> + none; +find_good_node([Node | Nodes]) -> + case rpc:call(Node, rabbit_mnesia, node_info, []) of + {badrpc, _Reason} -> + find_good_node(Nodes); + {OTP, Rabbit, _} -> + case rabbit_misc:sequence_error([check_otp_consistency(OTP), + check_rabbit_consistency(Rabbit)]) + of + {error, _} -> find_good_node(Nodes); + ok -> {ok, Node} + end + end. diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl index 849f5d3139..b2d1c11c82 100644 --- a/src/rabbit_node_monitor.erl +++ b/src/rabbit_node_monitor.erl @@ -18,7 +18,8 @@ -behaviour(gen_server). --export([prepare_cluster_status_file/0, +-export([cluster_status_file_name/0, + prepare_cluster_status_file/0, write_cluster_status_file/1, read_cluster_status_file/0, update_cluster_status_file/0, @@ -80,26 +81,27 @@ %% various situations. Obviously when mnesia is offline the information we have %% will be outdated, but it can't be otherwise. -cluster_status_file_filename() -> +cluster_status_file_name() -> rabbit_mnesia:dir() ++ "/cluster_nodes.config". prepare_cluster_status_file() -> NotPresent = fun (AllNodes0, WantDiscNode) -> - ThisNode = [node()], + ThisNode = [node()], - RunningNodes0 = legacy_read_previously_running_nodes(), - legacy_delete_previously_running_nodes(), + RunningNodes0 = legacy_read_previously_running_nodes(), + legacy_delete_previously_running_nodes(), - RunningNodes = lists:usort(RunningNodes0 ++ ThisNode), - AllNodes = - lists:usort(AllNodes0 ++ RunningNodes), - DiscNodes = case WantDiscNode of - true -> ThisNode; - false -> [] - end, + RunningNodes = lists:usort(RunningNodes0 ++ ThisNode), + AllNodes = + lists:usort(AllNodes0 ++ RunningNodes), + DiscNodes = case WantDiscNode of + true -> ThisNode; + false -> [] + end, - ok = write_cluster_status_file({AllNodes, DiscNodes, RunningNodes}) + ok = write_cluster_status_file({AllNodes, DiscNodes, + RunningNodes}) end, case try_read_cluster_status_file() of {ok, _} -> @@ -108,14 +110,12 @@ prepare_cluster_status_file() -> %% Legacy file NotPresent(AllNodes, legacy_should_be_disc_node(AllNodes)); {error, {cannot_read_file, _, enoent}} -> - {ok, {AllNodes, WantDiscNode}} = - application:get_env(rabbit, cluster_nodes), - NotPresent(AllNodes, WantDiscNode) + NotPresent([], true) end. write_cluster_status_file(Status) -> - FileName = cluster_status_file_filename(), + FileName = cluster_status_file_name(), case rabbit_file:write_term_file(FileName, [Status]) of ok -> ok; {error, Reason} -> @@ -124,7 +124,7 @@ write_cluster_status_file(Status) -> end. try_read_cluster_status_file() -> - FileName = cluster_status_file_filename(), + FileName = cluster_status_file_name(), case rabbit_file:read_term_file(FileName) of {ok, [{_, _, _} = Status]} -> {ok, Status}; |
