Skip to content

Commit 9962772

Browse files
mon/MgrMonitor: allow disabling always-on MGR modules
Add a new command ("ceph mgr module force disable <module>") that allows forcibly disabling an always-on module. This command should ideally only be used to for cluster recovery. Fixes: https://tracker.ceph.com/issues/66005 Signed-off-by: Rishabh Dave <[email protected]>
1 parent 4374ac7 commit 9962772

File tree

4 files changed

+102
-7
lines changed

4 files changed

+102
-7
lines changed

src/mgr/PyModuleRegistry.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ bool PyModuleRegistry::handle_mgr_map(const MgrMap &mgr_map_)
151151
return false;
152152
} else {
153153
bool modules_changed = mgr_map_.modules != mgr_map.modules ||
154-
mgr_map_.always_on_modules != mgr_map.always_on_modules;
154+
mgr_map_.always_on_modules != mgr_map.always_on_modules ||
155+
mgr_map_.force_disabled_modules != mgr_map.force_disabled_modules;
155156
mgr_map = mgr_map_;
156157

157158
if (standby_modules != nullptr) {
@@ -240,6 +241,16 @@ void PyModuleRegistry::active_start(
240241
// Anything we're skipping because of !can_run will be flagged
241242
// to the user separately via get_health_checks
242243
if (!(i.second->is_enabled() && i.second->is_loaded())) {
244+
dout(8) << __func__ << " Not starting module '" << i.first << "', it is "
245+
<< "not enabled and loaded" << dendl;
246+
continue;
247+
}
248+
249+
// These are always-on modules but user force-disabled them.
250+
if (mgr_map.force_disabled_modules.find(i.first) !=
251+
mgr_map.force_disabled_modules.end()) {
252+
dout(8) << __func__ << " Not starting module '" << i.first << "', it is "
253+
<< "force-disabled" << dendl;
243254
continue;
244255
}
245256

src/mon/MgrMap.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,9 @@ class MgrMap
297297
// active version.
298298
std::map<uint32_t, std::set<std::string>> always_on_modules;
299299

300+
// Modules which are always-on but have been force-disabled by user.
301+
std::set<std::string> force_disabled_modules;
302+
300303
// Modules which are reported to exist
301304
std::vector<ModuleInfo> available_modules;
302305

@@ -448,7 +451,7 @@ class MgrMap
448451
ENCODE_FINISH(bl);
449452
return;
450453
}
451-
ENCODE_START(13, 6, bl);
454+
ENCODE_START(14, 6, bl);
452455
encode(epoch, bl);
453456
encode(active_addrs, bl, features);
454457
encode(active_gid, bl);
@@ -473,13 +476,14 @@ class MgrMap
473476
encode(clients_addrs, bl, features);
474477
encode(clients_names, bl, features);
475478
encode(flags, bl);
479+
encode(force_disabled_modules, bl);
476480
ENCODE_FINISH(bl);
477481
return;
478482
}
479483

480484
void decode(ceph::buffer::list::const_iterator& p)
481485
{
482-
DECODE_START(13, p);
486+
DECODE_START(14, p);
483487
decode(epoch, p);
484488
decode(active_addrs, p);
485489
decode(active_gid, p);
@@ -549,6 +553,11 @@ class MgrMap
549553
if (struct_v >= 13) {
550554
decode(flags, p);
551555
}
556+
557+
if (struct_v >= 14) {
558+
decode(force_disabled_modules, p);
559+
}
560+
552561
DECODE_FINISH(p);
553562
}
554563

@@ -603,6 +612,13 @@ class MgrMap
603612
f->close_section();
604613
}
605614
f->close_section(); // always_on_modules
615+
616+
f->open_object_section("force_disabled_modules");
617+
for (auto& m : force_disabled_modules) {
618+
f->dump_string("module", m);
619+
}
620+
f->close_section();
621+
606622
f->dump_int("last_failure_osd_epoch", last_failure_osd_epoch);
607623
f->open_array_section("active_clients");
608624
for (const auto& i : clients) {

src/mon/MgrMonitor.cc

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,13 @@ bool MgrMonitor::preprocess_command(MonOpRequestRef op)
10211021
f->dump_string("module", p);
10221022
}
10231023
f->close_section();
1024+
1025+
f->open_array_section("force_disabled_modules");
1026+
for (auto& p : map.force_disabled_modules) {
1027+
f->dump_string("module", p);
1028+
}
1029+
f->close_section();
1030+
10241031
f->open_array_section("enabled_modules");
10251032
for (auto& p : map.modules) {
10261033
if (map.get_always_on_modules().count(p) > 0)
@@ -1050,7 +1057,11 @@ bool MgrMonitor::preprocess_command(MonOpRequestRef op)
10501057

10511058
for (auto& p : map.get_always_on_modules()) {
10521059
tbl << p;
1053-
tbl << "on (always on)";
1060+
if (map.force_disabled_modules.find(p) == map.force_disabled_modules.end()) {
1061+
tbl << "on (always on)";
1062+
} else {
1063+
tbl << "off (always on but force-disabled)";
1064+
}
10541065
tbl << TextTable::endrow;
10551066
}
10561067
for (auto& p : map.modules) {
@@ -1271,10 +1282,13 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op)
12711282
r = -EINVAL;
12721283
goto out;
12731284
}
1274-
if (pending_map.get_always_on_modules().count(module) > 0) {
1285+
1286+
if (pending_map.get_always_on_modules().count(module) > 0 &&
1287+
!pending_map.force_disabled_modules.contains(module)) {
12751288
ss << "module '" << module << "' is already enabled (always-on)";
12761289
goto out;
12771290
}
1291+
12781292
bool force = false;
12791293
cmd_getval_compat_cephbool(cmdmap, "force", force);
12801294
if (!pending_map.all_support_module(module) &&
@@ -1298,7 +1312,12 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op)
12981312
ss << "module '" << module << "' is already enabled";
12991313
r = 0;
13001314
goto out;
1315+
} else if (pending_map.force_disabled_modules.contains(module)) {
1316+
pending_map.force_disabled_modules.erase(module);
1317+
r = 0;
1318+
goto out;
13011319
}
1320+
13021321
pending_map.modules.insert(module);
13031322
} else if (prefix == "mgr module disable") {
13041323
string module;
@@ -1308,8 +1327,9 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op)
13081327
goto out;
13091328
}
13101329
if (pending_map.get_always_on_modules().count(module) > 0) {
1311-
ss << "module '" << module << "' cannot be disabled (always-on)";
1312-
r = -EINVAL;
1330+
ss << "module '" << module << "' cannot be disabled (always-on), use " <<
1331+
"'ceph mgr module force disable' command to disable an always-on module";
1332+
r = -EPERM;
13131333
goto out;
13141334
}
13151335
if (!pending_map.module_enabled(module)) {
@@ -1322,6 +1342,50 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op)
13221342
}
13231343
dout(8) << __func__ << " disabling module " << module << " from new " << dendl;
13241344
pending_map.modules.erase(module);
1345+
} else if (prefix == "mgr module force disable") {
1346+
string mod;
1347+
cmd_getval(cmdmap, "module", mod);
1348+
1349+
bool confirmation_flag = false;
1350+
cmd_getval(cmdmap, "yes_i_really_mean_it", confirmation_flag);
1351+
1352+
if (mod.empty()) {
1353+
ss << "Module name wasn't passed!";
1354+
r = -EINVAL;
1355+
goto out;
1356+
}
1357+
1358+
if (!pending_map.get_always_on_modules().contains(mod)) {
1359+
ss << "Always-on module named \"" << mod << "\" does not exist";
1360+
r = -EINVAL;
1361+
goto out;
1362+
} else if (pending_map.modules.contains(mod)) {
1363+
ss << "Module '" << mod << "' is not an always-on module, only always-on " <<
1364+
"modules can be disabled through this command.";
1365+
r = -EINVAL;
1366+
goto out;
1367+
}
1368+
1369+
if (pending_map.force_disabled_modules.contains(mod)) {
1370+
ss << "Module \"" << mod << "\"is already disabled";
1371+
r = 0;
1372+
goto out;
1373+
}
1374+
1375+
if (!confirmation_flag) {
1376+
ss << "This command will disable operations and remove commands that "
1377+
<< "other Ceph utilities expect to be available. Do not continue "
1378+
<< "unless your cluster is already experiencing an event due to "
1379+
<< "which it is advised to disable this module as part of "
1380+
<< "troubleshooting. If you are sure that you wish to continue, "
1381+
<< "run again with --yes-i-really-mean-it";
1382+
r = -EPERM;
1383+
goto out;
1384+
}
1385+
1386+
dout(8) << __func__ << " force-disabling module '" << mod << "'" << dendl;
1387+
pending_map.force_disabled_modules.insert(mod);
1388+
pending_map.modules.erase(mod);
13251389
} else {
13261390
ss << "Command '" << prefix << "' not implemented!";
13271391
r = -ENOSYS;

src/mon/MonCommands.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,10 @@ COMMAND("mgr module enable "
13571357
COMMAND("mgr module disable "
13581358
"name=module,type=CephString",
13591359
"disable mgr module", "mgr", "rw")
1360+
COMMAND("mgr module force disable "
1361+
"name=module,type=CephString "
1362+
"name=yes_i_really_mean_it,type=CephBool,req=false",
1363+
"force disable a always-on mgr module", "mgr", "rw")
13601364
COMMAND("mgr metadata name=who,type=CephString,req=false",
13611365
"dump metadata for all daemons or a specific daemon",
13621366
"mgr", "r")

0 commit comments

Comments
 (0)