2014-04-09 00:41:11 +00:00
|
|
|
%% -------------------------------------------------------------------
|
|
|
|
%%
|
|
|
|
%% Copyright (c) 2013-2014 Basho Technologies, Inc.
|
|
|
|
%%
|
|
|
|
%% This file is provided to you under the Apache License,
|
|
|
|
%% Version 2.0 (the "License"); you may not use this file
|
|
|
|
%% except in compliance with the License. You may obtain
|
|
|
|
%% a copy of the License at
|
|
|
|
%%
|
|
|
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
%%
|
|
|
|
%% Unless required by applicable law or agreed to in writing,
|
|
|
|
%% software distributed under the License is distributed on an
|
|
|
|
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
%% KIND, either express or implied. See the License for the
|
|
|
|
%% specific language governing permissions and limitations
|
|
|
|
%% under the License.
|
|
|
|
%%
|
|
|
|
%% -------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(vnode_util).
|
|
|
|
-compile(export_all).
|
|
|
|
|
|
|
|
load(Nodes) ->
|
|
|
|
rt:load_modules_on_nodes([?MODULE], Nodes),
|
|
|
|
ok.
|
|
|
|
|
|
|
|
suspend_vnode(Node, Idx) ->
|
|
|
|
lager:info("Suspending vnode ~p/~p", [Node, Idx]),
|
|
|
|
Pid = rpc:call(Node, ?MODULE, remote_suspend_vnode, [Idx], infinity),
|
|
|
|
Pid.
|
|
|
|
|
|
|
|
remote_suspend_vnode(Idx) ->
|
|
|
|
Parent = self(),
|
|
|
|
Pid = spawn(fun() ->
|
|
|
|
{ok, Pid} = riak_core_vnode_manager:get_vnode_pid(Idx, riak_kv_vnode),
|
|
|
|
erlang:suspend_process(Pid, []),
|
|
|
|
Parent ! suspended,
|
|
|
|
receive resume ->
|
2014-04-10 19:32:32 +00:00
|
|
|
io:format("Resuming vnode :: ~p/~p~n", [node(), Idx]),
|
2014-04-09 00:41:11 +00:00
|
|
|
erlang:resume_process(Pid)
|
|
|
|
end
|
|
|
|
end),
|
|
|
|
receive suspended -> ok end,
|
|
|
|
Pid.
|
|
|
|
|
|
|
|
resume_vnode(Pid) ->
|
|
|
|
Pid ! resume.
|
2014-04-10 19:32:32 +00:00
|
|
|
|
|
|
|
kill_vnode({VIdx, VNode}) ->
|
|
|
|
lager:info("Killing vnode: ~p", [VIdx]),
|
|
|
|
Pid = vnode_pid(VNode, VIdx),
|
|
|
|
rpc:call(VNode, erlang, exit, [Pid, kill]),
|
|
|
|
ok = rt:wait_until(fun() ->
|
|
|
|
vnode_pid(VNode, VIdx) /= Pid
|
|
|
|
end).
|
|
|
|
|
|
|
|
vnode_pid(Node, Partition) ->
|
|
|
|
{ok, Pid} = rpc:call(Node, riak_core_vnode_manager, get_vnode_pid,
|
|
|
|
[Partition, riak_kv_vnode]),
|
|
|
|
Pid.
|
|
|
|
|
|
|
|
rebuild_vnode({VIdx, VNode}) ->
|
|
|
|
lager:info("Rebuild AAE tree: ~p", [VIdx]),
|
|
|
|
rebuild_aae_tree(VNode, VIdx).
|
|
|
|
|
|
|
|
rebuild_aae_tree(Node, Partition) ->
|
|
|
|
{ok, Pid} = rpc:call(Node, riak_kv_vnode, hashtree_pid, [Partition]),
|
|
|
|
Info = rpc:call(Node, riak_kv_entropy_info, compute_tree_info, []),
|
|
|
|
{_, Built} = lists:keyfind(Partition, 1, Info),
|
|
|
|
lager:info("Forcing rebuild of AAE tree for: ~b", [Partition]),
|
|
|
|
lager:info("Tree originally built at: ~p", [Built]),
|
|
|
|
rpc:call(Node, riak_kv_index_hashtree, clear, [Pid]),
|
|
|
|
ok = rt:wait_until(fun() ->
|
|
|
|
NewInfo = rpc:call(Node, riak_kv_entropy_info, compute_tree_info, []),
|
|
|
|
{_, NewBuilt} = lists:keyfind(Partition, 1, NewInfo),
|
|
|
|
NewBuilt > Built
|
|
|
|
end),
|
|
|
|
lager:info("Tree successfully rebuilt"),
|
|
|
|
ok.
|