1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
7 * Copyright (C) 2017 OVH
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
16 #include "common/ceph_context.h"
23 #include <boost/algorithm/string.hpp>
25 #include "include/common_fwd.h"
26 #include "include/mempool.h"
27 #include "include/stringify.h"
28 #include "common/admin_socket.h"
29 #include "common/code_environment.h"
30 #include "common/ceph_mutex.h"
31 #include "common/debug.h"
32 #include "common/config.h"
33 #include "common/ceph_crypto.h"
34 #include "common/hostname.h"
35 #include "common/HeartbeatMap.h"
36 #include "common/errno.h"
37 #include "common/Graylog.h"
38 #ifdef CEPH_DEBUG_MUTEX
39 #include "common/lockdep.h"
44 #include "auth/Crypto.h"
45 #include "include/str_list.h"
46 #include "common/config.h"
47 #include "common/config_obs.h"
48 #include "common/PluginRegistry.h"
49 #include "common/valgrind.h"
50 #include "include/spinlock.h"
51 #if !(defined(WITH_SEASTAR) && !defined(WITH_ALIEN))
52 #include "mon/MonMap.h"
56 #include "common/common_init.h"
61 using namespace std::literals
;
63 using ceph::bufferlist
;
64 using ceph::HeartbeatMap
;
67 #if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
68 namespace crimson::common
{
69 CephContext::CephContext()
70 : _conf
{crimson::common::local_conf()},
71 _perf_counters_collection
{crimson::common::local_perf_coll()},
72 _crypto_random
{std::make_unique
<CryptoRandom
>()}
75 // define the dtor in .cc as CryptoRandom is an incomplete type in the header
76 CephContext::~CephContext()
79 uint32_t CephContext::get_module_type() const
81 return CEPH_ENTITY_TYPE_OSD
;
84 CryptoRandom
* CephContext::random() const
86 return _crypto_random
.get();
89 CephContext
* CephContext::get()
95 void CephContext::put()
102 PerfCountersCollectionImpl
* CephContext::get_perfcounters_collection()
104 return _perf_counters_collection
.get_perf_collection();
108 #else // WITH_SEASTAR
111 #ifdef CEPH_DEBUG_MUTEX
112 class LockdepObs
: public md_config_obs_t
{
114 explicit LockdepObs(CephContext
*cct
)
115 : m_cct(cct
), m_registered(false), lock(ceph::make_mutex("lock_dep_obs")) {
117 ~LockdepObs() override
{
119 lockdep_unregister_ceph_context(m_cct
);
123 const char** get_tracked_conf_keys() const override
{
124 static const char *KEYS
[] = {"lockdep", NULL
};
128 void handle_conf_change(const ConfigProxy
& conf
,
129 const std::set
<std::string
> &changed
) override
{
130 std::unique_lock
locker(lock
);
131 if (conf
->lockdep
&& !m_registered
) {
132 lockdep_register_ceph_context(m_cct
);
134 } else if (!conf
->lockdep
&& m_registered
) {
135 lockdep_unregister_ceph_context(m_cct
);
136 m_registered
= false;
144 #endif // CEPH_DEBUG_MUTEX
146 class MempoolObs
: public md_config_obs_t
,
147 public AdminSocketHook
{
152 explicit MempoolObs(CephContext
*cct
)
153 : cct(cct
), lock(ceph::make_mutex("mem_pool_obs")) {
154 cct
->_conf
.add_observer(this);
155 int r
= cct
->get_admin_socket()->register_command(
158 "get mempool stats");
161 ~MempoolObs() override
{
162 cct
->_conf
.remove_observer(this);
163 cct
->get_admin_socket()->unregister_commands(this);
167 const char** get_tracked_conf_keys() const override
{
168 static const char *KEYS
[] = {
175 void handle_conf_change(const ConfigProxy
& conf
,
176 const std::set
<std::string
> &changed
) override
{
177 std::unique_lock
locker(lock
);
178 if (changed
.count("mempool_debug")) {
179 mempool::set_debug_mode(cct
->_conf
->mempool_debug
);
184 int call(std::string_view command
, const cmdmap_t
& cmdmap
,
185 const bufferlist
& inbl
,
188 bufferlist
& out
) override
{
189 if (command
== "dump_mempools") {
190 f
->open_object_section("mempools");
199 } // anonymous namespace
201 namespace ceph::common
{
202 class CephContextServiceThread
: public Thread
205 explicit CephContextServiceThread(CephContext
*cct
)
206 : _reopen_logs(false), _exit_thread(false), _cct(cct
)
210 ~CephContextServiceThread() override
{}
212 void *entry() override
215 std::unique_lock
l(_lock
);
220 if (_cct
->_conf
->heartbeat_interval
) {
221 auto interval
= ceph::make_timespan(_cct
->_conf
->heartbeat_interval
);
222 _cond
.wait_for(l
, interval
);
231 _cct
->_log
->reopen_log_file();
232 _reopen_logs
= false;
234 _cct
->_heartbeat_map
->check_touch_file();
236 // refresh the perf coutners
237 _cct
->_refresh_perf_values();
244 std::lock_guard
l(_lock
);
251 std::lock_guard
l(_lock
);
257 ceph::mutex _lock
= ceph::make_mutex("CephContextServiceThread::_lock");
258 ceph::condition_variable _cond
;
266 * observe logging config changes
268 * The logging subsystem sits below most of the ceph code, including
269 * the config subsystem, to keep it simple and self-contained. Feed
270 * logging-related config changes to the log.
272 class LogObs
: public md_config_obs_t
{
273 ceph::logging::Log
*log
;
277 explicit LogObs(ceph::logging::Log
*l
)
278 : log(l
), lock(ceph::make_mutex("log_obs")) {
281 const char** get_tracked_conf_keys() const override
{
282 static const char *KEYS
[] = {
298 "log_coarse_timestamps",
306 void handle_conf_change(const ConfigProxy
& conf
,
307 const std::set
<std::string
> &changed
) override
{
308 std::unique_lock
locker(lock
);
310 if (changed
.count("log_to_stderr") || changed
.count("err_to_stderr")) {
311 int l
= conf
->log_to_stderr
? 99 : (conf
->err_to_stderr
? -1 : -2);
312 log
->set_stderr_level(l
, l
);
316 if (changed
.count("log_to_syslog")) {
317 int l
= conf
->log_to_syslog
? 99 : (conf
->err_to_syslog
? -1 : -2);
318 log
->set_syslog_level(l
, l
);
322 if (changed
.count("log_file") ||
323 changed
.count("log_to_file")) {
324 if (conf
->log_to_file
) {
325 log
->set_log_file(conf
->log_file
);
327 log
->set_log_file({});
329 log
->reopen_log_file();
332 if (changed
.count("log_stderr_prefix")) {
333 log
->set_log_stderr_prefix(conf
.get_val
<std::string
>("log_stderr_prefix"));
336 if (changed
.count("log_max_new")) {
338 log
->set_max_new(conf
->log_max_new
);
341 if (changed
.count("log_max_recent")) {
342 log
->set_max_recent(conf
->log_max_recent
);
346 if (changed
.count("log_to_graylog") || changed
.count("err_to_graylog")) {
347 int l
= conf
->log_to_graylog
? 99 : (conf
->err_to_graylog
? -1 : -2);
348 log
->set_graylog_level(l
, l
);
350 if (conf
->log_to_graylog
|| conf
->err_to_graylog
) {
351 log
->start_graylog(conf
->host
, conf
.get_val
<uuid_d
>("fsid"));
352 } else if (! (conf
->log_to_graylog
&& conf
->err_to_graylog
)) {
357 if (log
->graylog() && (changed
.count("log_graylog_host") || changed
.count("log_graylog_port"))) {
358 log
->graylog()->set_destination(conf
->log_graylog_host
, conf
->log_graylog_port
);
362 if (changed
.count("log_to_journald") || changed
.count("err_to_journald")) {
363 int l
= conf
.get_val
<bool>("log_to_journald") ? 99 : (conf
.get_val
<bool>("err_to_journald") ? -1 : -2);
364 log
->set_journald_level(l
, l
);
367 log
->start_journald_logger();
369 log
->stop_journald_logger();
373 if (changed
.find("log_coarse_timestamps") != changed
.end()) {
374 log
->set_coarse_timestamps(conf
.get_val
<bool>("log_coarse_timestamps"));
378 if (log
->graylog() && changed
.count("host")) {
379 log
->graylog()->set_hostname(conf
->host
);
382 if (log
->graylog() && changed
.count("fsid")) {
383 log
->graylog()->set_fsid(conf
.get_val
<uuid_d
>("fsid"));
389 namespace ceph::common
{
390 // cct config watcher
391 class CephContextObs
: public md_config_obs_t
{
395 explicit CephContextObs(CephContext
*cct
) : cct(cct
) {}
397 const char** get_tracked_conf_keys() const override
{
398 static const char *KEYS
[] = {
399 "enable_experimental_unrecoverable_data_corrupting_features",
401 "container_image", // just so we don't hear complaints about it!
407 void handle_conf_change(const ConfigProxy
& conf
,
408 const std::set
<std::string
> &changed
) override
{
410 "enable_experimental_unrecoverable_data_corrupting_features")) {
411 std::lock_guard
lg(cct
->_feature_lock
);
413 cct
->_experimental_features
.clear();
414 auto add_experimental_feature
= [this] (auto feature
) {
415 cct
->_experimental_features
.emplace(std::string
{feature
});
417 for_each_substr(conf
->enable_experimental_unrecoverable_data_corrupting_features
,
418 ";,= \t", add_experimental_feature
);
420 if (getenv("CEPH_DEV") == NULL
) {
421 if (!cct
->_experimental_features
.empty()) {
422 if (cct
->_experimental_features
.count("*")) {
423 lderr(cct
) << "WARNING: all dangerous and experimental features are enabled." << dendl
;
425 lderr(cct
) << "WARNING: the following dangerous and experimental features are enabled: "
426 << cct
->_experimental_features
<< dendl
;
432 if (changed
.count("crush_location")) {
433 cct
->crush_location
.update_from_conf();
439 class CephContextHook
: public AdminSocketHook
{
443 explicit CephContextHook(CephContext
*cct
) : m_cct(cct
) {}
445 int call(std::string_view command
, const cmdmap_t
& cmdmap
,
446 const bufferlist
& inbl
,
449 bufferlist
& out
) override
{
451 return m_cct
->do_command(command
, cmdmap
, f
, errss
, &out
);
452 } catch (const bad_cmd_get
& e
) {
459 bool CephContext::check_experimental_feature_enabled(const std::string
& feat
)
461 std::stringstream message
;
462 bool enabled
= check_experimental_feature_enabled(feat
, &message
);
463 lderr(this) << message
.str() << dendl
;
467 bool CephContext::check_experimental_feature_enabled(const std::string
& feat
,
468 std::ostream
*message
)
470 std::unique_lock
<ceph::spinlock
> lg(_feature_lock
);
472 bool enabled
= (_experimental_features
.count(feat
) ||
473 _experimental_features
.count("*"));
476 (*message
) << "WARNING: experimental feature '" << feat
<< "' is enabled\n";
477 (*message
) << "Please be aware that this feature is experimental, untested,\n";
478 (*message
) << "unsupported, and may result in data corruption, data loss,\n";
479 (*message
) << "and/or irreparable damage to your cluster. Do not use\n";
480 (*message
) << "feature with important data.\n";
482 (*message
) << "*** experimental feature '" << feat
<< "' is not enabled ***\n";
483 (*message
) << "This feature is marked as experimental, which means it\n";
484 (*message
) << " - is untested\n";
485 (*message
) << " - is unsupported\n";
486 (*message
) << " - may corrupt your data\n";
487 (*message
) << " - may break your cluster is an unrecoverable fashion\n";
488 (*message
) << "To enable this feature, add this to your ceph.conf:\n";
489 (*message
) << " enable experimental unrecoverable data corrupting features = " << feat
<< "\n";
494 int CephContext::do_command(std::string_view command
, const cmdmap_t
& cmdmap
,
500 return _do_command(command
, cmdmap
, f
, ss
, out
);
501 } catch (const bad_cmd_get
& e
) {
507 #pragma GCC push_options
508 #pragma GCC optimize ("O0")
509 static void leak_some_memory() {
510 volatile char *foo
= new char[1234];
513 #pragma GCC pop_options
515 int CephContext::_do_command(
516 std::string_view command
, const cmdmap_t
& cmdmap
,
522 lgeneric_dout(this, 1) << "do_command '" << command
<< "' '" << cmdmap
<< "'"
524 ceph_assert_always(!(command
== "assert" && _conf
->debug_asok_assert_abort
));
525 if (command
== "abort") {
526 if (_conf
->debug_asok_assert_abort
) {
532 if (command
== "leak_some_memory") {
535 else if (command
== "perfcounters_dump" || command
== "1" ||
536 command
== "perf dump") {
539 cmd_getval(cmdmap
, "logger", logger
);
540 cmd_getval(cmdmap
, "counter", counter
);
541 _perf_counters_collection
->dump_formatted(f
, false, false, logger
, counter
);
543 else if (command
== "perfcounters_schema" || command
== "2" ||
544 command
== "perf schema") {
545 _perf_counters_collection
->dump_formatted(f
, true, false);
547 else if (command
== "counter dump") {
548 _perf_counters_collection
->dump_formatted(f
, false, true);
550 else if (command
== "counter schema") {
551 _perf_counters_collection
->dump_formatted(f
, true, true);
553 else if (command
== "perf histogram dump") {
556 cmd_getval(cmdmap
, "logger", logger
);
557 cmd_getval(cmdmap
, "counter", counter
);
558 _perf_counters_collection
->dump_formatted_histograms(f
, false, logger
,
561 else if (command
== "perf histogram schema") {
562 _perf_counters_collection
->dump_formatted_histograms(f
, true);
564 else if (command
== "perf reset") {
566 std::string
section(command
);
567 f
->open_object_section(section
.c_str());
568 if (!cmd_getval(cmdmap
, "var", var
)) {
569 f
->dump_string("error", "syntax error: 'perf reset <var>'");
571 if(!_perf_counters_collection
->reset(var
))
572 f
->dump_stream("error") << "Not find: " << var
;
574 f
->dump_string("success", std::string(command
) + ' ' + var
);
579 std::string
section(command
);
580 boost::replace_all(section
, " ", "_");
581 f
->open_object_section(section
.c_str());
582 if (command
== "config show") {
583 _conf
.show_config(f
);
585 else if (command
== "config unset") {
587 if (!(cmd_getval(cmdmap
, "var", var
))) {
590 r
= _conf
.rm_val(var
.c_str());
591 if (r
< 0 && r
!= -ENOENT
) {
592 ss
<< "error unsetting '" << var
<< "': "
595 _conf
.apply_changes(&ss
);
601 else if (command
== "config set") {
603 std::vector
<std::string
> val
;
605 if (!(cmd_getval(cmdmap
, "var", var
)) ||
606 !(cmd_getval(cmdmap
, "val", val
))) {
609 // val may be multiple words
610 auto valstr
= str_join(val
, " ");
611 r
= _conf
.set_val(var
.c_str(), valstr
.c_str());
613 ss
<< "error setting '" << var
<< "' to '" << valstr
<< "': "
616 std::stringstream ss
;
617 _conf
.apply_changes(&ss
);
618 f
->dump_string("success", ss
.str());
621 } else if (command
== "config get") {
623 if (!cmd_getval(cmdmap
, "var", var
)) {
627 // FIPS zeroization audit 20191115: this memset is not security related.
628 memset(buf
, 0, sizeof(buf
));
630 r
= _conf
.get_val(var
.c_str(), &tmp
, sizeof(buf
));
632 ss
<< "error getting '" << var
<< "': " << cpp_strerror(r
);
634 f
->dump_string(var
.c_str(), buf
);
637 } else if (command
== "config help") {
639 if (cmd_getval(cmdmap
, "var", var
)) {
640 // Output a single one
641 std::string key
= ConfFile::normalize_key_name(var
);
642 auto schema
= _conf
.get_schema(key
);
644 ss
<< "Setting not found: '" << key
<< "'";
647 f
->dump_object("option", *schema
);
651 f
->open_array_section("options");
652 for (const auto &option
: ceph_options
) {
653 f
->dump_object("option", option
);
657 } else if (command
== "config diff") {
658 f
->open_object_section("diff");
660 f
->close_section(); // unknown
661 } else if (command
== "config diff get") {
663 f
->open_object_section("diff");
664 _conf
.diff(f
, setting
);
665 f
->close_section(); // unknown
667 else if (command
== "injectargs") {
668 std::vector
<std::string
> argsvec
;
669 cmd_getval(cmdmap
, "injected_args", argsvec
);
670 if (!argsvec
.empty()) {
671 auto args
= joinify
<std::string
>(argsvec
.begin(), argsvec
.end(), " ");
672 r
= _conf
.injectargs(args
, &ss
);
675 else if (command
== "log flush") {
678 else if (command
== "log dump") {
681 else if (command
== "log reopen") {
682 _log
->reopen_log_file();
685 ceph_abort_msg("registered under wrong command?");
689 lgeneric_dout(this, 1) << "do_command '" << command
<< "' '" << cmdmap
690 << "' result is " << out
->length() << " bytes" << dendl
;
694 CephContext::CephContext(uint32_t module_type_
,
695 enum code_environment_t code_env
,
697 : CephContext(module_type_
, create_options
{code_env
, init_flags_
, nullptr})
700 CephContext::CephContext(uint32_t module_type_
,
701 const create_options
& options
)
703 _conf
{options
.code_env
== CODE_ENVIRONMENT_DAEMON
},
705 _module_type(module_type_
),
706 _init_flags(options
.init_flags
),
712 _service_thread(NULL
),
715 _perf_counters_collection(NULL
),
716 _perf_counters_conf_obs(NULL
),
717 _heartbeat_map(NULL
),
720 _plugin_registry(NULL
),
721 #ifdef CEPH_DEBUG_MUTEX
726 if (options
.create_log
) {
727 _log
= options
.create_log(&_conf
->subsys
);
729 _log
= new ceph::logging::Log(&_conf
->subsys
);
732 _log_obs
= new LogObs(_log
);
733 _conf
.add_observer(_log_obs
);
735 _cct_obs
= new CephContextObs(this);
736 _conf
.add_observer(_cct_obs
);
737 #ifdef CEPH_DEBUG_MUTEX
738 _lockdep_obs
= new LockdepObs(this);
739 _conf
.add_observer(_lockdep_obs
);
741 _perf_counters_collection
= new PerfCountersCollection(this);
743 _admin_socket
= new AdminSocket(this);
744 _heartbeat_map
= new HeartbeatMap(this);
746 _plugin_registry
= new PluginRegistry(this);
748 _admin_hook
= new CephContextHook(this);
749 _admin_socket
->register_command("assert", _admin_hook
, "");
750 _admin_socket
->register_command("abort", _admin_hook
, "");
751 _admin_socket
->register_command("leak_some_memory", _admin_hook
, "");
752 _admin_socket
->register_command("perfcounters_dump", _admin_hook
, "");
753 _admin_socket
->register_command("1", _admin_hook
, "");
754 _admin_socket
->register_command("perf dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook
, "dump non-labeled counters and their values");
755 _admin_socket
->register_command("perfcounters_schema", _admin_hook
, "");
756 _admin_socket
->register_command("perf histogram dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook
, "dump perf histogram values");
757 _admin_socket
->register_command("2", _admin_hook
, "");
758 _admin_socket
->register_command("perf schema", _admin_hook
, "dump non-labeled counters schemas");
759 _admin_socket
->register_command("counter dump", _admin_hook
, "dump all labeled and non-labeled counters and their values");
760 _admin_socket
->register_command("counter schema", _admin_hook
, "dump all labeled and non-labeled counters schemas");
761 _admin_socket
->register_command("perf histogram schema", _admin_hook
, "dump perf histogram schema");
762 _admin_socket
->register_command("perf reset name=var,type=CephString", _admin_hook
, "perf reset <name>: perf reset all or one perfcounter name");
763 _admin_socket
->register_command("config show", _admin_hook
, "dump current config settings");
764 _admin_socket
->register_command("config help name=var,type=CephString,req=false", _admin_hook
, "get config setting schema and descriptions");
765 _admin_socket
->register_command("config set name=var,type=CephString name=val,type=CephString,n=N", _admin_hook
, "config set <field> <val> [<val> ...]: set a config variable");
766 _admin_socket
->register_command("config unset name=var,type=CephString", _admin_hook
, "config unset <field>: unset a config variable");
767 _admin_socket
->register_command("config get name=var,type=CephString", _admin_hook
, "config get <field>: get the config value");
768 _admin_socket
->register_command(
769 "config diff", _admin_hook
,
770 "dump diff of current config and default config");
771 _admin_socket
->register_command(
772 "config diff get name=var,type=CephString", _admin_hook
,
773 "dump diff get <field>: dump diff of current and default config setting <field>");
774 _admin_socket
->register_command("injectargs name=injected_args,type=CephString,n=N", _admin_hook
, "inject configuration arguments into running daemon"),
775 _admin_socket
->register_command("log flush", _admin_hook
, "flush log entries to log file");
776 _admin_socket
->register_command("log dump", _admin_hook
, "dump recent log entries to log file");
777 _admin_socket
->register_command("log reopen", _admin_hook
, "reopen log file");
779 _crypto_none
= CryptoHandler::create(CEPH_CRYPTO_NONE
);
780 _crypto_aes
= CryptoHandler::create(CEPH_CRYPTO_AES
);
781 _crypto_random
.reset(new CryptoRandom());
783 lookup_or_create_singleton_object
<MempoolObs
>("mempool_obs", false, this);
786 CephContext::~CephContext()
788 associated_objs
.clear();
789 join_service_thread();
792 _perf_counters_collection
->remove(_cct_perf
);
797 delete _plugin_registry
;
799 _admin_socket
->unregister_commands(_admin_hook
);
801 delete _admin_socket
;
803 delete _heartbeat_map
;
805 delete _perf_counters_collection
;
806 _perf_counters_collection
= NULL
;
808 delete _perf_counters_conf_obs
;
809 _perf_counters_conf_obs
= NULL
;
811 _conf
.remove_observer(_log_obs
);
815 _conf
.remove_observer(_cct_obs
);
818 #ifdef CEPH_DEBUG_MUTEX
819 _conf
.remove_observer(_lockdep_obs
);
829 if (_crypto_inited
> 0) {
830 ceph_assert(_crypto_inited
== 1); // or else someone explicitly did
831 // init but not shutdown
836 void CephContext::put() {
838 ANNOTATE_HAPPENS_AFTER(&nref
);
839 ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&nref
);
840 if (g_ceph_context
== this)
841 g_ceph_context
= nullptr;
844 ANNOTATE_HAPPENS_BEFORE(&nref
);
848 void CephContext::init_crypto()
850 if (_crypto_inited
++ == 0) {
851 TOPNSPC::crypto::init();
855 void CephContext::shutdown_crypto()
857 if (--_crypto_inited
== 0) {
858 TOPNSPC::crypto::shutdown(g_code_env
== CODE_ENVIRONMENT_LIBRARY
);
862 void CephContext::start_service_thread()
865 std::lock_guard
lg(_service_thread_lock
);
866 if (_service_thread
) {
869 _service_thread
= new CephContextServiceThread(this);
870 _service_thread
->create("service");
873 if (!(get_init_flags() & CINIT_FLAG_NO_CCT_PERF_COUNTERS
))
874 _enable_perf_counter();
876 // make logs flush on_exit()
877 if (_conf
->log_flush_on_exit
)
878 _log
->set_flush_on_exit();
880 // Trigger callbacks on any config observers that were waiting for
881 // it to become safe to start threads.
882 _conf
.set_safe_to_start_threads();
883 _conf
.call_all_observers();
885 // start admin socket
886 if (_conf
->admin_socket
.length())
887 _admin_socket
->init(_conf
->admin_socket
);
890 void CephContext::reopen_logs()
892 std::lock_guard
lg(_service_thread_lock
);
894 _service_thread
->reopen_logs();
897 void CephContext::join_service_thread()
899 std::unique_lock
<ceph::spinlock
> lg(_service_thread_lock
);
901 CephContextServiceThread
*thread
= _service_thread
;
905 _service_thread
= NULL
;
909 thread
->exit_thread();
913 if (!(get_init_flags() & CINIT_FLAG_NO_CCT_PERF_COUNTERS
))
914 _disable_perf_counter();
917 uint32_t CephContext::get_module_type() const
922 void CephContext::set_init_flags(int flags
)
927 int CephContext::get_init_flags() const
932 PerfCountersCollection
*CephContext::get_perfcounters_collection()
934 return _perf_counters_collection
;
937 void CephContext::_enable_perf_counter()
940 PerfCountersBuilder
plb(this, "cct", l_cct_first
, l_cct_last
);
941 plb
.add_u64(l_cct_total_workers
, "total_workers", "Total workers");
942 plb
.add_u64(l_cct_unhealthy_workers
, "unhealthy_workers", "Unhealthy workers");
943 _cct_perf
= plb
.create_perf_counters();
944 _perf_counters_collection
->add(_cct_perf
);
946 assert(_mempool_perf_names
.empty());
947 assert(_mempool_perf_descriptions
.empty());
948 _mempool_perf_names
.reserve(mempool::num_pools
* 2);
949 _mempool_perf_descriptions
.reserve(mempool::num_pools
* 2);
950 for (unsigned i
= 0; i
< mempool::num_pools
; ++i
) {
951 std::string n
= mempool::get_pool_name(mempool::pool_index_t(i
));
952 _mempool_perf_names
.push_back(n
+ "_bytes"s
);
953 _mempool_perf_descriptions
.push_back(
954 "mempool "s
+ n
+ " total bytes");
955 _mempool_perf_names
.push_back(n
+ "_items"s
);
956 _mempool_perf_descriptions
.push_back(
957 "mempool "s
+ n
+ " total items"s
);
960 PerfCountersBuilder
plb2(this, "mempool", l_mempool_first
,
961 l_mempool_first
+ 1 + 2*mempool::num_pools
);
962 unsigned l
= l_mempool_first
+ 1;
963 for (unsigned i
= 0; i
< mempool::num_pools
; ++i
) {
964 plb2
.add_u64(l
++, _mempool_perf_names
[i
*2].c_str(),
965 _mempool_perf_descriptions
[i
*2].c_str());
966 plb2
.add_u64(l
++, _mempool_perf_names
[i
*2+1].c_str(),
967 _mempool_perf_descriptions
[i
*2+1].c_str());
969 _mempool_perf
= plb2
.create_perf_counters();
970 _perf_counters_collection
->add(_mempool_perf
);
973 void CephContext::_disable_perf_counter()
978 _perf_counters_collection
->remove(_cct_perf
);
982 _perf_counters_collection
->remove(_mempool_perf
);
983 delete _mempool_perf
;
984 _mempool_perf
= nullptr;
985 _mempool_perf_names
.clear();
986 _mempool_perf_descriptions
.clear();
989 void CephContext::_refresh_perf_values()
992 _cct_perf
->set(l_cct_total_workers
, _heartbeat_map
->get_total_workers());
993 _cct_perf
->set(l_cct_unhealthy_workers
, _heartbeat_map
->get_unhealthy_workers());
995 unsigned l
= l_mempool_first
+ 1;
996 for (unsigned i
= 0; i
< mempool::num_pools
; ++i
) {
997 mempool::pool_t
& p
= mempool::get_pool(mempool::pool_index_t(i
));
998 _mempool_perf
->set(l
++, p
.allocated_bytes());
999 _mempool_perf
->set(l
++, p
.allocated_items());
1003 AdminSocket
*CephContext::get_admin_socket()
1005 return _admin_socket
;
1008 CryptoHandler
*CephContext::get_crypto_handler(int type
)
1011 case CEPH_CRYPTO_NONE
:
1012 return _crypto_none
;
1013 case CEPH_CRYPTO_AES
:
1020 void CephContext::notify_pre_fork()
1023 std::lock_guard
lg(_fork_watchers_lock
);
1024 for (auto &&t
: _fork_watchers
) {
1025 t
->handle_pre_fork();
1029 // note: we don't hold a lock here, but we assume we are idle at
1030 // fork time, which happens during process init and startup.
1031 auto i
= associated_objs
.begin();
1032 while (i
!= associated_objs
.end()) {
1033 if (associated_objs_drop_on_fork
.count(i
->first
.first
)) {
1034 i
= associated_objs
.erase(i
);
1039 associated_objs_drop_on_fork
.clear();
1043 void CephContext::notify_post_fork()
1045 ceph::spin_unlock(&_fork_watchers_lock
);
1046 for (auto &&t
: _fork_watchers
)
1047 t
->handle_post_fork();
1050 void CephContext::set_mon_addrs(const MonMap
& mm
) {
1051 std::vector
<entity_addrvec_t
> mon_addrs
;
1052 for (auto& i
: mm
.mon_info
) {
1053 mon_addrs
.push_back(i
.second
.public_addrs
);
1056 set_mon_addrs(mon_addrs
);
1059 #endif // WITH_SEASTAR