diff options
| author | Michael Klishin <michael@clojurewerkz.org> | 2016-05-23 15:15:06 +0300 |
|---|---|---|
| committer | Michael Klishin <michael@clojurewerkz.org> | 2016-05-23 15:15:06 +0300 |
| commit | 2b9bdfd73b7157cbce9ece636d05f6916d5a3a5a (patch) | |
| tree | 40a080c495eed4e828b8d3707968466dea90c568 | |
| parent | 77332e682250f4e6a315de81abadd9e3a682e416 (diff) | |
| parent | ba88ee7f743f0abb85e09981c7d3a86f95e835c1 (diff) | |
| download | rabbitmq-server-git-2b9bdfd73b7157cbce9ece636d05f6916d5a3a5a.tar.gz | |
Merge branch 'stable' into rabbitmq-server-687
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | docs/rabbitmq-server.service.example | 3 | ||||
| -rw-r--r-- | docs/rabbitmqctl.1.xml | 27 | ||||
| -rw-r--r-- | packaging/RPMS/Fedora/rabbitmq-server.spec | 3 | ||||
| -rw-r--r-- | packaging/debs/Debian/debian/changelog | 6 | ||||
| -rw-r--r-- | rabbitmq-components.mk | 4 | ||||
| -rwxr-xr-x[-rw-r--r--] | scripts/rabbitmq-env | 1 | ||||
| -rwxr-xr-x | scripts/rabbitmq-server | 6 | ||||
| -rwxr-xr-x | scripts/rabbitmq-server-ha.ocf | 18 | ||||
| -rw-r--r-- | src/rabbit_binding.erl | 4 | ||||
| -rw-r--r-- | src/rabbit_control_main.erl | 13 | ||||
| -rw-r--r-- | src/rabbit_file.erl | 10 | ||||
| -rw-r--r-- | src/rabbit_hipe.erl | 89 | ||||
| -rw-r--r-- | src/rabbit_policy.erl | 4 |
15 files changed, 152 insertions, 39 deletions
@@ -221,6 +221,7 @@ RSYNC_FLAGS += -a $(RSYNC_V) \ --exclude 'plugins/' \ --exclude '$(notdir $(DIST_DIR))/' \ --exclude '/$(notdir $(PACKAGES_DIR))/' \ + --exclude '/PACKAGES/' \ --exclude '/cowboy/doc/' \ --exclude '/cowboy/examples/' \ --exclude '/rabbitmq_amqp1_0/test/swiftmq/build/'\ @@ -44,4 +44,4 @@ See [building RabbitMQ server from source](http://www.rabbitmq.com/build-server. ## Copyright -(c) Pivotal Software Inc., 2007-2015. +(c) Pivotal Software Inc., 2007-2016. diff --git a/docs/rabbitmq-server.service.example b/docs/rabbitmq-server.service.example index 5a8f1cd73e..1aa6549b64 100644 --- a/docs/rabbitmq-server.service.example +++ b/docs/rabbitmq-server.service.example @@ -1,7 +1,8 @@ # systemd unit example [Unit] Description=RabbitMQ broker -After=syslog.target network.target +After=network.target epmd@0.0.0.0.socket +Wants=network.target epmd@0.0.0.0.socket [Service] Type=notify diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml index 1ecf8d4d3a..ec864af6cf 100644 --- a/docs/rabbitmqctl.1.xml +++ b/docs/rabbitmqctl.1.xml @@ -290,6 +290,33 @@ </para> </listitem> </varlistentry> + + <varlistentry> + <term><cmdsynopsis><command>hipe_compile</command> <arg choice="req"><replaceable>directory</replaceable></arg></cmdsynopsis></term> + <listitem> + <para> + Performs HiPE-compilation and caches resulting + .beam-files in the given directory. + </para> + <para> + Parent directories are created if necessary. Any + existing <command>.beam</command> files from the + directory are automatically deleted prior to + compilation. + </para> + <para> + To use this precompiled files, you should set + <command>RABBITMQ_SERVER_CODE_PATH</command> environment + variable to directory specified in + <command>hipe_compile</command> invokation. + </para> + <para role="example-prefix">For example:</para> + <screen role="example">rabbitmqctl hipe_compile /tmp/rabbit-hipe/ebin</screen> + <para role="example"> + HiPE-compiles modules and stores them to /tmp/rabbit-hipe/ebin directory. + </para> + </listitem> + </varlistentry> </variablelist> </refsect2> diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec index 5996b553ae..5113de4755 100644 --- a/packaging/RPMS/Fedora/rabbitmq-server.spec +++ b/packaging/RPMS/Fedora/rabbitmq-server.spec @@ -129,6 +129,9 @@ done rm -rf %{buildroot} %changelog +* Thu May 19 2016 michael@rabbitmq.com 3.6.2-1 +- New Upstream Release + * Tue Mar 1 2016 michael@rabbitmq.com 3.6.1-1 - New Upstream Release diff --git a/packaging/debs/Debian/debian/changelog b/packaging/debs/Debian/debian/changelog index adf8ce5aa5..52459181a6 100644 --- a/packaging/debs/Debian/debian/changelog +++ b/packaging/debs/Debian/debian/changelog @@ -1,3 +1,9 @@ +rabbitmq-server (3.6.2-1) unstable; urgency=low + + * New Upstream Release + + -- Michael Klishin <michael@rabbitmq.com> Thu, 19 May 2016 09:20:06 +0100 + rabbitmq-server (3.6.1-1) unstable; urgency=low * New Upstream Release diff --git a/rabbitmq-components.mk b/rabbitmq-components.mk index b200585b30..920a67b121 100644 --- a/rabbitmq-components.mk +++ b/rabbitmq-components.mk @@ -44,6 +44,7 @@ dep_rabbitmq_event_exchange = git_rmq rabbitmq-event-exchange $(curren dep_rabbitmq_federation = git_rmq rabbitmq-federation $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_federation_management = git_rmq rabbitmq-federation-management $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_java_client = git_rmq rabbitmq-java-client $(current_rmq_ref) $(base_rmq_ref) master +dep_rabbitmq_jms_topic_exchange = git_rmq rabbitmq-jms-topic-exchange $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_lvc = git_rmq rabbitmq-lvc-plugin $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_management = git_rmq rabbitmq-management $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_management_agent = git_rmq rabbitmq-management-agent $(current_rmq_ref) $(base_rmq_ref) master @@ -62,6 +63,7 @@ dep_rabbitmq_stomp = git_rmq rabbitmq-stomp $(current_rmq_ref dep_rabbitmq_toke = git_rmq rabbitmq-toke $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_top = git_rmq rabbitmq-top $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_tracing = git_rmq rabbitmq-tracing $(current_rmq_ref) $(base_rmq_ref) master +dep_rabbitmq_trust_store = git_rmq rabbitmq-trust-store $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_test = git_rmq rabbitmq-test $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_web_dispatch = git_rmq rabbitmq-web-dispatch $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_web_stomp = git_rmq rabbitmq-web-stomp $(current_rmq_ref) $(base_rmq_ref) master @@ -99,6 +101,7 @@ RABBITMQ_COMPONENTS = amqp_client \ rabbitmq_federation \ rabbitmq_federation_management \ rabbitmq_java_client \ + rabbitmq_jms_topic_exchange \ rabbitmq_lvc \ rabbitmq_management \ rabbitmq_management_agent \ @@ -118,6 +121,7 @@ RABBITMQ_COMPONENTS = amqp_client \ rabbitmq_toke \ rabbitmq_top \ rabbitmq_tracing \ + rabbitmq_trust_store \ rabbitmq_web_dispatch \ rabbitmq_web_mqtt \ rabbitmq_web_mqtt_examples \ diff --git a/scripts/rabbitmq-env b/scripts/rabbitmq-env index 35239620ca..def47ebd27 100644..100755 --- a/scripts/rabbitmq-env +++ b/scripts/rabbitmq-env @@ -177,6 +177,7 @@ DEFAULT_NODE_PORT=5672 [ "x" = "x$RABBITMQ_MNESIA_BASE" ] && RABBITMQ_MNESIA_BASE=${MNESIA_BASE} [ "x" = "x$RABBITMQ_SERVER_START_ARGS" ] && RABBITMQ_SERVER_START_ARGS=${SERVER_START_ARGS} [ "x" = "x$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" ] && RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=${SERVER_ADDITIONAL_ERL_ARGS} +[ "x" = "x$RABBITMQ_SERVER_CODE_PATH" ] && RABBITMQ_SERVER_CODE_PATH=${SERVER_CODE_PATH} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${MNESIA_DIR} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME} diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server index ab2975feb1..74337311cd 100755 --- a/scripts/rabbitmq-server +++ b/scripts/rabbitmq-server @@ -133,11 +133,15 @@ ensure_thread_pool_size() { } start_rabbitmq_server() { + # "-pa ${RABBITMQ_SERVER_CODE_PATH}" should be the very first + # command-line argument. In case of using cached HiPE-compilation, + # this will allow for compiled versions of erlang built-in modules + # (e.g. lists) to be loaded. ensure_thread_pool_size check_start_params && RABBITMQ_CONFIG_FILE=$RABBITMQ_CONFIG_FILE \ exec ${ERL_DIR}erl \ - -pa ${RABBITMQ_EBIN_ROOT} \ + -pa ${RABBITMQ_SERVER_CODE_PATH} ${RABBITMQ_EBIN_ROOT} \ ${RABBITMQ_START_RABBIT} \ ${RABBITMQ_NAME_TYPE} ${RABBITMQ_NODENAME} \ -boot "${SASL_BOOT_FILE}" \ diff --git a/scripts/rabbitmq-server-ha.ocf b/scripts/rabbitmq-server-ha.ocf index 06eeb50837..8a2075d9f0 100755 --- a/scripts/rabbitmq-server-ha.ocf +++ b/scripts/rabbitmq-server-ha.ocf @@ -1358,18 +1358,18 @@ is_master() { # separately. The second argument is used to distingush them. check_timeouts() { local op_rc=$1 - local crm_attr_name=$2 + local timeouts_attr_name=$2 local op_name=$3 if [ $op_rc -ne 124 -a $op_rc -ne 137 ]; then - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name $crm_attr_name --update 0 + ocf_run attrd_updater -p --name $timeouts_attr_name --update 0 return 0 fi local count - count=`crm_attribute -N $THIS_PCMK_NODE -l reboot --name $crm_attr_name --query 2>/dev/null` + count=`attrd_updater --name $timeouts_attr_name --query 2>/dev/null` if [ $? -ne 0 ]; then - # the crm_attribute exited with error. In that case most probably it printed garbage + # the attrd_updater exited with error. In that case most probably it printed garbage # instead of the number we need. So defensively assume that it is zero. count=0 @@ -1378,9 +1378,9 @@ check_timeouts() { count=$((count+1)) # There is a slight chance that this piece of code will be executed twice simultaneously. - # As a result, $crm_attr_name's value will be one less than it should be. But we don't need + # As a result, $timeouts_attr_name's value will be one less than it should be. But we don't need # precise calculation here. - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name $crm_attr_name --update $count + ocf_run attrd_updater -p --name $timeouts_attr_name --update $count if [ $count -lt $OCF_RESKEY_max_rabbitmqctl_timeouts ]; then ocf_log warn "${LH} 'rabbitmqctl $op_name' timed out $count of max. $OCF_RESKEY_max_rabbitmqctl_timeouts time(s) in a row. Doing nothing for now." @@ -1670,9 +1670,9 @@ action_start() { return $OCF_SUCCESS fi - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit_list_channels_timeouts' --update '0' - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit_get_alarms_timeouts' --update '0' - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit_list_queues_timeouts' --update '0' + ocf_run attrd_updater -p --name 'rabbit_list_channels_timeouts' --update '0' + ocf_run attrd_updater -p --name 'rabbit_get_alarms_timeouts' --update '0' + ocf_run attrd_updater -p --name 'rabbit_list_queues_timeouts' --update '0' ocf_log info "${LH} Deleting start time attribute" ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --delete ocf_log info "${LH} Deleting master attribute" diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl index 299e254c50..8904c1dd74 100644 --- a/src/rabbit_binding.erl +++ b/src/rabbit_binding.erl @@ -100,7 +100,8 @@ -define(INFO_KEYS, [source_name, source_kind, destination_name, destination_kind, - routing_key, arguments]). + routing_key, arguments, + vhost]). recover(XNames, QNames) -> rabbit_misc:table_filter( @@ -272,6 +273,7 @@ infos(Items, B) -> [{Item, i(Item, B)} || Item <- Items]. i(source_name, #binding{source = SrcName}) -> SrcName#resource.name; i(source_kind, #binding{source = SrcName}) -> SrcName#resource.kind; +i(vhost, #binding{source = SrcName}) -> SrcName#resource.virtual_host; i(destination_name, #binding{destination = DstName}) -> DstName#resource.name; i(destination_kind, #binding{destination = DstName}) -> DstName#resource.kind; i(routing_key, #binding{key = RoutingKey}) -> RoutingKey; diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index f63694b657..2df4fd96c0 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -37,6 +37,7 @@ reset, force_reset, rotate_logs, + hipe_compile, {join_cluster, [?RAM_DEF]}, change_cluster_node_type, @@ -113,7 +114,7 @@ [stop, stop_app, start_app, wait, reset, force_reset, rotate_logs, join_cluster, change_cluster_node_type, update_cluster_nodes, forget_cluster_node, rename_cluster_node, cluster_status, status, - environment, eval, force_boot, help, node_health_check]). + environment, eval, force_boot, help, node_health_check, hipe_compile]). -define(COMMANDS_WITH_TIMEOUT, [list_user_permissions, list_policies, list_queues, list_exchanges, @@ -383,6 +384,16 @@ action(rotate_logs, Node, Args = [Suffix], _Opts, Inform) -> Inform("Rotating logs to files with suffix \"~s\"", [Suffix]), call(Node, {rabbit, rotate_logs, Args}); +action(hipe_compile, _Node, [TargetDir], _Opts, _Inform) -> + ok = application:load(rabbit), + case rabbit_hipe:can_hipe_compile() of + true -> + {ok, _, _} = rabbit_hipe:compile_to_directory(TargetDir), + ok; + false -> + {error, "HiPE compilation is not supported"} + end; + action(close_connection, Node, [PidStr, Explanation], _Opts, Inform) -> Inform("Closing connection \"~s\"", [PidStr]), rpc_call(Node, rabbit_networking, close_connection, diff --git a/src/rabbit_file.erl b/src/rabbit_file.erl index 6c4f0e5ccd..1088f2c2dd 100644 --- a/src/rabbit_file.erl +++ b/src/rabbit_file.erl @@ -23,6 +23,7 @@ -export([append_file/2, ensure_parent_dirs_exist/1]). -export([rename/2, delete/1, recursive_delete/1, recursive_copy/2]). -export([lock_file/1]). +-export([filename_as_a_directory/1]). -import(file_handle_cache, [with_handle/1, with_handle/2]). @@ -58,6 +59,7 @@ (file:filename(), file:filename()) -> rabbit_types:ok_or_error({file:filename(), file:filename(), any()})). -spec(lock_file/1 :: (file:filename()) -> rabbit_types:ok_or_error('eexist')). +-spec(filename_as_a_directory/1 :: (file:filename()) -> file:filename()). -endif. @@ -305,3 +307,11 @@ lock_file(Path) -> ok = prim_file:close(Lock) end) end. + +filename_as_a_directory(FileName) -> + case lists:last(FileName) of + "/" -> + FileName; + _ -> + FileName ++ "/" + end. diff --git a/src/rabbit_hipe.erl b/src/rabbit_hipe.erl index 05b5f3719d..d4597d4efc 100644 --- a/src/rabbit_hipe.erl +++ b/src/rabbit_hipe.erl @@ -5,15 +5,15 @@ %% practice 2 processes seems just as fast as any other number > 1, %% and keeps the progress bar realistic-ish. -define(HIPE_PROCESSES, 2). --export([maybe_hipe_compile/0, log_hipe_result/1]). -%% HiPE compilation happens before we have log handlers - so we have -%% to io:format/2, it's all we can do. +-export([maybe_hipe_compile/0, log_hipe_result/1]). +-export([compile_to_directory/1]). +-export([can_hipe_compile/0]). +%% Compile and load during server startup sequence maybe_hipe_compile() -> {ok, Want} = application:get_env(rabbit, hipe_compile), - Can = code:which(hipe) =/= non_existing, - case {Want, Can} of + case {Want, can_hipe_compile()} of {true, true} -> hipe_compile(); {true, false} -> false; {false, _} -> {ok, disabled} @@ -33,38 +33,49 @@ log_hipe_result(false) -> rabbit_log:warning( "Not HiPE compiling: HiPE not found in this Erlang installation.~n"). +hipe_compile() -> + hipe_compile(fun compile_and_load/1, false). + +compile_to_directory(Dir0) -> + Dir = rabbit_file:filename_as_a_directory(Dir0), + ok = prepare_ebin_directory(Dir), + hipe_compile(fun (Mod) -> compile_and_save(Mod, Dir) end, true). + +needs_compilation(Mod, Force) -> + Exists = code:which(Mod) =/= non_existing, + %% We skip modules already natively compiled. This + %% happens when RabbitMQ is stopped (just the + %% application, not the entire node) and started + %% again. + NotYetCompiled = not already_hipe_compiled(Mod), + NotVersioned = not compiled_with_version_support(Mod), + Exists andalso (Force orelse (NotYetCompiled andalso NotVersioned)). + %% HiPE compilation happens before we have log handlers and can take a %% long time, so make an exception to our no-stdout policy and display %% progress via stdout. -hipe_compile() -> +hipe_compile(CompileFun, Force) -> {ok, HipeModulesAll} = application:get_env(rabbit, hipe_modules), - HipeModules = [HM || HM <- HipeModulesAll, - code:which(HM) =/= non_existing andalso - %% We skip modules already natively compiled. This - %% happens when RabbitMQ is stopped (just the - %% application, not the entire node) and started - %% again. - already_hipe_compiled(HM) - andalso (not compiled_with_version_support(HM))], + HipeModules = lists:filter(fun(Mod) -> needs_compilation(Mod, Force) end, HipeModulesAll), case HipeModules of [] -> {ok, already_compiled}; - _ -> do_hipe_compile(HipeModules) + _ -> do_hipe_compile(HipeModules, CompileFun) end. already_hipe_compiled(Mod) -> try %% OTP 18.x or later - Mod:module_info(native) =:= false + Mod:module_info(native) =:= true %% OTP prior to 18.x catch error:badarg -> - code:is_module_native(Mod) =:= false + code:is_module_native(Mod) =:= true end. compiled_with_version_support(Mod) -> proplists:get_value(erlang_version_support, Mod:module_info(attributes)) =/= undefined. -do_hipe_compile(HipeModules) -> +do_hipe_compile(HipeModules, CompileFun) -> Count = length(HipeModules), io:format("~nHiPE compiling: |~s|~n |", [string:copies("-", Count)]), @@ -79,11 +90,7 @@ do_hipe_compile(HipeModules) -> %% advanced API does not load automatically the code, except if the %% 'load' option is set. PidMRefs = [spawn_monitor(fun () -> [begin - {M, Beam, _} = - code:get_object_code(M), - {ok, _} = - hipe:compile(M, [], Beam, - [o3, load]), + CompileFun(M), io:format("#") end || M <- Ms] end) || @@ -101,3 +108,39 @@ split(L, N) -> split0(L, [[] || _ <- lists:seq(1, N)]). split0([], Ls) -> Ls; split0([I | Is], [L | Ls]) -> split0(Is, Ls ++ [[I | L]]). + +prepare_ebin_directory(Dir) -> + ok = rabbit_file:ensure_dir(Dir), + ok = delete_beam_files(Dir), + ok. + +delete_beam_files(Dir) -> + {ok, Files} = file:list_dir(Dir), + lists:foreach(fun(File) -> + case filename:extension(File) of + ".beam" -> + ok = file:delete(filename:join([Dir, File])); + _ -> + ok + end + end, + Files). + +compile_and_load(Mod) -> + {Mod, Beam, _} = code:get_object_code(Mod), + {ok, _} = hipe:compile(Mod, [], Beam, [o3, load]). + +compile_and_save(Module, Dir) -> + {Module, BeamCode, _} = code:get_object_code(Module), + BeamName = filename:join([Dir, atom_to_list(Module) ++ ".beam"]), + {ok, {Architecture, NativeCode}} = hipe:compile(Module, [], BeamCode, [o3]), + {ok, _, Chunks0} = beam_lib:all_chunks(BeamCode), + ChunkName = hipe_unified_loader:chunk_name(Architecture), + Chunks1 = lists:keydelete(ChunkName, 1, Chunks0), + Chunks = Chunks1 ++ [{ChunkName,NativeCode}], + {ok, BeamPlusNative} = beam_lib:build_module(Chunks), + ok = file:write_file(BeamName, BeamPlusNative), + BeamName. + +can_hipe_compile() -> + code:which(hipe) =/= non_existing. diff --git a/src/rabbit_policy.erl b/src/rabbit_policy.erl index d04551043e..eb8cf63327 100644 --- a/src/rabbit_policy.erl +++ b/src/rabbit_policy.erl @@ -221,11 +221,11 @@ validate(_VHost, <<"policy">>, Name, Term, _User) -> Name, policy_validation(), Term). notify(VHost, <<"policy">>, Name, Term) -> - rabbit_event:notify(policy_set, [{name, Name} | Term]), + rabbit_event:notify(policy_set, [{name, Name}, {vhost, VHost} | Term]), update_policies(VHost). notify_clear(VHost, <<"policy">>, Name) -> - rabbit_event:notify(policy_cleared, [{name, Name}]), + rabbit_event:notify(policy_cleared, [{name, Name}, {vhost, VHost}]), update_policies(VHost). %%---------------------------------------------------------------------------- |
