Skip to content

Commit dfaf2e0

Browse files
MB-61292: Add cb_atomic_persistent_term
The idea is to modify encryption keys in persistent_term atomically and avoid scenarios like: 1. proc1 reads keys from disk 2. proc3 changes keys are changed on disk 3. proc2 reads keys from disk 3. proc2 writes keys to persistent_term based on #3 4. proc1 writes keys to persistent_term based on #1 (overwrites #2) Change-Id: I8d08717170e7b9c920778b7918fc74877d06bbe8 Reviewed-on: https://review.couchbase.org/c/ns_server/+/213279 Tested-by: Timofey Barmin <[email protected]> Reviewed-by: Navdeep S Boparai <[email protected]> Well-Formed: Build Bot <[email protected]>
1 parent d45c3e1 commit dfaf2e0

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
%% @author Couchbase <[email protected]>
2+
%% @copyright 2024-Present Couchbase, Inc.
3+
%%
4+
%% Use of this software is governed by the Business Source License included in
5+
%% the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
6+
%% file, in accordance with the Business Source License, use of this software
7+
%% will be governed by the Apache License, Version 2.0, included in the file
8+
%% licenses/APL2.txt.
9+
%%
10+
-module(cb_atomic_persistent_term).
11+
12+
%% API
13+
-export([start_link/0, set/2, get_or_set_if_undefined/2]).
14+
15+
%%%===================================================================
16+
%%% API
17+
%%%===================================================================
18+
19+
start_link() ->
20+
work_queue:start_link(?MODULE).
21+
22+
get_or_set_if_undefined(Name, ValueFun) ->
23+
maybe
24+
undefined ?= persistent_term:get(Name, undefined),
25+
work_queue:submit_sync_work(
26+
?MODULE,
27+
fun () ->
28+
case persistent_term:get(Name, undefined) of
29+
undefined ->
30+
case ValueFun() of
31+
{ok, Value} ->
32+
persistent_term:put(Name, Value),
33+
{ok, Value};
34+
{error, _} = Error ->
35+
Error
36+
end;
37+
Value ->
38+
{ok, Value}
39+
end
40+
end)
41+
else
42+
V -> {ok, V}
43+
end.
44+
45+
set(Name, SetFun) ->
46+
work_queue:submit_sync_work(
47+
?MODULE,
48+
fun () ->
49+
PrevValue = persistent_term:get(Name, undefined),
50+
case SetFun(PrevValue) of
51+
{set, Value, Return} ->
52+
persistent_term:put(Name, Value),
53+
Return;
54+
{ignore, Return} ->
55+
Return
56+
end
57+
end).
58+
59+
%%%===================================================================
60+
%%% Internal functions
61+
%%%===================================================================

apps/ns_server/src/ns_server_cluster_sup.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ start_link() ->
3434

3535
init([]) ->
3636
{ok, {{one_for_one, 10, 1},
37-
[{local_tasks, {local_tasks, start_link, []},
37+
[{atomic_persistent_term, {cb_atomic_persistent_term, start_link, []},
38+
permanent, 5000, worker, [cb_atomic_persistent_term]},
39+
{local_tasks, {local_tasks, start_link, []},
3840
permanent, brutal_kill, worker, [local_tasks]},
3941
{log_os_info, {log_os_info, start_link, []},
4042
transient, 1000, worker, [log_os_info]},

0 commit comments

Comments
 (0)