From c88c4fbadf0cb1586386e1b4d2abf14427f4dc2c Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Thu, 27 Nov 2014 14:54:47 +0000 Subject: Support renaming other remote nodes at the same time, in case we want to do a big bang. --- src/rabbit_control_main.erl | 6 +- src/rabbit_mnesia_offline.erl | 131 +++++++++++++++++++++--------------------- 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. -- cgit v1.2.1