summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2014-11-27 14:54:47 +0000
committerSimon MacMullen <simon@rabbitmq.com>2014-11-27 14:54:47 +0000
commitc88c4fbadf0cb1586386e1b4d2abf14427f4dc2c (patch)
tree8e0f36e914077909eee36f45efe9c184b43ab5c2
parent6e84950b23c2a23157a96146e8c5d36e5009848d (diff)
downloadrabbitmq-server-c88c4fbadf0cb1586386e1b4d2abf14427f4dc2c.tar.gz
Support renaming other remote nodes at the same time, in case we want to do a big bang.
-rw-r--r--src/rabbit_control_main.erl6
-rw-r--r--src/rabbit_mnesia_offline.erl131
2 files changed, 69 insertions, 68 deletions
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index b19971fc..21c4e4c3 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -235,11 +235,13 @@ action(forget_cluster_node, Node, [ClusterNodeS], Opts, Inform) ->
[ClusterNode, false])
end;
-action(rename_current_node, _Node, [FromNodeS, ToNodeS], _Opts, Inform) ->
+action(rename_current_node, _Node, [FromNodeS, ToNodeS | OthersS],
+ _Opts, Inform) ->
+ Others = [list_to_atom(N) || N <- OthersS],
FromNode = list_to_atom(FromNodeS),
ToNode = list_to_atom(ToNodeS),
Inform("Renaming local cluster node ~s to ~s", [FromNode, ToNode]),
- rabbit_mnesia_offline:rename_local_node(FromNode, ToNode);
+ rabbit_mnesia_offline:rename_local_node(FromNode, ToNode, Others);
action(force_boot, Node, [], _Opts, Inform) ->
Inform("Forcing boot for Mnesia dir ~s", [mnesia:system_info(directory)]),
diff --git a/src/rabbit_mnesia_offline.erl b/src/rabbit_mnesia_offline.erl
index 86b5c370..eb22bc14 100644
--- a/src/rabbit_mnesia_offline.erl
+++ b/src/rabbit_mnesia_offline.erl
@@ -17,7 +17,7 @@
-module(rabbit_mnesia_offline).
-include("rabbit.hrl").
--export([rename_local_node/2]).
+-export([rename_local_node/3]).
-export([rename_remote_node/2]).
-export([maybe_complete_rename/1]).
@@ -25,14 +25,15 @@
-ifdef(use_specs).
--spec(rename_local_node/2 :: (node(), node()) -> 'ok').
+-spec(rename_local_node/3 :: (node(), node(), [node()]) -> 'ok').
-spec(rename_remote_node/2 :: (node(), node()) -> 'ok').
-endif.
%%----------------------------------------------------------------------------
-rename_local_node(FromNode, ToNode) ->
+rename_local_node(FromNode, ToNode, Others) ->
+ NodeMap = dict:from_list(split_others([FromNode, ToNode | Others])),
try
rabbit_control_main:become(FromNode),
rabbit_log:info("Renaming node ~s to ~s~n", [FromNode, ToNode]),
@@ -50,24 +51,23 @@ rename_local_node(FromNode, ToNode) ->
io:format(" * Backing up to '~s'~n", [FromBackup]),
ok = mnesia:backup(FromBackup),
stop_mnesia(),
- rabbit_control_main:become(ToNode),
io:format(" * Converting backup '~s'~n", [ToBackup]),
- convert_backup(FromNode, ToNode, FromBackup, ToBackup),
+ convert_backup(NodeMap, FromBackup, ToBackup),
ok = rabbit_file:write_term_file(rename_config_name(),
[{FromNode, ToNode}]),
io:format(" * Converting config files~n", []),
- convert_config_file(FromNode, ToNode,
+ convert_config_file(NodeMap,
rabbit_node_monitor:running_nodes_filename()),
- convert_config_file(FromNode, ToNode,
+ convert_config_file(NodeMap,
rabbit_node_monitor:cluster_status_filename()),
ok
after
stop_mnesia()
end.
-nodes_running(Nodes) ->
- [N || N <- Nodes, rabbit:is_running(N)].
-
+split_others([]) -> [];
+split_others([_]) -> exit(even_list_needed);
+split_others([A, B | T]) -> [{A, B} | split_others(T)].
maybe_complete_rename(AllNodes) ->
case rabbit_file:read_term_file(rename_config_name()) of
@@ -109,47 +109,42 @@ rename_config_name() -> rabbit_mnesia:dir() ++ "/rename-pending.config".
start_mnesia() -> rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia).
stop_mnesia() -> stopped = mnesia:stop().
-convert_backup(FromNode, ToNode, FromBackup, ToBackup) ->
- Switch = fun
- (Node) when Node == FromNode ->
- ToNode;
- (Node) when Node == ToNode ->
- throw({error, {already_exists, Node}});
- (Node) ->
- Node
+convert_backup(NodeMap, FromBackup, ToBackup) ->
+ Switch = fun (OldNode) ->
+ lookup_node(OldNode, NodeMap)
end,
Convert =
fun
%% TODO do we ever hit these three heads?
- ({schema, db_nodes, Nodes}, Acc) ->
- io:format(" +++ db_nodes ~p~n", [Nodes]),
- {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
- ({schema, version, Version}, Acc) ->
- io:format(" +++ version: ~p~n", [Version]),
- {[{schema, version, Version}], Acc};
- ({schema, cookie, Cookie}, Acc) ->
- io:format(" +++ cookie: ~p~n", [Cookie]),
- {[{schema, cookie, Cookie}], Acc};
- ({schema, Tab, CreateList}, Acc) ->
- %% io:format("~n * Checking table: '~p'~n", [Tab]),
- %%io:format(" . Initial content: ~p~n", [CreateList]),
- Keys = [ram_copies, disc_copies, disc_only_copies],
- OptSwitch =
- fun({Key, Val}) ->
- case lists:member(Key, Keys) of
- true ->
- %%io:format(" + Checking key: '~p'~n", [Key]),
- {Key, lists:map(Switch, Val)};
- false->
- {Key, Val}
- end
- end,
- Res = {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc},
- %%io:format(" . Resulting content: ~p~n", [Res]),
- Res;
+ %% ({schema, db_nodes, Nodes}, Acc) ->
+ %% io:format(" +++ db_nodes ~p~n", [Nodes]),
+ %% {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
+ %% ({schema, version, Version}, Acc) ->
+ %% io:format(" +++ version: ~p~n", [Version]),
+ %% {[{schema, version, Version}], Acc};
+ %% ({schema, cookie, Cookie}, Acc) ->
+ %% io:format(" +++ cookie: ~p~n", [Cookie]),
+ %% {[{schema, cookie, Cookie}], Acc};
+ %% ({schema, Tab, CreateList}, Acc) ->
+ %% io:format("~n * Checking table: '~p'~n", [Tab]),
+ %% io:format(" . Initial content: ~p~n", [CreateList]),
+ %% Keys = [ram_copies, disc_copies, disc_only_copies],
+ %% OptSwitch =
+ %% fun({Key, Val}) ->
+ %% case lists:member(Key, Keys) of
+ %% true ->
+ %% %%io:format(" + Checking key: '~p'~n", [Key]),
+ %% {Key, lists:map(Switch, Val)};
+ %% false->
+ %% {Key, Val}
+ %% end
+ %% end,
+ %% Res = {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc},
+ %% io:format(" . Resulting content: ~p~n", [Res]),
+ %% Res;
(Other, Acc) ->
- case lists:member(element(1, Other), [rabbit_durable_queue]) of
- true -> Other1 = update_term(FromNode, ToNode, Other),
+ case lists:member(element(1, Other), [schema, rabbit_durable_queue]) of
+ true -> Other1 = update_term(NodeMap, Other),
io:format(" --- ~p~n +++ ~p~n", [Other, Other1]),
{[Other1], Acc};
false -> {[Other], Acc}
@@ -157,19 +152,25 @@ convert_backup(FromNode, ToNode, FromBackup, ToBackup) ->
end,
mnesia:traverse_backup(FromBackup, ToBackup, Convert, switched).
-convert_config_file(FromNode, ToNode, Path) ->
+convert_config_file(NodeMap, Path) ->
{ok, Term} = rabbit_file:read_term_file(Path),
- ok = rabbit_file:write_term_file(Path, update_term(FromNode, ToNode, Term)).
-
-update_term(N1, N2, L) when is_list(L) ->
- [update_term(N1, N2, I) || I <- L];
-update_term(N1, N2, T) when is_tuple(T) ->
- list_to_tuple(update_term(N1, N2, tuple_to_list(T)));
-update_term(N1, N2, N1) ->
- N2;
-update_term(N1, N2, Pid) when is_pid(Pid), node(Pid) == N1 ->
- rabbit_misc:pid_change_node(Pid, N2);
-update_term(_N1, _N2, Term) ->
+ ok = rabbit_file:write_term_file(Path, update_term(NodeMap, Term)).
+
+lookup_node(OldNode, NodeMap) ->
+ case dict:find(OldNode, NodeMap) of
+ {ok, NewNode} -> NewNode;
+ error -> OldNode
+ end.
+
+update_term(NodeMap, L) when is_list(L) ->
+ [update_term(NodeMap, I) || I <- L];
+update_term(NodeMap, T) when is_tuple(T) ->
+ list_to_tuple(update_term(NodeMap, tuple_to_list(T)));
+update_term(NodeMap, Node) when is_atom(Node) ->
+ lookup_node(Node, NodeMap);
+update_term(NodeMap, Pid) when is_pid(Pid) ->
+ rabbit_misc:pid_change_node(Pid, lookup_node(node(Pid), NodeMap));
+update_term(_NodeMap, Term) ->
Term.
%%----------------------------------------------------------------------------
@@ -177,18 +178,16 @@ update_term(_N1, _N2, Term) ->
rename_remote_node(FromNode, ToNode) ->
All = rabbit_mnesia:cluster_nodes(all),
Running = rabbit_mnesia:cluster_nodes(running),
- case {lists:member(FromNode, All),
- lists:member(FromNode, Running),
- lists:member(ToNode, All)} of
- {true, false, true} -> ok;
- {false, _, _} -> exit({old_node_not_in_cluster, FromNode});
- {_, true, _} -> exit({old_node_running, FromNode});
- {_, _, false} -> exit({new_node_not_in_cluster, ToNode})
+ case {lists:member(FromNode, Running), lists:member(ToNode, All)} of
+ {false, true} -> ok;
+ {true, _} -> exit({old_node_running, FromNode});
+ {_, false} -> exit({new_node_not_in_cluster, ToNode})
end,
mnesia:del_table_copy(schema, FromNode),
+ NodeMap = dict:from_list([{FromNode, ToNode}]),
{atomic, ok} = mnesia:transform_table(
rabbit_durable_queue,
- fun (Q) -> update_term(FromNode, ToNode, Q) end,
+ fun (Q) -> update_term(NodeMap, Q) end,
record_info(fields, amqqueue)),
ok.