Skip to content

Commit 82e123e

Browse files
author
Yury Kirsanov
committed
clusterer: make use_controller a per-cluster parameter (breaking config change)
use_controller was a single global 0/1 switch that turned the controller path on, with a separate 'cluster_id' modparam list naming which clusters were controller-managed. That split was confusing: two parameters to express one intent, and 'use_controller=0' could be read as if it meant per-cluster. Collapse the two into one per-cluster parameter. Each modparam("clusterer", "use_controller", N) now registers cluster N as controller-managed (creates the pre-fork stub, flags it controller_managed so it never touches the DB, and arms the native-hijack guard). Native clusters remain defined the usual way (DB rows or static my_node_info/neighbor_node_info); a hybrid instance simply lists its controller clusters with use_controller and its native ones separately. The derived internal boolean the rest of the module keys off is unchanged, so all downstream logic (db_mode override, mirror/child-init guards, packet handling) is untouched. This is a breaking config change (hard break, no silent compatibility): - use_controller now takes a cluster_id >= 1. A bare use_controller=0 is rejected with a clear error; to disable the controller, omit the modparam. - The 'cluster_id' modparam (which existed only as the controller stub list) is removed. It is kept registered solely to fail at startup with a hint pointing to the new form, instead of a generic "unknown parameter". Docs (admin guide, tests appendix, README) updated so every example uses the per-cluster form and every cluster is explicitly defined.
1 parent 8a19310 commit 82e123e

4 files changed

Lines changed: 161 additions & 138 deletions

File tree

modules/clusterer/clusterer_mod.c

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,55 @@ int current_id = -1;
5151
int *_current_id_shm = NULL;
5252
int db_mode = 1;
5353
int clusterer_enable_rerouting = 1;
54-
int use_controller = 0;
54+
int use_controller = 0; /* derived: 1 if any controller-managed cluster is configured */
5555

56-
/* cluster_ids to pre-create when use_controller=1 */
56+
/* cluster_ids registered as controller-managed via the 'use_controller' modparam */
5757
static int cc_stub_ids[64];
5858
static int cc_stub_count = 0;
5959

60-
static int cc_add_cluster_id(modparam_t type, void *val)
60+
/* 'use_controller' modparam: each entry names one controller-managed cluster_id.
61+
* In the devel series this changed from a global 0/1 switch into a per-cluster
62+
* list - modparam("clusterer","use_controller",N) marks cluster N as
63+
* controller-managed. The derived 'use_controller' int above stays as the
64+
* "controller feature active at all" flag the rest of the module keys off. */
65+
static int cc_add_controller_cluster(modparam_t type, void *val)
6166
{
67+
int id = (int)(long)val;
68+
int i;
69+
70+
if (id <= 0) {
71+
LM_ERR("clusterer: use_controller now takes a cluster_id >= 1 "
72+
"(per-cluster); to disable the controller omit the modparam. "
73+
"Old 'use_controller=1' global configs must set use_controller "
74+
"to each controller cluster_id and drop the 'cluster_id' "
75+
"modparam\n");
76+
return -1;
77+
}
6278
if (cc_stub_count >= 64) {
63-
LM_ERR("clusterer: too many cluster_id entries\n");
79+
LM_ERR("clusterer: too many use_controller entries\n");
6480
return -1;
6581
}
66-
cc_stub_ids[cc_stub_count++] = (int)(long)val;
82+
for (i = 0; i < cc_stub_count; i++)
83+
if (cc_stub_ids[i] == id) {
84+
LM_ERR("clusterer: use_controller lists cluster_id %d twice\n", id);
85+
return -1;
86+
}
87+
cc_stub_ids[cc_stub_count++] = id;
88+
use_controller = 1; /* at least one controller-managed cluster exists */
6789
return 0;
6890
}
6991

92+
/* 'cluster_id' modparam: removed. It used to list controller-managed clusters;
93+
* that role now belongs to per-cluster 'use_controller'. Kept registered only to
94+
* fail loudly with a migration hint instead of a generic "unknown parameter". */
95+
static int cc_add_cluster_id(modparam_t type, void *val)
96+
{
97+
LM_ERR("clusterer: the 'cluster_id' modparam has been removed; register "
98+
"each controller-managed cluster with "
99+
"modparam(\"clusterer\", \"use_controller\", <cluster_id>) instead\n");
100+
return -1;
101+
}
102+
70103
str clusterer_db_url = {NULL, 0};
71104

72105
extern db_con_t *db_hdl;
@@ -176,7 +209,7 @@ static const param_export_t params[] = {
176209
{"flags_col", STR_PARAM, &flags_col.s },
177210
{"description_col", STR_PARAM, &description_col.s },
178211
{"db_mode", INT_PARAM, &db_mode },
179-
{"use_controller", INT_PARAM, &use_controller },
212+
{"use_controller", INT_PARAM|USE_FUNC_PARAM, (void*)cc_add_controller_cluster},
180213
{"cluster_id", INT_PARAM|USE_FUNC_PARAM, (void*)cc_add_cluster_id},
181214
{"neighbor_node_info", STR_PARAM|USE_FUNC_PARAM,
182215
(void*)&provision_neighbor},
@@ -527,7 +560,7 @@ static int mod_init(void)
527560
}
528561

529562
/* Controller-managed clusters: pre-create a stub for each cluster_id the
530-
* controller registered (via the 'cluster_id' modparam), so cl_register_cap()
563+
* controller registered (via the 'use_controller' modparam), so cl_register_cap()
531564
* succeeds for tm/dialog before clusterer_controller injects the real
532565
* identity. Each stub is flagged controller_managed: it never touches the DB
533566
* and behaves as db_mode=0, so it coexists with DB-native clusters. A
@@ -541,7 +574,7 @@ static int mod_init(void)
541574
for (_ex = *cluster_list; _ex; _ex = _ex->next)
542575
if (_ex->cluster_id == cc_stub_ids[_ci]) {
543576
LM_ERR("clusterer: cluster_id %d is registered as "
544-
"controller-managed (cluster_id modparam) but is "
577+
"controller-managed (use_controller modparam) but is "
545578
"already defined via native config "
546579
"(my_node_info/neighbor_node_info/DB) or listed "
547580
"twice - a cluster_id must be unique and either "

modules/clusterer_controller/README

Lines changed: 74 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ Chapter 1. Admin Guide
106106
each other automatically at startup and the cluster topology is
107107
maintained dynamically at runtime.
108108

109-
When use_controller=1 is set in the clusterer module, the
109+
When a cluster is registered as controller-managed via
110+
modparam("clusterer", "use_controller", N), the
110111
clusterer_controller module takes over all topology management:
111112
it allocates unique node IDs, discovers peer BIN socket
112113
addresses, and calls the clusterer internal API to add or
@@ -499,15 +500,17 @@ on-key")
499500
* proto_bin — required so that BIN listeners are registered
500501
and available for discovery when clusterer_controller
501502
initialises and scans the proto_bin listener list.
502-
* clusterer — required, and it must have use_controller=1
503-
set. That global switch is what pre-creates the
504-
controller-managed cluster stubs, marks them so they never
505-
touch the database, and arms the guard that stops the
506-
controller from driving a native cluster of the same id. If
507-
clusterer_controller is loaded while clusterer has
508-
use_controller=0, it refuses to start with a clear error —
509-
there is no controller-managed cluster for it to drive and
510-
those safety mechanisms would be off.
503+
* clusterer — required, and it must register at least one
504+
cluster as controller-managed with modparam("clusterer",
505+
"use_controller", N). That per-cluster parameter is what
506+
pre-creates the controller-managed cluster stubs, marks
507+
them so they never touch the database, and arms the guard
508+
that stops the controller from driving a native cluster of
509+
the same id. If clusterer_controller is loaded while
510+
clusterer has no use_controller cluster registered, it
511+
refuses to start with a clear error — there is no
512+
controller-managed cluster for it to drive and those safety
513+
mechanisms would be off.
511514

512515
Both dependencies are declared in the module's dep_export_t.
513516
OpenSIPS will refuse to start if either dependency is not
@@ -516,28 +519,29 @@ on-key")
516519
resolves the dependency at runtime and will initialize the
517520
required modules first regardless of loadmodule order.
518521

519-
The reverse is also checked: if use_controller=1 is set but the
520-
clusterer_controller module is not loaded, clusterer logs an
521-
error at startup, since the controller-managed cluster stubs
522-
would never obtain a node identity or form. clusterer itself
523-
keeps running, so any native or DB-backed clusters are
524-
unaffected.
525-
526-
Hybrid deployments are unaffected. use_controller is a single
527-
global switch; in a hybrid instance (native and
528-
controller-managed clusters side by side) it is always 1 and
529-
only the per-cluster kind differs (native via DB/static
530-
provisioning versus controller-managed via the cluster_id
531-
list). Both consistency checks above therefore only fire on a
532-
genuine module/config mismatch — never on a hybrid or
533-
pure-controller setup.
522+
The reverse is also checked: if a use_controller cluster is
523+
registered but the clusterer_controller module is not loaded,
524+
clusterer logs an error at startup, since the
525+
controller-managed cluster stubs would never obtain a node
526+
identity or form. clusterer itself keeps running, so any native
527+
or DB-backed clusters are unaffected.
528+
529+
Hybrid deployments are unaffected. use_controller is a
530+
per-cluster parameter: each entry names one controller-managed
531+
cluster id. In a hybrid instance (native and controller-managed
532+
clusters side by side), the controller-managed clusters are
533+
listed with use_controller while the native ones are defined
534+
the usual way (DB rows or static
535+
my_node_info/neighbor_node_info). Both consistency checks above
536+
therefore only fire on a genuine module/config mismatch — never
537+
on a hybrid or pure-controller setup.
534538

535539
All other modules that use the clusterer interface (tm, dialog,
536540
dispatcher, usrloc etc.) may be loaded in any order relative to
537541
clusterer_controller. The clusterer module automatically
538-
creates a cluster stub when use_controller=1 is set and a
539-
module attempts to register a capability for an unknown
540-
cluster.
542+
creates a cluster stub when a use_controller cluster is
543+
registered and a module attempts to register a capability for
544+
an unknown cluster.
541545

542546
1.5.2. External Libraries or Applications
543547

@@ -832,9 +836,10 @@ modparam("clusterer_controller", "password", "MyStr0ngPassw0rd!")
832836
...
833837
# clusters 1 and 2 registered as controller-managed on the clusterer sid
834838
e
835-
modparam("clusterer", "use_controller", 1)
836-
modparam("clusterer", "cluster_id", 1)
837-
modparam("clusterer", "cluster_id", 2)
839+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
840+
anaged
841+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
842+
anaged
838843

839844
# Enable automatic failover for every cluster (this is also the default)
840845
modparam("clusterer_controller", "manage_shtags", 1)
@@ -849,9 +854,10 @@ modparam("clusterer_controller", "cluster", "id=2,multicast=239.0.90.2:3
849854
...
850855
# clusters 1 and 2 registered as controller-managed on the clusterer sid
851856
e
852-
modparam("clusterer", "use_controller", 1)
853-
modparam("clusterer", "cluster_id", 1)
854-
modparam("clusterer", "cluster_id", 2)
857+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
858+
anaged
859+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
860+
anaged
855861

856862
# manage_shtags=1 globally, but cluster 2 uses its own MI/event-route sc
857863
ripts
@@ -866,9 +872,10 @@ modparam("clusterer_controller", "cluster",
866872
...
867873
# clusters 1 and 2 registered as controller-managed on the clusterer sid
868874
e
869-
modparam("clusterer", "use_controller", 1)
870-
modparam("clusterer", "cluster_id", 1)
871-
modparam("clusterer", "cluster_id", 2)
875+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
876+
anaged
877+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
878+
anaged
872879

873880
# Disable automatic failover globally; enable it only for cluster 1
874881
modparam("clusterer_controller", "manage_shtags", 0)
@@ -890,10 +897,8 @@ socket=bin:10.22.23.191:3857
890897
loadmodule "proto_bin.so"
891898

892899
loadmodule "clusterer.so"
893-
modparam("clusterer", "use_controller", 1) # enable the controller p
894-
ath (global switch)
895-
modparam("clusterer", "cluster_id", 1) # register cluster 1 as c
896-
ontroller-managed
900+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller
901+
-managed
897902
modparam("clusterer", "sharing_tag", "vip1/1=active")
898903
modparam("clusterer", "ping_interval", 4)
899904
modparam("clusterer", "ping_timeout", 1500)
@@ -939,9 +944,10 @@ modparam("clusterer_controller", "password", "MyStr0ngPassw0rd!")
939944
Example 1.12. Set master_stickiness parameter
940945
...
941946
# both clusters registered as controller-managed on the clusterer side
942-
modparam("clusterer", "use_controller", 1)
943-
modparam("clusterer", "cluster_id", 1)
944-
modparam("clusterer", "cluster_id", 2)
947+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
948+
anaged
949+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
950+
anaged
945951

946952
# Global default (sticky) — omit entirely for the same effect
947953
modparam("clusterer_controller", "master_stickiness", 1)
@@ -1210,12 +1216,10 @@ socket=bin:10.0.2.10:5566
12101216
loadmodule "proto_bin.so"
12111217

12121218
loadmodule "clusterer.so"
1213-
modparam("clusterer", "use_controller", 1) # enable the controller pat
1214-
h (global switch)
1215-
modparam("clusterer", "cluster_id", 1) # cluster 1 is controller-
1216-
managed
1217-
modparam("clusterer", "cluster_id", 2) # cluster 2 is controller-
1218-
managed
1219+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
1220+
anaged
1221+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
1222+
anaged
12191223

12201224
loadmodule "clusterer_controller.so"
12211225
# Cluster 1 — dialog replication group, LAN segment 10.0.1.0/24
@@ -1238,12 +1242,10 @@ socket=bin:10.22.23.191:3857
12381242
loadmodule "proto_bin.so"
12391243

12401244
loadmodule "clusterer.so"
1241-
modparam("clusterer", "use_controller", 1) # enable the controller pat
1242-
h (global switch)
1243-
modparam("clusterer", "cluster_id", 1) # cluster 1 is controller-
1244-
managed
1245-
modparam("clusterer", "cluster_id", 2) # cluster 2 is controller-
1246-
managed
1245+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
1246+
anaged
1247+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
1248+
anaged
12471249

12481250
loadmodule "clusterer_controller.so"
12491251
modparam("clusterer_controller", "cluster",
@@ -1268,11 +1270,12 @@ modparam("dispatcher", "cluster_id", 2)
12681270

12691271
Which kind a cluster is follows from how it is declared:
12701272
* Controller-managed — every cluster_id registered with the
1271-
clusterer module via modparam("clusterer", "cluster_id", N)
1272-
(and matched by a cluster entry in this module). Its
1273-
topology and this node's node_id are driven at runtime by
1274-
the controller; it never touches the database and always
1275-
behaves as db_mode=0, regardless of the global db_mode.
1273+
clusterer module via modparam("clusterer",
1274+
"use_controller", N) (and matched by a cluster entry in
1275+
this module). Its topology and this node's node_id are
1276+
driven at runtime by the controller; it never touches the
1277+
database and always behaves as db_mode=0, regardless of the
1278+
global db_mode.
12761279
* Native — every cluster loaded from the clusterer database
12771280
(db_mode!=0) or provisioned statically. It behaves exactly
12781281
as classic clusterer: fixed my_node_id, DB persistence
@@ -1315,10 +1318,8 @@ s")
13151318
modparam("clusterer", "my_node_id", 5) # this node's id in its nati
13161319
ve/DB clusters (global)
13171320
# controller side: cluster 1 is dynamic (no DB, no static rows)
1318-
modparam("clusterer", "use_controller", 1) # enable the controller path
1319-
(global switch)
1320-
modparam("clusterer", "cluster_id", 1) # register cluster 1 as con
1321-
troller-managed
1321+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-ma
1322+
naged
13221323

13231324
loadmodule "clusterer_controller.so"
13241325
modparam("clusterer_controller", "cluster",
@@ -1350,10 +1351,8 @@ modparam("clusterer", "my_node_info", "cluster_id=7, url=bin:10.0.
13501351
modparam("clusterer", "neighbor_node_info", "cluster_id=7, node_id=6, ur
13511352
l=bin:10.0.0.11:5566")
13521353
# controller side: cluster 1 is dynamic
1353-
modparam("clusterer", "use_controller", 1) # enable the contro
1354-
ller path (global switch)
1355-
modparam("clusterer", "cluster_id", 1) # register cluster
1356-
1 as controller-managed
1354+
modparam("clusterer", "use_controller", 1) # cluster 1 is cont
1355+
roller-managed
13571356

13581357
loadmodule "clusterer_controller.so"
13591358
modparam("clusterer_controller", "cluster",
@@ -1386,10 +1385,8 @@ socket=bin:10.22.23.191:3857
13861385
loadmodule "proto_bin.so"
13871386

13881387
loadmodule "clusterer.so"
1389-
modparam("clusterer", "use_controller", 1) # enable the controller p
1390-
ath (global switch)
1391-
modparam("clusterer", "cluster_id", 1) # register cluster 1 as c
1392-
ontroller-managed
1388+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller
1389+
-managed
13931390
modparam("clusterer", "sharing_tag", "vip1/1=active")
13941391
modparam("clusterer", "ping_interval", 4)
13951392
modparam("clusterer", "ping_timeout", 1500)
@@ -1667,9 +1664,10 @@ A.7. Test 6 — Multiple clusters over one BIN socket
16671664
but both advertise the same BIN socket (bin:IP:3857). Each
16681665
cluster must form independently and its replication must stay
16691666
isolated over the shared socket.
1670-
modparam("clusterer", "use_controller", 1)
1671-
modparam("clusterer", "cluster_id", 1)
1672-
modparam("clusterer", "cluster_id", 2)
1667+
modparam("clusterer", "use_controller", 1) # cluster 1 is controller-m
1668+
anaged
1669+
modparam("clusterer", "use_controller", 2) # cluster 2 is controller-m
1670+
anaged
16731671
modparam("clusterer_controller", "cluster",
16741672
"id=1,multicast=239.0.90.1:3333,bin_socket=bin:IP:3857")
16751673
modparam("clusterer_controller", "cluster",

0 commit comments

Comments
 (0)