summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert@lshift.net>2008-11-28 13:38:29 +0000
committerHubert Plociniczak <hubert@lshift.net>2008-11-28 13:38:29 +0000
commit483ae51c76ea1423f7cc496d81491a23102a73d1 (patch)
tree02ef81c4a6067d85c6e6cdb476dd02224fa6fcde
parent64cd20da94be05e0ba5a9f2af9441eec4824075a (diff)
parentb03225948fa01e0e9b8ece91956d3fd967b06356 (diff)
downloadrabbitmq-server-483ae51c76ea1423f7cc496d81491a23102a73d1.tar.gz
Merge bug19331 into default
-rw-r--r--Makefile54
-rw-r--r--include/rabbit.hrl4
-rw-r--r--packaging/RPMS/Fedora/Makefile3
-rw-r--r--packaging/RPMS/Fedora/rabbitmq-server.spec14
-rwxr-xr-xscripts/rabbitmq-server2
-rw-r--r--src/rabbit.erl4
-rw-r--r--src/rabbit_alarm.erl19
-rw-r--r--src/rabbit_amqqueue.erl2
-rw-r--r--src/rabbit_amqqueue_process.erl4
-rw-r--r--src/rabbit_control.erl138
-rw-r--r--src/rabbit_exchange.erl12
-rw-r--r--src/rabbit_heartbeat.erl2
-rw-r--r--src/rabbit_load.erl6
-rw-r--r--src/rabbit_misc.erl2
-rw-r--r--src/rabbit_mnesia.erl4
-rw-r--r--src/rabbit_networking.erl4
-rw-r--r--src/rabbit_sasl_report_file_h.erl5
-rw-r--r--src/rabbit_tests.erl2
18 files changed, 156 insertions, 125 deletions
diff --git a/Makefile b/Makefile
index ee7bb30d..04a0aff6 100644
--- a/Makefile
+++ b/Makefile
@@ -23,6 +23,7 @@ LOG_BASE=/tmp
VERSION=0.0.0
TARBALL_NAME=rabbitmq-server-$(VERSION)
+TARGET_SRC_DIR=dist/$(TARBALL_NAME)
SIBLING_CODEGEN_DIR=../rabbitmq-codegen/
AMQP_CODEGEN_DIR=$(shell [ -d $(SIBLING_CODEGEN_DIR) ] && echo $(SIBLING_CODEGEN_DIR) || echo codegen)
@@ -92,39 +93,27 @@ stop-cover: all
########################################################################
-generic_stage:
- mkdir -p $(GENERIC_STAGE_DIR)
- cp -r ebin include src $(GENERIC_STAGE_DIR)
- cp LICENSE LICENSE-MPL-RabbitMQ $(GENERIC_STAGE_DIR)
-
- if [ -f INSTALL.in ]; then \
- cp INSTALL.in $(GENERIC_STAGE_DIR)/INSTALL; \
- elinks -dump -no-references -no-numbering $(WEB_URL)install.html \
- >> $(GENERIC_STAGE_DIR)/INSTALL; \
- cp BUILD.in $(GENERIC_STAGE_DIR)/BUILD; \
- elinks -dump -no-references -no-numbering $(WEB_URL)build-server.html \
- >> $(GENERIC_STAGE_DIR)/BUILD; \
- else \
- cp INSTALL $(GENERIC_STAGE_DIR); \
- cp BUILD $(GENERIC_STAGE_DIR); \
- fi
-
- sed -i 's/%%VERSION%%/$(VERSION)/' $(GENERIC_STAGE_DIR)/ebin/rabbit.app
-
srcdist: distclean
- $(MAKE) VERSION=$(VERSION) GENERIC_STAGE_DIR=dist/$(TARBALL_NAME) generic_stage
-
- mkdir -p dist/$(TARBALL_NAME)/codegen
- cp -r $(AMQP_CODEGEN_DIR)/* dist/$(TARBALL_NAME)/codegen/
- cp codegen.py Makefile dist/$(TARBALL_NAME)
-
- cp -r scripts dist/$(TARBALL_NAME)
- cp -r docs dist/$(TARBALL_NAME)
- chmod 0755 dist/$(TARBALL_NAME)/scripts/*
+ mkdir -p $(TARGET_SRC_DIR)/codegen
+ cp -r ebin src include LICENSE LICENSE-MPL-RabbitMQ $(TARGET_SRC_DIR)
+ cp INSTALL.in $(TARGET_SRC_DIR)/INSTALL
+ elinks -dump -no-references -no-numbering $(WEB_URL)install.html \
+ >> $(TARGET_SRC_DIR)/INSTALL
+ cp BUILD.in $(TARGET_SRC_DIR)/BUILD
+ elinks -dump -no-references -no-numbering $(WEB_URL)build-server.html \
+ >> $(TARGET_SRC_DIR)/BUILD
+ sed -i 's/%%VERSION%%/$(VERSION)/' $(TARGET_SRC_DIR)/ebin/rabbit.app
+
+ cp -r $(AMQP_CODEGEN_DIR)/* $(TARGET_SRC_DIR)/codegen/
+ cp codegen.py Makefile $(TARGET_SRC_DIR)
+
+ cp -r scripts $(TARGET_SRC_DIR)
+ cp -r docs $(TARGET_SRC_DIR)
+ chmod 0755 $(TARGET_SRC_DIR)/scripts/*
(cd dist; tar -zcf $(TARBALL_NAME).tar.gz $(TARBALL_NAME))
(cd dist; zip -r $(TARBALL_NAME).zip $(TARBALL_NAME))
- rm -rf dist/$(TARBALL_NAME)
+ rm -rf $(TARGET_SRC_DIR)
distclean: clean
make -C $(AMQP_CODEGEN_DIR) clean
@@ -135,8 +124,9 @@ install: all
@[ -n "$(TARGET_DIR)" ] || (echo "Please set TARGET_DIR."; false)
@[ -n "$(SBIN_DIR)" ] || (echo "Please set SBIN_DIR."; false)
@[ -n "$(MAN_DIR)" ] || (echo "Please set MAN_DIR."; false)
-
- $(MAKE) VERSION=$(VERSION) GENERIC_STAGE_DIR=$(TARGET_DIR) generic_stage
+
+ mkdir -p $(TARGET_DIR)
+ cp -r ebin include LICENSE LICENSE-MPL-RabbitMQ INSTALL $(TARGET_DIR)
chmod 0755 scripts/*
mkdir -p $(SBIN_DIR)
@@ -149,5 +139,3 @@ install: all
$$manpage | gzip --best > \
$(MAN_DIR)/man1/`echo $$manpage | sed -e 's:docs/\(.*\)\.pod:\1\.1\.gz:g'`; \
done
-
- rm -f $(TARGET_DIR)/BUILD
diff --git a/include/rabbit.hrl b/include/rabbit.hrl
index 706a92af..42bc8fa9 100644
--- a/include/rabbit.hrl
+++ b/include/rabbit.hrl
@@ -63,7 +63,7 @@
-include("rabbit_framing_spec.hrl").
-type(maybe(T) :: T | 'none').
--type(node() :: atom()).
+-type(erlang_node() :: atom()).
-type(socket() :: port()).
-type(thunk(T) :: fun(() -> T)).
@@ -123,7 +123,7 @@
-type(msg_id() :: non_neg_integer()).
-type(msg() :: {queue_name(), pid(), msg_id(), bool(), message()}).
-type(listener() ::
- #listener{node :: node(),
+ #listener{node :: erlang_node(),
protocol :: atom(),
host :: string() | atom(),
port :: non_neg_integer()}).
diff --git a/packaging/RPMS/Fedora/Makefile b/packaging/RPMS/Fedora/Makefile
index 33032f11..f6d8dde8 100644
--- a/packaging/RPMS/Fedora/Makefile
+++ b/packaging/RPMS/Fedora/Makefile
@@ -20,7 +20,8 @@ prepare:
cp rabbitmq-server.logrotate SOURCES/rabbitmq-server.logrotate
server: prepare
- rpmbuild -ba SPECS/rabbitmq-server.spec $(DEFINES) --target noarch
+ rpmbuild -ba SPECS/rabbitmq-server.spec $(DEFINES) --target i386
+ rpmbuild -ba SPECS/rabbitmq-server.spec $(DEFINES) --target x86_64
clean:
rm -rf SOURCES SPECS RPMS SRPMS BUILD tmp
diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec
index 214f6918..23ebecef 100644
--- a/packaging/RPMS/Fedora/rabbitmq-server.spec
+++ b/packaging/RPMS/Fedora/rabbitmq-server.spec
@@ -11,11 +11,11 @@ URL: http://www.rabbitmq.com/
Vendor: LShift Ltd., Cohesive Financial Technologies LLC., Rabbit Technlogies Ltd.
%if 0%{?debian}
%else
-BuildRequires: python, python-json
+BuildRequires: erlang, python-json
%endif
Requires: erlang, logrotate
Packager: Hubert Plociniczak <hubert@lshift.net>
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%{_arch}-root
Summary: The RabbitMQ server
Requires(post): chkconfig
Requires(pre): chkconfig initscripts
@@ -25,11 +25,14 @@ RabbitMQ is an implementation of AMQP, the emerging standard for high
performance enterprise messaging. The RabbitMQ server is a robust and
scalable implementation of an AMQP broker.
+%ifarch x86_64
+ %define _erllibdir /usr/lib64/erlang/lib
+%else
+ %define _erllibdir /usr/lib/erlang/lib
+%endif
-%define _erllibdir %(erl -noshell -eval "io:format('~s~n', [code:lib_dir()]), halt().")
%define _maindir %{buildroot}%{_erllibdir}/rabbitmq_server-%{version}
-
%pre
if [ $1 -gt 1 ]; then
#Upgrade - stop and remove previous instance of rabbitmq-server init.d script
@@ -67,6 +70,8 @@ cp %{buildroot}%{_mandir}/man1/rabbitmqctl.1.gz %{buildroot}%{_mandir}/man1/rabb
mkdir -p %{buildroot}/etc/logrotate.d
install %SOURCE3 %{buildroot}/etc/logrotate.d/rabbitmq-server
+rm %{_maindir}/LICENSE %{_maindir}/LICENSE-MPL-RabbitMQ %{_maindir}/INSTALL
+
%post
# create rabbitmq group
if ! getent group rabbitmq >/dev/null; then
@@ -110,6 +115,7 @@ fi
/var/log/rabbitmq/
/etc/rc.d/init.d/rabbitmq-server
%config(noreplace) /etc/logrotate.d/rabbitmq-server
+%doc LICENSE LICENSE-MPL-RabbitMQ INSTALL
%clean
rm -rf %{buildroot}
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server
index c953a753..fba2f026 100755
--- a/scripts/rabbitmq-server
+++ b/scripts/rabbitmq-server
@@ -53,7 +53,7 @@ else
CLUSTER_CONFIG=""
fi
-erl \
+exec erl \
-pa "`dirname $0`/../ebin" \
${START_RABBIT} \
-sname ${NODENAME} \
diff --git a/src/rabbit.erl b/src/rabbit.erl
index a33c5b7b..195dd729 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -57,8 +57,8 @@
-spec(rotate_logs/1 :: (file_suffix()) -> 'ok' | {'error', any()}).
-spec(status/0 :: () ->
[{running_applications, [{atom(), string(), string()}]} |
- {nodes, [node()]} |
- {running_nodes, [node()]}]).
+ {nodes, [erlang_node()]} |
+ {running_nodes, [erlang_node()]}]).
-spec(log_location/1 :: ('sasl' | 'kernel') -> log_location()).
-endif.
diff --git a/src/rabbit_alarm.erl b/src/rabbit_alarm.erl
index d9c1c450..c2d6aaff 100644
--- a/src/rabbit_alarm.erl
+++ b/src/rabbit_alarm.erl
@@ -77,7 +77,9 @@ register(Pid, HighMemMFA) ->
%%----------------------------------------------------------------------------
init([]) ->
- {ok, #alarms{alertees = dict:new()}}.
+ HWM = system_memory_high_watermark(),
+ {ok, #alarms{alertees = dict:new(),
+ system_memory_high_watermark = HWM}}.
handle_call({register, Pid, HighMemMFA},
State = #alarms{alertees = Alertess}) ->
@@ -118,7 +120,20 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%----------------------------------------------------------------------------
-
+
+system_memory_high_watermark() ->
+ %% When we register our alarm_handler, the
+ %% system_memory_high_watermark alarm may already have gone
+ %% off. How do we find out about that? Calling
+ %% alarm_handler:get_alarms() would deadlock. So instead we ask
+ %% memsup. Unfortunately that doesn't expose a suitable API, so we
+ %% have to reach quite deeply into its internals.
+ {dictionary, D} = process_info(whereis(memsup), dictionary),
+ case lists:keysearch(system_memory_high_watermark, 1, D) of
+ {value, {_, set}} -> true;
+ _Other -> false
+ end.
+
alert(Alert, Alertees) ->
dict:fold(fun (Pid, {M, F, A}, Acc) ->
ok = erlang:apply(M, F, A ++ [Pid, Alert]),
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl
index 56d2c35d..4b318eeb 100644
--- a/src/rabbit_amqqueue.erl
+++ b/src/rabbit_amqqueue.erl
@@ -89,7 +89,7 @@
-spec(basic_cancel/4 :: (amqqueue(), pid(), ctag(), any()) -> 'ok').
-spec(notify_sent/2 :: (pid(), pid()) -> 'ok').
-spec(internal_delete/1 :: (queue_name()) -> 'ok' | not_found()).
--spec(on_node_down/1 :: (node()) -> 'ok').
+-spec(on_node_down/1 :: (erlang_node()) -> 'ok').
-spec(pseudo_queue/2 :: (binary(), pid()) -> amqqueue()).
-endif.
diff --git a/src/rabbit_amqqueue_process.erl b/src/rabbit_amqqueue_process.erl
index e687df84..f8964e34 100644
--- a/src/rabbit_amqqueue_process.erl
+++ b/src/rabbit_amqqueue_process.erl
@@ -689,7 +689,9 @@ handle_info({'DOWN', _MonitorRef, process, DownPid, _Reason}, State) ->
handle_ch_down(DownPid, State);
handle_info(timeout, State) ->
- {noreply, State, hibernate};
+ %% TODO: Once we drop support for R11B-5, we can change this to
+ %% {noreply, State, hibernate};
+ proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]);
handle_info(Info, State) ->
?LOGDEBUG("Info in queue: ~p~n", [Info]),
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index bc588279..2f7e58e0 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -26,43 +26,50 @@
-module(rabbit_control).
-include("rabbit.hrl").
--export([start/0, stop/0, action/3]).
+-export([start/0, stop/0, action/4]).
+
+-record(params, {quiet, node, command, args}).
-define(RPC_TIMEOUT, 30000).
start() ->
- case init:get_plain_arguments() of
- [] ->
+ FullCommand = init:get_plain_arguments(),
+ #params{quiet = Quiet, node = Node, command = Command, args = Args} =
+ parse_args(FullCommand, #params{quiet = false, node = rabbit_misc:localnode(rabbit)}),
+ Inform = case Quiet of
+ true -> fun(_Format, _Data) -> ok end;
+ false -> fun io:format/2
+ end,
+ case catch action(Command, Node, Args, Inform) of
+ ok ->
+ Inform("done.~n", []),
+ init:stop();
+ {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} ->
+ io:format("Error~nInvalid command ~p~n", [FullCommand]),
usage();
- FullCommand ->
- {Node, Command, Args} = parse_args(FullCommand),
- case catch action(Command, Node, Args) of
- ok ->
- io:format("done.~n"),
- init:stop();
- {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} ->
- io:format("Invalid command ~p~n", [FullCommand]),
- usage();
- Other ->
- io:format("~nrabbit_control action ~p failed:~n~p~n", [Command, Other]),
- halt(2)
- end
+ Other ->
+ io:format("Error~nrabbit_control action ~p failed:~n~p~n", [Command, Other]),
+ halt(2)
end.
-parse_args(["-n", NodeS, Command | Args]) ->
+parse_args(["-n", NodeS | Args], Params) ->
Node = case lists:member($@, NodeS) of
true -> list_to_atom(NodeS);
false -> rabbit_misc:localnode(list_to_atom(NodeS))
end,
- {Node, list_to_atom(Command), Args};
-parse_args([Command | Args]) ->
- {rabbit_misc:localnode(rabbit), list_to_atom(Command), Args}.
+ parse_args(Args, Params#params{node = Node});
+parse_args(["-q" | Args], Params) ->
+ parse_args(Args, Params#params{quiet = true});
+parse_args([Command | Args], Params) ->
+ Params#params{command = list_to_atom(Command), args = Args};
+parse_args([], _) ->
+ usage().
stop() ->
ok.
usage() ->
- io:format("Usage: rabbitmqctl [-n <node>] <command> [<arg> ...]
+ io:format("Usage: rabbitmqctl [-q] [-n <node>] <command> [<arg> ...]
Available commands:
@@ -89,6 +96,9 @@ Available commands:
list_user_vhosts <UserName>
list_vhost_users <VHostPath>
+Quiet output mode is selected with the \"-q\" flag. Informational messages
+are suppressed when quiet mode is in effect.
+
<node> should be the name of the master node of the RabbitMQ cluster. It
defaults to the node named \"rabbit\" on the local host. On a host named
\"server.example.com\", the master node will usually be rabbit@server (unless
@@ -98,95 +108,95 @@ output of hostname -s is usually the correct suffix to use after the \"@\" sign.
"),
halt(1).
-action(stop, Node, []) ->
- io:format("Stopping and halting node ~p ...", [Node]),
+action(stop, Node, [], Inform) ->
+ Inform("Stopping and halting node ~p ...~n", [Node]),
call(Node, {rabbit, stop_and_halt, []});
-action(stop_app, Node, []) ->
- io:format("Stopping node ~p ...", [Node]),
+action(stop_app, Node, [], Inform) ->
+ Inform("Stopping node ~p ...~n", [Node]),
call(Node, {rabbit, stop, []});
-action(start_app, Node, []) ->
- io:format("Starting node ~p ...", [Node]),
+action(start_app, Node, [], Inform) ->
+ Inform("Starting node ~p ...~n", [Node]),
call(Node, {rabbit, start, []});
-action(reset, Node, []) ->
- io:format("Resetting node ~p ...", [Node]),
+action(reset, Node, [], Inform) ->
+ Inform("Resetting node ~p ...~n", [Node]),
call(Node, {rabbit_mnesia, reset, []});
-action(force_reset, Node, []) ->
- io:format("Forcefully resetting node ~p ...", [Node]),
+action(force_reset, Node, [], Inform) ->
+ Inform("Forcefully resetting node ~p ...~n", [Node]),
call(Node, {rabbit_mnesia, force_reset, []});
-action(cluster, Node, ClusterNodeSs) ->
+action(cluster, Node, ClusterNodeSs, Inform) ->
ClusterNodes = lists:map(fun list_to_atom/1, ClusterNodeSs),
- io:format("Clustering node ~p with ~p ...",
+ Inform("Clustering node ~p with ~p ...~n",
[Node, ClusterNodes]),
rpc_call(Node, rabbit_mnesia, cluster, [ClusterNodes]);
-action(status, Node, []) ->
- io:format("Status of node ~p ...", [Node]),
+action(status, Node, [], Inform) ->
+ Inform("Status of node ~p ...~n", [Node]),
Res = call(Node, {rabbit, status, []}),
- io:format("~n~p~n", [Res]),
+ io:format("~p~n", [Res]),
ok;
-action(rotate_logs, Node, []) ->
- io:format("Reopening logs for node ~p ...", [Node]),
+action(rotate_logs, Node, [], Inform) ->
+ Inform("Reopening logs for node ~p ...~n", [Node]),
call(Node, {rabbit, rotate_logs, [""]});
-action(rotate_logs, Node, Args = [Suffix]) ->
- io:format("Rotating logs to files with suffix ~p ...", [Suffix]),
+action(rotate_logs, Node, Args = [Suffix], Inform) ->
+ Inform("Rotating logs to files with suffix ~p ...~n", [Suffix]),
call(Node, {rabbit, rotate_logs, Args});
-action(add_user, Node, Args = [Username, _Password]) ->
- io:format("Creating user ~p ...", [Username]),
+action(add_user, Node, Args = [Username, _Password], Inform) ->
+ Inform("Creating user ~p ...~n", [Username]),
call(Node, {rabbit_access_control, add_user, Args});
-action(delete_user, Node, Args = [_Username]) ->
- io:format("Deleting user ~p ...", Args),
+action(delete_user, Node, Args = [_Username], Inform) ->
+ Inform("Deleting user ~p ...~n", Args),
call(Node, {rabbit_access_control, delete_user, Args});
-action(change_password, Node, Args = [Username, _Newpassword]) ->
- io:format("Changing password for user ~p ...", [Username]),
+action(change_password, Node, Args = [Username, _Newpassword], Inform) ->
+ Inform("Changing password for user ~p ...~n", [Username]),
call(Node, {rabbit_access_control, change_password, Args});
-action(list_users, Node, []) ->
- io:format("Listing users ..."),
+action(list_users, Node, [], Inform) ->
+ Inform("Listing users ...~n", []),
display_list(call(Node, {rabbit_access_control, list_users, []}));
-action(add_vhost, Node, Args = [_VHostPath]) ->
- io:format("Creating vhost ~p ...", Args),
+action(add_vhost, Node, Args = [_VHostPath], Inform) ->
+ Inform("Creating vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, add_vhost, Args});
-action(delete_vhost, Node, Args = [_VHostPath]) ->
- io:format("Deleting vhost ~p ...", Args),
+action(delete_vhost, Node, Args = [_VHostPath], Inform) ->
+ Inform("Deleting vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, delete_vhost, Args});
-action(list_vhosts, Node, []) ->
- io:format("Listing vhosts ..."),
+action(list_vhosts, Node, [], Inform) ->
+ Inform("Listing vhosts ...~n", []),
display_list(call(Node, {rabbit_access_control, list_vhosts, []}));
-action(map_user_vhost, Node, Args = [_Username, _VHostPath]) ->
- io:format("Mapping user ~p to vhost ~p ...", Args),
+action(map_user_vhost, Node, Args = [_Username, _VHostPath], Inform) ->
+ Inform("Mapping user ~p to vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, map_user_vhost, Args});
-action(unmap_user_vhost, Node, Args = [_Username, _VHostPath]) ->
- io:format("Unmapping user ~p from vhost ~p ...", Args),
+action(unmap_user_vhost, Node, Args = [_Username, _VHostPath], Inform) ->
+ Inform("Unmapping user ~p from vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, unmap_user_vhost, Args});
-action(list_user_vhosts, Node, Args = [_Username]) ->
- io:format("Listing vhosts for user ~p...", Args),
+action(list_user_vhosts, Node, Args = [_Username], Inform) ->
+ Inform("Listing vhosts for user ~p...~n", Args),
display_list(call(Node, {rabbit_access_control, list_user_vhosts, Args}));
-action(list_vhost_users, Node, Args = [_VHostPath]) ->
- io:format("Listing users for vhosts ~p...", Args),
+action(list_vhost_users, Node, Args = [_VHostPath], Inform) ->
+ Inform("Listing users for vhosts ~p...~n", Args),
display_list(call(Node, {rabbit_access_control, list_vhost_users, Args})).
display_list(L) when is_list(L) ->
lists:foreach(fun (I) ->
- io:format("~n~s", [binary_to_list(I)])
+ io:format("~s~n", [binary_to_list(I)])
end,
lists:sort(L)),
- io:nl();
+ ok;
display_list(Other) -> Other.
call(Node, {Mod, Fun, Args}) ->
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index a8c54438..58b8d7d6 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -268,9 +268,17 @@ exchanges_for_queue(QueueName) ->
has_bindings(ExchangeName) ->
MatchHead = #route{binding = #binding{exchange_name = ExchangeName,
- queue_name = '$1',
_ = '_'}},
- continue(mnesia:select(route, [{MatchHead, [], ['$1']}], 1, read)).
+ try
+ continue(mnesia:select(route, [{MatchHead, [], ['$_']}], 1, read))
+ catch exit:{aborted, {badarg, _}} ->
+ %% work around OTP-7025, which was fixed in R12B-1, by
+ %% falling back on a less efficient method
+ case mnesia:match_object(MatchHead) of
+ [] -> false;
+ [_|_] -> true
+ end
+ end.
continue('$end_of_table') -> false;
continue({[_|_], _}) -> true;
diff --git a/src/rabbit_heartbeat.erl b/src/rabbit_heartbeat.erl
index 6e825578..b05a4655 100644
--- a/src/rabbit_heartbeat.erl
+++ b/src/rabbit_heartbeat.erl
@@ -67,7 +67,7 @@ heartbeater(Sock, TimeoutMillisec, StatName, Threshold, Handler, MonitorRef) ->
{'DOWN', MonitorRef, process, _Object, _Info} -> ok;
Other -> exit({unexpected_message, Other})
after TimeoutMillisec ->
- case prim_inet:getstat(Sock, [StatName]) of
+ case inet:getstat(Sock, [StatName]) of
{ok, [{StatName, NewStatVal}]} ->
if NewStatVal =/= StatVal ->
F({NewStatVal, 0});
diff --git a/src/rabbit_load.erl b/src/rabbit_load.erl
index 8deec8eb..2154bf72 100644
--- a/src/rabbit_load.erl
+++ b/src/rabbit_load.erl
@@ -34,11 +34,11 @@
-ifdef(use_specs).
--type(node() :: atom()).
--type(load() :: {{non_neg_integer(), float()}, node()}).
+-type(erlang_node() :: atom()).
+-type(load() :: {{non_neg_integer(), float()}, erlang_node()}).
-spec(local_load/0 :: () -> load()).
-spec(remote_loads/0 :: () -> [load()]).
--spec(pick/0 :: () -> node()).
+-spec(pick/0 :: () -> erlang_node()).
-endif.
diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl
index 7638af58..c1c643d3 100644
--- a/src/rabbit_misc.erl
+++ b/src/rabbit_misc.erl
@@ -85,7 +85,7 @@
-spec(with_user_and_vhost/3 :: (username(), vhost(), thunk(A)) -> A).
-spec(execute_mnesia_transaction/1 :: (thunk(A)) -> A).
-spec(ensure_ok/2 :: ('ok' | {'error', any()}, atom()) -> 'ok').
--spec(localnode/1 :: (atom()) -> node()).
+-spec(localnode/1 :: (atom()) -> erlang_node()).
-spec(tcp_name/3 :: (atom(), ip_address(), ip_port()) -> atom()).
-spec(intersperse/2 :: (A, [A]) -> [A]).
-spec(upmap/2 :: (fun ((A) -> B), [A]) -> [B]).
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index 9b67135d..8d34d285 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -40,11 +40,11 @@
-ifdef(use_specs).
--spec(status/0 :: () -> [{'nodes' | 'running_nodes', [node()]}]).
+-spec(status/0 :: () -> [{'nodes' | 'running_nodes', [erlang_node()]}]).
-spec(ensure_mnesia_dir/0 :: () -> 'ok').
-spec(init/0 :: () -> 'ok').
-spec(is_db_empty/0 :: () -> bool()).
--spec(cluster/1 :: ([node()]) -> 'ok').
+-spec(cluster/1 :: ([erlang_node()]) -> 'ok').
-spec(reset/0 :: () -> 'ok').
-spec(force_reset/0 :: () -> 'ok').
-spec(create_tables/0 :: () -> 'ok').
diff --git a/src/rabbit_networking.erl b/src/rabbit_networking.erl
index 79c927cb..a91602ab 100644
--- a/src/rabbit_networking.erl
+++ b/src/rabbit_networking.erl
@@ -45,8 +45,8 @@
-spec(start_tcp_listener/2 :: (host(), ip_port()) -> 'ok').
-spec(stop_tcp_listener/2 :: (host(), ip_port()) -> 'ok').
-spec(active_listeners/0 :: () -> [listener()]).
--spec(node_listeners/1 :: (node()) -> [listener()]).
--spec(on_node_down/1 :: (node()) -> 'ok').
+-spec(node_listeners/1 :: (erlang_node()) -> [listener()]).
+-spec(on_node_down/1 :: (erlang_node()) -> 'ok').
-spec(check_tcp_listener_address/3 :: (atom(), host(), ip_port()) ->
{ip_address(), atom()}).
diff --git a/src/rabbit_sasl_report_file_h.erl b/src/rabbit_sasl_report_file_h.erl
index 3374d63d..10e2ee6e 100644
--- a/src/rabbit_sasl_report_file_h.erl
+++ b/src/rabbit_sasl_report_file_h.erl
@@ -71,8 +71,9 @@ handle_call(Event, State) ->
terminate(Reason, State) ->
sasl_report_file_h:terminate(Reason, State).
-code_change(OldVsn, State, Extra) ->
- sasl_report_file_h:code_change(OldVsn, State, Extra).
+code_change(_OldVsn, State, _Extra) ->
+ %% There is no sasl_report_file_h:code_change/3
+ {ok, State}.
%%----------------------------------------------------------------------
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index fff02d73..db78bbcc 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -465,7 +465,7 @@ test_user_management() ->
control_action(Command, Args) -> control_action(Command, node(), Args).
control_action(Command, Node, Args) ->
- case catch rabbit_control:action(Command, Node, Args) of
+ case catch rabbit_control:action(Command, Node, Args, fun io:format/2) of
ok ->
io:format("done.~n"),
ok;