diff options
| author | Simon MacMullen <simon@rabbitmq.com> | 2014-10-24 16:12:39 +0100 |
|---|---|---|
| committer | Simon MacMullen <simon@rabbitmq.com> | 2014-10-24 16:12:39 +0100 |
| commit | 5f718633f55a851b797283cc7ecdb523649b3570 (patch) | |
| tree | 23dc70e48ab83c6db4dfd4746d39192e46dd90bd | |
| parent | 3b5475471a491360d36bcac3da42c22aa5770ff9 (diff) | |
| download | rabbitmq-server-git-5f718633f55a851b797283cc7ecdb523649b3570.tar.gz | |
*Do* start epmd ourselves if we want to impersonate a node. And just allow net_kernel:start() to fail and catch the error later.
| -rw-r--r-- | src/rabbit_cli.erl | 23 | ||||
| -rw-r--r-- | src/rabbit_control_main.erl | 10 | ||||
| -rw-r--r-- | src/rabbit_nodes.erl | 24 |
3 files changed, 41 insertions, 16 deletions
diff --git a/src/rabbit_cli.erl b/src/rabbit_cli.erl index a946c12a16..58f40a3ce9 100644 --- a/src/rabbit_cli.erl +++ b/src/rabbit_cli.erl @@ -17,7 +17,8 @@ -module(rabbit_cli). -include("rabbit_cli.hrl"). --export([main/3, name_type/0, parse_arguments/4]). +-export([main/3, start_distribution/0, start_distribution/1, + parse_arguments/4]). %%---------------------------------------------------------------------------- @@ -31,7 +32,8 @@ -spec(main/3 :: (fun (([string()], string()) -> parse_result()), fun ((atom(), atom(), [any()], [any()]) -> any()), atom()) -> no_return()). --spec(name_type/0 :: () -> 'shortnames' | 'longnames'). +-spec(start_distribution/0 :: () -> {'ok', pid()} | {'error', any()}). +-spec(start_distribution/1 :: (string()) -> {'ok', pid()} | {'error', any()}). -spec(usage/1 :: (atom()) -> no_return()). -spec(parse_arguments/4 :: ([{atom(), [{string(), optdef()}]} | atom()], @@ -42,6 +44,7 @@ %%---------------------------------------------------------------------------- main(ParseFun, DoFun, UsageMod) -> + error_logger:tty(false), {ok, [[NodeStr|_]|_]} = init:get_argument(nodename), {Command, Opts, Args} = case ParseFun(init:get_plain_arguments(), NodeStr) of @@ -77,12 +80,6 @@ main(ParseFun, DoFun, UsageMod) -> {'EXIT', {badarg, _}} -> print_error("invalid parameter: ~p", [Args]), usage(UsageMod); - {error, {distribution_failed, _}} -> - print_error( - "Could not start distribution.~n" - "The most likely reason is that epmd has not been started by~n" - "the server. Make sure the server is running.~n", []), - rabbit_misc:quit(2); {error, {Problem, Reason}} when is_atom(Problem), is_binary(Reason) -> %% We handle this common case specially to avoid ~p since %% that has i18n issues @@ -111,11 +108,11 @@ main(ParseFun, DoFun, UsageMod) -> end. start_distribution() -> - CtlNodeName = rabbit_misc:format("rabbitmq-cli-~s", [os:getpid()]), - case net_kernel:start([list_to_atom(CtlNodeName), name_type()]) of - {ok, _} -> ok; - {error, Reason} -> throw({error, {distribution_failed, Reason}}) - end. + start_distribution(list_to_atom( + rabbit_misc:format("rabbitmq-cli-~s", [os:getpid()]))). + +start_distribution(Name) -> + net_kernel:start([Name, name_type()]). name_type() -> case os:getenv("RABBITMQ_USE_LONGNAME") of diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index e5a28b559d..5410185608 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -584,12 +584,18 @@ exit_loop(Port) -> end. become(BecomeNode) -> + %% We might not have started distribution if epmd was not running, + %% but we need it now even if we have to start epmd ourselves. + case erlang:is_alive() of + true -> ok; + false -> rabbit_nodes:ensure_epmd(), + rabbit_cli:start_distribution() + end, case net_adm:ping(BecomeNode) of pong -> exit({node_running, BecomeNode}); pang -> io:format(" * Impersonating node: ~s...", [BecomeNode]), - error_logger:tty(false), ok = net_kernel:stop(), - {ok, _} = net_kernel:start([BecomeNode,rabbit_cli:name_type()]), + {ok, _} = rabbit_cli:start_distribution(BecomeNode), io:format(" done~n", []), Dir = mnesia:system_info(directory), io:format(" * Mnesia directory : ~s~n", [Dir]) diff --git a/src/rabbit_nodes.erl b/src/rabbit_nodes.erl index 7f7fcc3126..66d05428c6 100644 --- a/src/rabbit_nodes.erl +++ b/src/rabbit_nodes.erl @@ -18,7 +18,7 @@ -export([names/1, diagnostics/1, make/1, parts/1, cookie_hash/0, is_running/2, is_process_running/2, - cluster_name/0, set_cluster_name/1]). + cluster_name/0, set_cluster_name/1, ensure_epmd/0]). -include_lib("kernel/include/inet.hrl"). @@ -41,6 +41,7 @@ -spec(is_process_running/2 :: (node(), atom()) -> boolean()). -spec(cluster_name/0 :: () -> binary()). -spec(set_cluster_name/1 :: (binary()) -> 'ok'). +-spec(ensure_epmd/0 :: () -> 'ok'). -endif. @@ -77,6 +78,10 @@ diagnostics_node(Node) -> {Name, Host} = parts(Node), [{"~s:", [Node]} | case names(Host) of + {error, address} -> + [{" * connection refused from epmd (port ~s) on ~s~n" + " - has the server started it?~n", + [epmd_port(), Host]}]; {error, Reason} -> [{" * unable to connect to epmd (port ~s) on ~s: ~s~n", [epmd_port(), Host, rabbit_misc:format_inet_error(Reason)]}]; @@ -197,3 +202,20 @@ cluster_name_default() -> set_cluster_name(Name) -> rabbit_runtime_parameters:set_global(cluster_name, Name). + +ensure_epmd() -> + {ok, Root} = init:get_argument(root), + {ok, Prog} = init:get_argument(progname), + ID = random:uniform(1000000000), + Port = open_port( + {spawn_executable, filename:join([Root, "bin", Prog])}, + [{args, ["-sname", rabbit_misc:format("epmd-starter-~b", [ID]), + "-noshell", "-eval", "halt()."]}, + exit_status, stderr_to_stdout, use_stdio]), + port_shutdown_loop(Port). + +port_shutdown_loop(Port) -> + receive + {Port, {exit_status, _Rc}} -> ok; + {Port, _} -> port_shutdown_loop(Port) + end. |
