summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Scvortov <alexandru@rabbitmq.com>2010-07-05 10:24:29 +0100
committerAlexandru Scvortov <alexandru@rabbitmq.com>2010-07-05 10:24:29 +0100
commit8a8114858e4a3e01297b2f31e875c3a8ac174038 (patch)
tree1254fb4fa02c3eb2c5945ed06d1db521369ed2b0
parent8af1cb807ba9ae63e6a67a81cb5f4bb71fb06ef0 (diff)
downloadrabbitmq-server-8a8114858e4a3e01297b2f31e875c3a8ac174038.tar.gz
added -f switch to rabbitmqctl cluster
-rw-r--r--src/rabbit_control.erl9
-rw-r--r--src/rabbit_mnesia.erl90
-rw-r--r--src/rabbit_tests.erl12
3 files changed, 67 insertions, 44 deletions
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index 323d4d2f..a498a68a 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -154,11 +154,16 @@ action(force_reset, Node, [], Inform) ->
Inform("Forcefully resetting node ~p", [Node]),
call(Node, {rabbit_mnesia, force_reset, []});
-action(cluster, Node, ClusterNodeSs, Inform) ->
+action(cluster, Node, Args, Inform) ->
+ {Force, ClusterNodeSs} =
+ case Args of
+ ["-f" | Rest] -> {true, Rest};
+ _ -> {false, Args}
+ end,
ClusterNodes = lists:map(fun list_to_atom/1, ClusterNodeSs),
Inform("Clustering node ~p with ~p",
[Node, ClusterNodes]),
- rpc_call(Node, rabbit_mnesia, cluster, [ClusterNodes]);
+ rpc_call(Node, rabbit_mnesia, cluster, [ClusterNodes, Force]);
action(status, Node, [], Inform) ->
Inform("Status of node ~p", [Node]),
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index d4b29943..53028c2b 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -32,7 +32,7 @@
-module(rabbit_mnesia).
-export([ensure_mnesia_dir/0, dir/0, status/0, init/0, is_db_empty/0,
- cluster/1, reset/0, force_reset/0, is_clustered/0,
+ cluster/2, reset/0, force_reset/0, is_clustered/0,
empty_ram_only_tables/0]).
-export([table_names/0]).
@@ -53,7 +53,7 @@
-spec(ensure_mnesia_dir/0 :: () -> 'ok').
-spec(init/0 :: () -> 'ok').
-spec(is_db_empty/0 :: () -> boolean()).
--spec(cluster/1 :: ([erlang_node()]) -> 'ok').
+-spec(cluster/2 :: ([erlang_node()], boolean()) -> 'ok').
-spec(reset/0 :: () -> 'ok').
-spec(force_reset/0 :: () -> 'ok').
-spec(is_clustered/0 :: () -> boolean()).
@@ -84,7 +84,7 @@ status() ->
init() ->
ok = ensure_mnesia_running(),
ok = ensure_mnesia_dir(),
- ok = init_db(read_cluster_nodes_config()),
+ ok = init_db(read_cluster_nodes_config(), true),
ok = wait_for_tables(),
ok.
@@ -95,13 +95,14 @@ is_db_empty() ->
%% Alter which disk nodes this node is clustered with. This can be a
%% subset of all the disk nodes in the cluster but can (and should)
%% include the node itself if it is to be a disk rather than a ram
-%% node.
-cluster(ClusterNodes) ->
+%% node. If Force is false, only connections to online nodes are
+%% allowed.
+cluster(ClusterNodes, Force) ->
ok = ensure_mnesia_not_running(),
ok = ensure_mnesia_dir(),
rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia),
try
- ok = init_db(ClusterNodes),
+ ok = init_db(ClusterNodes, Force),
ok = wait_for_tables(),
ok = create_cluster_nodes_config(ClusterNodes)
after
@@ -273,38 +274,55 @@ delete_cluster_nodes_config() ->
%% Take a cluster node config and create the right kind of node - a
%% standalone disk node, or disk or ram node connected to the
-%% specified cluster nodes.
-init_db(ClusterNodes) ->
- case mnesia:change_config(extra_db_nodes, ClusterNodes -- [node()]) of
- {ok, []} ->
- case mnesia:system_info(use_dir) of
- true ->
- case check_schema_integrity() of
- ok ->
- ok;
- {error, Reason} ->
- %% NB: we cannot use rabbit_log here since
- %% it may not have been started yet
- error_logger:warning_msg(
- "schema integrity check failed: ~p~n"
- "moving database to backup location "
- "and recreating schema from scratch~n",
- [Reason]),
- ok = move_db(),
+%% specified cluster nodes. If Force is false, don't allow
+%% connections to offline nodes.
+init_db(ClusterNodes, Force) ->
+ ProperClusterNodes = ClusterNodes -- [node()],
+ case mnesia:change_config(extra_db_nodes, ProperClusterNodes) of
+ {ok, Nodes} ->
+ case Force of
+ false ->
+ FailedClusterNodes = ProperClusterNodes -- Nodes,
+ case FailedClusterNodes of
+ [] -> ok;
+ _ ->
+ throw({error, {failed_to_cluster_with,
+ FailedClusterNodes,
+ "Mnesia could not connect to some nodes."}})
+ end;
+ _ -> ok
+ end,
+ case Nodes of
+ [] ->
+ case mnesia:system_info(use_dir) of
+ true ->
+ case check_schema_integrity() of
+ ok ->
+ ok;
+ {error, Reason} ->
+ %% NB: we cannot use rabbit_log here since
+ %% it may not have been started yet
+ error_logger:warning_msg(
+ "schema integrity check failed: ~p~n"
+ "moving database to backup location "
+ "and recreating schema from scratch~n",
+ [Reason]),
+ ok = move_db(),
+ ok = create_schema()
+ end;
+ false ->
ok = create_schema()
end;
- false ->
- ok = create_schema()
- end;
- {ok, [_|_]} ->
- IsDiskNode = ClusterNodes == [] orelse
- lists:member(node(), ClusterNodes),
- ok = wait_for_replicated_tables(),
- ok = create_local_table_copy(schema, disc_copies),
- ok = create_local_table_copies(case IsDiskNode of
- true -> disc;
- false -> ram
- end);
+ [_|_] ->
+ IsDiskNode = ClusterNodes == [] orelse
+ lists:member(node(), ClusterNodes),
+ ok = wait_for_replicated_tables(),
+ ok = create_local_table_copy(schema, disc_copies),
+ ok = create_local_table_copies(case IsDiskNode of
+ true -> disc;
+ false -> ram
+ end)
+ end;
{error, Reason} ->
%% one reason we may end up here is if we try to join
%% nodes together that are currently running standalone or
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index 960d9a9c..55d1f52e 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -601,19 +601,19 @@ test_cluster_management() ->
ok = control_action(reset, []),
lists:foreach(fun (Arg) ->
- ok = control_action(cluster, Arg),
+ ok = control_action(cluster, ["-f" | Arg]),
ok
end,
ClusteringSequence),
lists:foreach(fun (Arg) ->
ok = control_action(reset, []),
- ok = control_action(cluster, Arg),
+ ok = control_action(cluster, ["-f" | Arg]),
ok
end,
ClusteringSequence),
ok = control_action(reset, []),
lists:foreach(fun (Arg) ->
- ok = control_action(cluster, Arg),
+ ok = control_action(cluster, ["-f" | Arg]),
ok = control_action(start_app, []),
ok = control_action(stop_app, []),
ok
@@ -621,7 +621,7 @@ test_cluster_management() ->
ClusteringSequence),
lists:foreach(fun (Arg) ->
ok = control_action(reset, []),
- ok = control_action(cluster, Arg),
+ ok = control_action(cluster, ["-f" | Arg]),
ok = control_action(start_app, []),
ok = control_action(stop_app, []),
ok
@@ -632,12 +632,12 @@ test_cluster_management() ->
ok = control_action(reset, []),
ok = control_action(start_app, []),
ok = control_action(stop_app, []),
- ok = control_action(cluster, ["invalid1@invalid",
+ ok = control_action(cluster, ["-f", "invalid1@invalid",
"invalid2@invalid"]),
%% join a non-existing cluster as a ram node
ok = control_action(reset, []),
- ok = control_action(cluster, ["invalid1@invalid",
+ ok = control_action(cluster, ["-f", "invalid1@invalid",
"invalid2@invalid"]),
SecondaryNode = rabbit_misc:makenode("hare"),