| 1392 | } |
| 1393 | |
| 1394 | PyObject *ActivePyModules::get_foreign_config( |
| 1395 | const std::string& who, |
| 1396 | const std::string& name) |
| 1397 | { |
| 1398 | dout(10) << "ceph_foreign_option_get " << who << " " << name << dendl; |
| 1399 | |
| 1400 | // NOTE: for now this will only work with build-in options, not module options. |
| 1401 | const Option *opt = g_conf().find_option(name); |
| 1402 | if (!opt) { |
| 1403 | dout(4) << "ceph_foreign_option_get " << name << " not found " << dendl; |
| 1404 | PyErr_Format(PyExc_KeyError, "option not found: %s", name.c_str()); |
| 1405 | return nullptr; |
| 1406 | } |
| 1407 | |
| 1408 | // If the monitors are not yet running pacific, we cannot rely on our local |
| 1409 | // ConfigMap |
| 1410 | if (!have_local_config_map) { |
| 1411 | dout(20) << "mon cluster wasn't pacific when we started: falling back to 'config get'" |
| 1412 | << dendl; |
| 1413 | without_gil_t no_gil; |
| 1414 | Command cmd; |
| 1415 | { |
| 1416 | std::lock_guard l(lock); |
| 1417 | cmd.run( |
| 1418 | &monc, |
| 1419 | "{\"prefix\": \"config get\","s + |
| 1420 | "\"who\": \""s + who + "\","s + |
| 1421 | "\"key\": \""s + name + "\"}"); |
| 1422 | } |
| 1423 | cmd.wait(); |
| 1424 | dout(10) << "ceph_foreign_option_get (mon command) " << who << " " << name << " = " |
| 1425 | << cmd.outbl.to_str() << dendl; |
| 1426 | no_gil.acquire_gil(); |
| 1427 | return get_python_typed_option_value(opt->type, cmd.outbl.to_str()); |
| 1428 | } |
| 1429 | |
| 1430 | // mimic the behavor of mon/ConfigMonitor's 'config get' command |
| 1431 | EntityName entity; |
| 1432 | if (!entity.from_str(who) && |
| 1433 | !entity.from_str(who + ".")) { |
| 1434 | dout(5) << "unrecognized entity '" << who << "'" << dendl; |
| 1435 | PyErr_Format(PyExc_KeyError, "invalid entity: %s", who.c_str()); |
| 1436 | return nullptr; |
| 1437 | } |
| 1438 | |
| 1439 | without_gil_t no_gil; |
| 1440 | lock.lock(); |
| 1441 | |
| 1442 | // FIXME: this is super inefficient, since we generate the entire daemon |
| 1443 | // config just to extract one value from it! |
| 1444 | |
| 1445 | std::map<std::string,std::string,std::less<>> config; |
| 1446 | cluster_state.with_osdmap([&](const OSDMap &osdmap) { |
| 1447 | std::map<string,string> crush_location; |
| 1448 | string device_class; |
| 1449 | if (entity.is_osd()) { |
| 1450 | osdmap.crush->get_full_location(who, &crush_location); |
| 1451 | int id = atoi(entity.get_id().c_str()); |
no test coverage detected