|
20 | 20 | -export([start/0, stop/0, action/5, diagnostics/1, log_action/3]). |
21 | 21 |
|
22 | 22 | -define(RPC_TIMEOUT, infinity). |
23 | | --define(WAIT_FOR_VM_ATTEMPTS, 5). |
24 | 23 |
|
25 | 24 | -define(QUIET_OPT, "-q"). |
26 | 25 | -define(NODE_OPT, "-n"). |
@@ -193,9 +192,9 @@ action(force_cluster, Node, ClusterNodeSs, _Opts, Inform) -> |
193 | 192 | [Node, ClusterNodes]), |
194 | 193 | rpc_call(Node, rabbit_mnesia, force_cluster, [ClusterNodes]); |
195 | 194 |
|
196 | | -action(wait, Node, [], _Opts, Inform) -> |
| 195 | +action(wait, Node, [PidFile], _Opts, Inform) -> |
197 | 196 | Inform("Waiting for ~p", [Node]), |
198 | | - wait_for_application(Node, ?WAIT_FOR_VM_ATTEMPTS); |
| 197 | + wait_for_application(Node, PidFile, Inform); |
199 | 198 |
|
200 | 199 | action(status, Node, [], _Opts, Inform) -> |
201 | 200 | Inform("Status of node ~p", [Node]), |
@@ -356,23 +355,69 @@ action(report, Node, _Args, _Opts, Inform) -> |
356 | 355 |
|
357 | 356 | %%---------------------------------------------------------------------------- |
358 | 357 |
|
359 | | -wait_for_application(Node, Attempts) -> |
| 358 | +wait_for_application(Node, PidFile, Inform) -> |
| 359 | + Pid = wait_and_read_pid_file(PidFile), |
| 360 | + Inform("pid is ~s", [Pid]), |
| 361 | + wait_for_application(Node, Pid). |
| 362 | + |
| 363 | +wait_for_application(Node, Pid) -> |
| 364 | + case process_up(Pid) of |
| 365 | + true -> case node_up(Node) of |
| 366 | + true -> ok; |
| 367 | + false -> timer:sleep(1000), |
| 368 | + wait_for_application(Node, Pid) |
| 369 | + end; |
| 370 | + false -> {error, process_not_running} |
| 371 | + end. |
| 372 | + |
| 373 | +wait_and_read_pid_file(PidFile) -> |
| 374 | + case file:read_file(PidFile) of |
| 375 | + {ok, Bin} -> string:strip(binary_to_list(Bin), right, $\n); |
| 376 | + {error, enoent} -> timer:sleep(500), |
| 377 | + wait_and_read_pid_file(PidFile); |
| 378 | + {error, _} = E -> exit({error, {could_not_read_pid, E}}) |
| 379 | + end. |
| 380 | + |
| 381 | +node_up(Node) -> |
360 | 382 | case rpc_call(Node, application, which_applications, [infinity]) of |
361 | | - {badrpc, _} = E -> case Attempts of |
362 | | - 0 -> E; |
363 | | - _ -> wait_for_application0(Node, Attempts - 1) |
364 | | - end; |
365 | | - Apps -> case proplists:is_defined(rabbit, Apps) of |
366 | | - %% We've seen the node up; if it goes down |
367 | | - %% die immediately. |
368 | | - true -> ok; |
369 | | - false -> wait_for_application0(Node, 0) |
370 | | - end |
| 383 | + {badrpc, _} -> false; |
| 384 | + Apps -> proplists:is_defined(rabbit, Apps) |
371 | 385 | end. |
372 | 386 |
|
373 | | -wait_for_application0(Node, Attempts) -> |
374 | | - timer:sleep(1000), |
375 | | - wait_for_application(Node, Attempts). |
| 387 | +% Test using some OS clunkiness since we shouldn't trust |
| 388 | +% rpc:call(os, getpid, []) at this point |
| 389 | +process_up(Pid) -> |
| 390 | + with_os([{unix, fun () -> |
| 391 | + system("ps -p " ++ Pid |
| 392 | + ++ " >/dev/null 2>&1") =:= 0 |
| 393 | + end}, |
| 394 | + {win32, fun () -> |
| 395 | + Res = os:cmd("tasklist /nh /fi \"pid eq " ++ |
| 396 | + Pid ++ "\" 2>&1"), |
| 397 | + case re:run(Res, "erl\\.exe", [{capture, none}]) of |
| 398 | + match -> true; |
| 399 | + _ -> false |
| 400 | + end |
| 401 | + end}]). |
| 402 | + |
| 403 | +with_os(Handlers) -> |
| 404 | + {OsFamily, _} = os:type(), |
| 405 | + case proplists:get_value(OsFamily, Handlers) of |
| 406 | + undefined -> throw({unsupported_os, OsFamily}); |
| 407 | + Handler -> Handler() |
| 408 | + end. |
| 409 | + |
| 410 | +% Like system(3) |
| 411 | +system(Cmd) -> |
| 412 | + ShCmd = "sh -c '" ++ escape_quotes(Cmd) ++ "'", |
| 413 | + Port = erlang:open_port({spawn, ShCmd}, [exit_status,nouse_stdio]), |
| 414 | + receive {Port, {exit_status, Status}} -> Status end. |
| 415 | + |
| 416 | +% Escape the quotes in a shell command so that it can be used in "sh -c 'cmd'" |
| 417 | +escape_quotes(Cmd) -> |
| 418 | + lists:flatten(lists:map(fun ($') -> "'\\''"; (Ch) -> Ch end, Cmd)). |
| 419 | + |
| 420 | +%%---------------------------------------------------------------------------- |
376 | 421 |
|
377 | 422 | default_if_empty(List, Default) when is_list(List) -> |
378 | 423 | if List == [] -> Default; |
|
0 commit comments