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/mempool.h"
26 #include "common/admin_socket.h"
27 #include "common/code_environment.h"
28 #include "common/ceph_mutex.h"
29 #include "common/debug.h"
30 #include "common/config.h"
31 #include "common/ceph_crypto.h"
32 #include "common/HeartbeatMap.h"
33 #include "common/errno.h"
34 #include "common/Graylog.h"
38 #include "auth/Crypto.h"
39 #include "include/str_list.h"
40 #include "common/config.h"
41 #include "common/config_obs.h"
42 #include "common/PluginRegistry.h"
43 #include "common/valgrind.h"
44 #include "include/spinlock.h"
46 using ceph::bufferlist
;
47 using ceph::HeartbeatMap
;
50 #include "common/common_init.h"
56 CephContext::CephContext()
57 : _conf
{ceph::common::local_conf()},
58 _perf_counters_collection
{ceph::common::local_perf_coll()},
59 _crypto_random
{std::make_unique
<CryptoRandom
>()}
62 // define the dtor in .cc as CryptoRandom is an incomplete type in the header
63 CephContext::~CephContext()
66 uint32_t CephContext::get_module_type() const
68 return CEPH_ENTITY_TYPE_OSD
;
71 CryptoRandom
* CephContext::random() const
73 return _crypto_random
.get();
76 CephContext
* CephContext::get()
82 void CephContext::put()
89 PerfCountersCollectionImpl
* CephContext::get_perfcounters_collection()
91 return _perf_counters_collection
.get_perf_collection();
97 class LockdepObs
: public md_config_obs_t
{
99 explicit LockdepObs(CephContext
*cct
)
100 : m_cct(cct
), m_registered(false), lock(ceph::make_mutex("lock_dep_obs")) {
102 ~LockdepObs() override
{
104 lockdep_unregister_ceph_context(m_cct
);
108 const char** get_tracked_conf_keys() const override
{
109 static const char *KEYS
[] = {"lockdep", NULL
};
113 void handle_conf_change(const ConfigProxy
& conf
,
114 const std::set
<std::string
> &changed
) override
{
115 std::unique_lock
locker(lock
);
116 if (conf
->lockdep
&& !m_registered
) {
117 lockdep_register_ceph_context(m_cct
);
119 } else if (!conf
->lockdep
&& m_registered
) {
120 lockdep_unregister_ceph_context(m_cct
);
121 m_registered
= false;
130 class MempoolObs
: public md_config_obs_t
,
131 public AdminSocketHook
{
136 explicit MempoolObs(CephContext
*cct
)
137 : cct(cct
), lock(ceph::make_mutex("mem_pool_obs")) {
138 cct
->_conf
.add_observer(this);
139 int r
= cct
->get_admin_socket()->register_command(
143 "get mempool stats");
146 ~MempoolObs() override
{
147 cct
->_conf
.remove_observer(this);
148 cct
->get_admin_socket()->unregister_command("dump_mempools");
152 const char** get_tracked_conf_keys() const override
{
153 static const char *KEYS
[] = {
160 void handle_conf_change(const ConfigProxy
& conf
,
161 const std::set
<std::string
> &changed
) override
{
162 std::unique_lock
locker(lock
);
163 if (changed
.count("mempool_debug")) {
164 mempool::set_debug_mode(cct
->_conf
->mempool_debug
);
169 bool call(std::string_view command
, const cmdmap_t
& cmdmap
,
170 std::string_view format
, bufferlist
& out
) override
{
171 if (command
== "dump_mempools") {
172 std::unique_ptr
<Formatter
> f(Formatter::create(format
));
173 f
->open_object_section("mempools");
174 mempool::dump(f
.get());
183 } // anonymous namespace
185 class CephContextServiceThread
: public Thread
188 explicit CephContextServiceThread(CephContext
*cct
)
189 : _reopen_logs(false), _exit_thread(false), _cct(cct
)
193 ~CephContextServiceThread() override
{}
195 void *entry() override
198 std::unique_lock
l(_lock
);
203 if (_cct
->_conf
->heartbeat_interval
) {
204 auto interval
= ceph::make_timespan(_cct
->_conf
->heartbeat_interval
);
205 _cond
.wait_for(l
, interval
);
214 _cct
->_log
->reopen_log_file();
215 _reopen_logs
= false;
217 _cct
->_heartbeat_map
->check_touch_file();
219 // refresh the perf coutners
220 _cct
->_refresh_perf_values();
227 std::lock_guard
l(_lock
);
234 std::lock_guard
l(_lock
);
240 ceph::mutex _lock
= ceph::make_mutex("CephContextServiceThread::_lock");
241 ceph::condition_variable _cond
;
249 * observe logging config changes
251 * The logging subsystem sits below most of the ceph code, including
252 * the config subsystem, to keep it simple and self-contained. Feed
253 * logging-related config changes to the log.
255 class LogObs
: public md_config_obs_t
{
256 ceph::logging::Log
*log
;
260 explicit LogObs(ceph::logging::Log
*l
)
261 : log(l
), lock(ceph::make_mutex("log_obs")) {
264 const char** get_tracked_conf_keys() const override
{
265 static const char *KEYS
[] = {
279 "log_coarse_timestamps",
287 void handle_conf_change(const ConfigProxy
& conf
,
288 const std::set
<std::string
> &changed
) override
{
289 std::unique_lock
locker(lock
);
291 if (changed
.count("log_to_stderr") || changed
.count("err_to_stderr")) {
292 int l
= conf
->log_to_stderr
? 99 : (conf
->err_to_stderr
? -1 : -2);
293 log
->set_stderr_level(l
, l
);
297 if (changed
.count("log_to_syslog")) {
298 int l
= conf
->log_to_syslog
? 99 : (conf
->err_to_syslog
? -1 : -2);
299 log
->set_syslog_level(l
, l
);
303 if (changed
.count("log_file") ||
304 changed
.count("log_to_file")) {
305 if (conf
->log_to_file
) {
306 log
->set_log_file(conf
->log_file
);
308 log
->set_log_file({});
310 log
->reopen_log_file();
313 if (changed
.count("log_stderr_prefix")) {
314 log
->set_log_stderr_prefix(conf
.get_val
<string
>("log_stderr_prefix"));
317 if (changed
.count("log_max_new")) {
319 log
->set_max_new(conf
->log_max_new
);
322 if (changed
.count("log_max_recent")) {
323 log
->set_max_recent(conf
->log_max_recent
);
327 if (changed
.count("log_to_graylog") || changed
.count("err_to_graylog")) {
328 int l
= conf
->log_to_graylog
? 99 : (conf
->err_to_graylog
? -1 : -2);
329 log
->set_graylog_level(l
, l
);
331 if (conf
->log_to_graylog
|| conf
->err_to_graylog
) {
332 log
->start_graylog();
333 } else if (! (conf
->log_to_graylog
&& conf
->err_to_graylog
)) {
338 if (log
->graylog() && (changed
.count("log_graylog_host") || changed
.count("log_graylog_port"))) {
339 log
->graylog()->set_destination(conf
->log_graylog_host
, conf
->log_graylog_port
);
342 if (changed
.find("log_coarse_timestamps") != changed
.end()) {
343 log
->set_coarse_timestamps(conf
.get_val
<bool>("log_coarse_timestamps"));
347 if (log
->graylog() && changed
.count("host")) {
348 log
->graylog()->set_hostname(conf
->host
);
351 if (log
->graylog() && changed
.count("fsid")) {
352 log
->graylog()->set_fsid(conf
.get_val
<uuid_d
>("fsid"));
358 // cct config watcher
359 class CephContextObs
: public md_config_obs_t
{
363 explicit CephContextObs(CephContext
*cct
) : cct(cct
) {}
365 const char** get_tracked_conf_keys() const override
{
366 static const char *KEYS
[] = {
367 "enable_experimental_unrecoverable_data_corrupting_features",
374 void handle_conf_change(const ConfigProxy
& conf
,
375 const std::set
<std::string
> &changed
) override
{
377 "enable_experimental_unrecoverable_data_corrupting_features")) {
378 std::lock_guard
lg(cct
->_feature_lock
);
380 conf
->enable_experimental_unrecoverable_data_corrupting_features
,
381 cct
->_experimental_features
);
382 if (getenv("CEPH_DEV") == NULL
) {
383 if (!cct
->_experimental_features
.empty()) {
384 if (cct
->_experimental_features
.count("*")) {
385 lderr(cct
) << "WARNING: all dangerous and experimental features are enabled." << dendl
;
387 lderr(cct
) << "WARNING: the following dangerous and experimental features are enabled: "
388 << cct
->_experimental_features
<< dendl
;
394 if (changed
.count("crush_location")) {
395 cct
->crush_location
.update_from_conf();
400 bool CephContext::check_experimental_feature_enabled(const std::string
& feat
)
402 stringstream message
;
403 bool enabled
= check_experimental_feature_enabled(feat
, &message
);
404 lderr(this) << message
.str() << dendl
;
408 bool CephContext::check_experimental_feature_enabled(const std::string
& feat
,
409 std::ostream
*message
)
411 std::unique_lock
<ceph::spinlock
> lg(_feature_lock
);
413 bool enabled
= (_experimental_features
.count(feat
) ||
414 _experimental_features
.count("*"));
417 (*message
) << "WARNING: experimental feature '" << feat
<< "' is enabled\n";
418 (*message
) << "Please be aware that this feature is experimental, untested,\n";
419 (*message
) << "unsupported, and may result in data corruption, data loss,\n";
420 (*message
) << "and/or irreparable damage to your cluster. Do not use\n";
421 (*message
) << "feature with important data.\n";
423 (*message
) << "*** experimental feature '" << feat
<< "' is not enabled ***\n";
424 (*message
) << "This feature is marked as experimental, which means it\n";
425 (*message
) << " - is untested\n";
426 (*message
) << " - is unsupported\n";
427 (*message
) << " - may corrupt your data\n";
428 (*message
) << " - may break your cluster is an unrecoverable fashion\n";
429 (*message
) << "To enable this feature, add this to your ceph.conf:\n";
430 (*message
) << " enable experimental unrecoverable data corrupting features = " << feat
<< "\n";
437 class CephContextHook
: public AdminSocketHook
{
441 explicit CephContextHook(CephContext
*cct
) : m_cct(cct
) {}
443 bool call(std::string_view command
, const cmdmap_t
& cmdmap
,
444 std::string_view format
, bufferlist
& out
) override
{
446 m_cct
->do_command(command
, cmdmap
, format
, &out
);
447 } catch (const bad_cmd_get
& e
) {
454 void CephContext::do_command(std::string_view command
, const cmdmap_t
& cmdmap
,
455 std::string_view format
, bufferlist
*out
)
457 Formatter
*f
= Formatter::create(format
, "json-pretty", "json-pretty");
459 for (auto it
= cmdmap
.begin(); it
!= cmdmap
.end(); ++it
) {
460 if (it
->first
!= "prefix") {
461 ss
<< it
->first
<< ":" << cmd_vartype_stringify(it
->second
) << " ";
464 lgeneric_dout(this, 1) << "do_command '" << command
<< "' '"
465 << ss
.str() << dendl
;
466 ceph_assert_always(!(command
== "assert" && _conf
->debug_asok_assert_abort
));
467 if (command
== "abort" && _conf
->debug_asok_assert_abort
) {
470 if (command
== "perfcounters_dump" || command
== "1" ||
471 command
== "perf dump") {
474 cmd_getval(this, cmdmap
, "logger", logger
);
475 cmd_getval(this, cmdmap
, "counter", counter
);
476 _perf_counters_collection
->dump_formatted(f
, false, logger
, counter
);
478 else if (command
== "perfcounters_schema" || command
== "2" ||
479 command
== "perf schema") {
480 _perf_counters_collection
->dump_formatted(f
, true);
482 else if (command
== "perf histogram dump") {
485 cmd_getval(this, cmdmap
, "logger", logger
);
486 cmd_getval(this, cmdmap
, "counter", counter
);
487 _perf_counters_collection
->dump_formatted_histograms(f
, false, logger
,
490 else if (command
== "perf histogram schema") {
491 _perf_counters_collection
->dump_formatted_histograms(f
, true);
493 else if (command
== "perf reset") {
495 std::string
section(command
);
496 f
->open_object_section(section
.c_str());
497 if (!cmd_getval(this, cmdmap
, "var", var
)) {
498 f
->dump_string("error", "syntax error: 'perf reset <var>'");
500 if(!_perf_counters_collection
->reset(var
))
501 f
->dump_stream("error") << "Not find: " << var
;
503 f
->dump_string("success", std::string(command
) + ' ' + var
);
508 std::string
section(command
);
509 boost::replace_all(section
, " ", "_");
510 f
->open_object_section(section
.c_str());
511 if (command
== "config show") {
512 _conf
.show_config(f
);
514 else if (command
== "config unset") {
516 if (!(cmd_getval(this, cmdmap
, "var", var
))) {
517 f
->dump_string("error", "syntax error: 'config unset <var>'");
519 int r
= _conf
.rm_val(var
.c_str());
520 if (r
< 0 && r
!= -ENOENT
) {
521 f
->dump_stream("error") << "error unsetting '" << var
<< "': "
525 _conf
.apply_changes(&ss
);
526 f
->dump_string("success", ss
.str());
531 else if (command
== "config set") {
533 std::vector
<std::string
> val
;
535 if (!(cmd_getval(this, cmdmap
, "var", var
)) ||
536 !(cmd_getval(this, cmdmap
, "val", val
))) {
537 f
->dump_string("error", "syntax error: 'config set <var> <value>'");
539 // val may be multiple words
540 string valstr
= str_join(val
, " ");
541 int r
= _conf
.set_val(var
.c_str(), valstr
.c_str());
543 f
->dump_stream("error") << "error setting '" << var
<< "' to '" << valstr
<< "': " << cpp_strerror(r
);
546 _conf
.apply_changes(&ss
);
547 f
->dump_string("success", ss
.str());
550 } else if (command
== "config get") {
552 if (!cmd_getval(this, cmdmap
, "var", var
)) {
553 f
->dump_string("error", "syntax error: 'config get <var>'");
556 // FIPS zeroization audit 20191115: this memset is not security related.
557 memset(buf
, 0, sizeof(buf
));
559 int r
= _conf
.get_val(var
.c_str(), &tmp
, sizeof(buf
));
561 f
->dump_stream("error") << "error getting '" << var
<< "': " << cpp_strerror(r
);
563 f
->dump_string(var
.c_str(), buf
);
566 } else if (command
== "config help") {
568 if (cmd_getval(this, cmdmap
, "var", var
)) {
569 // Output a single one
570 std::string key
= ConfFile::normalize_key_name(var
);
571 auto schema
= _conf
.get_schema(key
);
573 std::ostringstream msg
;
574 msg
<< "Setting not found: '" << key
<< "'";
575 f
->dump_string("error", msg
.str());
577 f
->dump_object("option", *schema
);
581 f
->open_array_section("options");
582 for (const auto &option
: ceph_options
) {
583 f
->dump_object("option", option
);
587 } else if (command
== "config diff") {
588 f
->open_object_section("diff");
590 f
->close_section(); // unknown
591 } else if (command
== "config diff get") {
593 f
->open_object_section("diff");
594 _conf
.diff(f
, setting
);
595 f
->close_section(); // unknown
596 } else if (command
== "log flush") {
599 else if (command
== "log dump") {
602 else if (command
== "log reopen") {
603 _log
->reopen_log_file();
606 ceph_abort_msg("registered under wrong command?");
612 lgeneric_dout(this, 1) << "do_command '" << command
<< "' '" << ss
.str()
613 << "result is " << out
->length() << " bytes" << dendl
;
616 CephContext::CephContext(uint32_t module_type_
,
617 enum code_environment_t code_env
,
620 _conf
{code_env
== CODE_ENVIRONMENT_DAEMON
},
622 _module_type(module_type_
),
623 _init_flags(init_flags_
),
629 _service_thread(NULL
),
632 _perf_counters_collection(NULL
),
633 _perf_counters_conf_obs(NULL
),
634 _heartbeat_map(NULL
),
637 _plugin_registry(NULL
),
641 _log
= new ceph::logging::Log(&_conf
->subsys
);
643 _log_obs
= new LogObs(_log
);
644 _conf
.add_observer(_log_obs
);
646 _cct_obs
= new CephContextObs(this);
647 _conf
.add_observer(_cct_obs
);
649 _lockdep_obs
= new LockdepObs(this);
650 _conf
.add_observer(_lockdep_obs
);
652 _perf_counters_collection
= new PerfCountersCollection(this);
654 _admin_socket
= new AdminSocket(this);
655 _heartbeat_map
= new HeartbeatMap(this);
657 _plugin_registry
= new PluginRegistry(this);
659 _admin_hook
= new CephContextHook(this);
660 _admin_socket
->register_command("assert", "assert", _admin_hook
, "");
661 _admin_socket
->register_command("abort", "abort", _admin_hook
, "");
662 _admin_socket
->register_command("perfcounters_dump", "perfcounters_dump", _admin_hook
, "");
663 _admin_socket
->register_command("1", "1", _admin_hook
, "");
664 _admin_socket
->register_command("perf dump", "perf dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook
, "dump perfcounters value");
665 _admin_socket
->register_command("perfcounters_schema", "perfcounters_schema", _admin_hook
, "");
666 _admin_socket
->register_command("perf histogram dump", "perf histogram dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook
, "dump perf histogram values");
667 _admin_socket
->register_command("2", "2", _admin_hook
, "");
668 _admin_socket
->register_command("perf schema", "perf schema", _admin_hook
, "dump perfcounters schema");
669 _admin_socket
->register_command("perf histogram schema", "perf histogram schema", _admin_hook
, "dump perf histogram schema");
670 _admin_socket
->register_command("perf reset", "perf reset name=var,type=CephString", _admin_hook
, "perf reset <name>: perf reset all or one perfcounter name");
671 _admin_socket
->register_command("config show", "config show", _admin_hook
, "dump current config settings");
672 _admin_socket
->register_command("config help", "config help name=var,type=CephString,req=false", _admin_hook
, "get config setting schema and descriptions");
673 _admin_socket
->register_command("config set", "config set name=var,type=CephString name=val,type=CephString,n=N", _admin_hook
, "config set <field> <val> [<val> ...]: set a config variable");
674 _admin_socket
->register_command("config unset", "config unset name=var,type=CephString", _admin_hook
, "config unset <field>: unset a config variable");
675 _admin_socket
->register_command("config get", "config get name=var,type=CephString", _admin_hook
, "config get <field>: get the config value");
676 _admin_socket
->register_command("config diff",
677 "config diff", _admin_hook
,
678 "dump diff of current config and default config");
679 _admin_socket
->register_command("config diff get",
680 "config diff get name=var,type=CephString", _admin_hook
,
681 "dump diff get <field>: dump diff of current and default config setting <field>");
682 _admin_socket
->register_command("log flush", "log flush", _admin_hook
, "flush log entries to log file");
683 _admin_socket
->register_command("log dump", "log dump", _admin_hook
, "dump recent log entries to log file");
684 _admin_socket
->register_command("log reopen", "log reopen", _admin_hook
, "reopen log file");
686 _crypto_none
= CryptoHandler::create(CEPH_CRYPTO_NONE
);
687 _crypto_aes
= CryptoHandler::create(CEPH_CRYPTO_AES
);
688 _crypto_random
.reset(new CryptoRandom());
690 lookup_or_create_singleton_object
<MempoolObs
>("mempool_obs", false, this);
693 CephContext::~CephContext()
695 associated_objs
.clear();
696 join_service_thread();
699 _perf_counters_collection
->remove(_cct_perf
);
704 delete _plugin_registry
;
706 _admin_socket
->unregister_commands(_admin_hook
);
708 delete _admin_socket
;
710 delete _heartbeat_map
;
712 delete _perf_counters_collection
;
713 _perf_counters_collection
= NULL
;
715 delete _perf_counters_conf_obs
;
716 _perf_counters_conf_obs
= NULL
;
718 _conf
.remove_observer(_log_obs
);
722 _conf
.remove_observer(_cct_obs
);
726 _conf
.remove_observer(_lockdep_obs
);
736 if (_crypto_inited
> 0) {
737 ceph_assert(_crypto_inited
== 1); // or else someone explicitly did
738 // init but not shutdown
743 void CephContext::put() {
745 ANNOTATE_HAPPENS_AFTER(&nref
);
746 ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&nref
);
749 ANNOTATE_HAPPENS_BEFORE(&nref
);
753 void CephContext::init_crypto()
755 if (_crypto_inited
++ == 0) {
756 ceph::crypto::init(this);
760 void CephContext::shutdown_crypto()
762 if (--_crypto_inited
== 0) {
763 ceph::crypto::shutdown(g_code_env
== CODE_ENVIRONMENT_LIBRARY
);
767 void CephContext::start_service_thread()
770 std::lock_guard
lg(_service_thread_lock
);
771 if (_service_thread
) {
774 _service_thread
= new CephContextServiceThread(this);
775 _service_thread
->create("service");
778 if (!(get_init_flags() & CINIT_FLAG_NO_CCT_PERF_COUNTERS
))
779 _enable_perf_counter();
781 // make logs flush on_exit()
782 if (_conf
->log_flush_on_exit
)
783 _log
->set_flush_on_exit();
785 // Trigger callbacks on any config observers that were waiting for
786 // it to become safe to start threads.
787 _conf
.set_safe_to_start_threads();
788 _conf
.call_all_observers();
790 // start admin socket
791 if (_conf
->admin_socket
.length())
792 _admin_socket
->init(_conf
->admin_socket
);
795 void CephContext::reopen_logs()
797 std::lock_guard
lg(_service_thread_lock
);
799 _service_thread
->reopen_logs();
802 void CephContext::join_service_thread()
804 std::unique_lock
<ceph::spinlock
> lg(_service_thread_lock
);
806 CephContextServiceThread
*thread
= _service_thread
;
810 _service_thread
= NULL
;
814 thread
->exit_thread();
818 if (!(get_init_flags() & CINIT_FLAG_NO_CCT_PERF_COUNTERS
))
819 _disable_perf_counter();
822 uint32_t CephContext::get_module_type() const
827 void CephContext::set_init_flags(int flags
)
832 int CephContext::get_init_flags() const
837 PerfCountersCollection
*CephContext::get_perfcounters_collection()
839 return _perf_counters_collection
;
842 void CephContext::_enable_perf_counter()
845 PerfCountersBuilder
plb(this, "cct", l_cct_first
, l_cct_last
);
846 plb
.add_u64(l_cct_total_workers
, "total_workers", "Total workers");
847 plb
.add_u64(l_cct_unhealthy_workers
, "unhealthy_workers", "Unhealthy workers");
848 _cct_perf
= plb
.create_perf_counters();
849 _perf_counters_collection
->add(_cct_perf
);
851 assert(_mempool_perf_names
.empty());
852 assert(_mempool_perf_descriptions
.empty());
853 _mempool_perf_names
.reserve(mempool::num_pools
* 2);
854 _mempool_perf_descriptions
.reserve(mempool::num_pools
* 2);
855 for (unsigned i
= 0; i
< mempool::num_pools
; ++i
) {
856 string n
= mempool::get_pool_name(mempool::pool_index_t(i
));
857 _mempool_perf_names
.push_back(n
+ "_bytes");
858 _mempool_perf_descriptions
.push_back(
859 string("mempool ") + n
+ " total bytes");
860 _mempool_perf_names
.push_back(n
+ "_items");
861 _mempool_perf_descriptions
.push_back(
862 string("mempool ") + n
+ " total items");
865 PerfCountersBuilder
plb2(this, "mempool", l_mempool_first
,
866 l_mempool_first
+ 1 + 2*mempool::num_pools
);
867 unsigned l
= l_mempool_first
+ 1;
868 for (unsigned i
= 0; i
< mempool::num_pools
; ++i
) {
869 plb2
.add_u64(l
++, _mempool_perf_names
[i
*2].c_str(),
870 _mempool_perf_descriptions
[i
*2].c_str());
871 plb2
.add_u64(l
++, _mempool_perf_names
[i
*2+1].c_str(),
872 _mempool_perf_descriptions
[i
*2+1].c_str());
874 _mempool_perf
= plb2
.create_perf_counters();
875 _perf_counters_collection
->add(_mempool_perf
);
878 void CephContext::_disable_perf_counter()
883 _perf_counters_collection
->remove(_cct_perf
);
887 _perf_counters_collection
->remove(_mempool_perf
);
888 delete _mempool_perf
;
889 _mempool_perf
= nullptr;
890 _mempool_perf_names
.clear();
891 _mempool_perf_descriptions
.clear();
894 void CephContext::_refresh_perf_values()
897 _cct_perf
->set(l_cct_total_workers
, _heartbeat_map
->get_total_workers());
898 _cct_perf
->set(l_cct_unhealthy_workers
, _heartbeat_map
->get_unhealthy_workers());
900 unsigned l
= l_mempool_first
+ 1;
901 for (unsigned i
= 0; i
< mempool::num_pools
; ++i
) {
902 mempool::pool_t
& p
= mempool::get_pool(mempool::pool_index_t(i
));
903 _mempool_perf
->set(l
++, p
.allocated_bytes());
904 _mempool_perf
->set(l
++, p
.allocated_items());
908 AdminSocket
*CephContext::get_admin_socket()
910 return _admin_socket
;
913 CryptoHandler
*CephContext::get_crypto_handler(int type
)
916 case CEPH_CRYPTO_NONE
:
918 case CEPH_CRYPTO_AES
:
925 void CephContext::notify_pre_fork()
928 std::lock_guard
lg(_fork_watchers_lock
);
929 for (auto &&t
: _fork_watchers
) {
930 t
->handle_pre_fork();
934 // note: we don't hold a lock here, but we assume we are idle at
935 // fork time, which happens during process init and startup.
936 auto i
= associated_objs
.begin();
937 while (i
!= associated_objs
.end()) {
938 if (associated_objs_drop_on_fork
.count(i
->first
.first
)) {
939 i
= associated_objs
.erase(i
);
944 associated_objs_drop_on_fork
.clear();
948 void CephContext::notify_post_fork()
950 ceph::spin_unlock(&_fork_watchers_lock
);
951 for (auto &&t
: _fork_watchers
)
952 t
->handle_post_fork();
954 #endif // WITH_SEASTAR