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 <boost/algorithm/string.hpp>
18 #include "include/mempool.h"
19 #include "common/admin_socket.h"
20 #include "common/perf_counters.h"
21 #include "common/code_environment.h"
22 #include "common/ceph_crypto.h"
23 #include "common/HeartbeatMap.h"
24 #include "common/errno.h"
25 #include "common/Graylog.h"
26 #include "auth/Crypto.h"
27 #include "include/str_list.h"
28 #include "common/PluginRegistry.h"
30 using ceph::bufferlist
;
31 using ceph::HeartbeatMap
;
35 class LockdepObs
: public md_config_obs_t
{
37 explicit LockdepObs(CephContext
*cct
)
38 : m_cct(cct
), m_registered(false), lock("lock_dep_obs", false, true) {
40 ~LockdepObs() override
{
42 lockdep_unregister_ceph_context(m_cct
);
46 const char** get_tracked_conf_keys() const override
{
47 static const char *KEYS
[] = {"lockdep", NULL
};
51 void handle_conf_change(const md_config_t
*conf
,
52 const std::set
<std::string
> &changed
) override
{
53 Mutex::Locker
locker(lock
);
54 if (conf
->lockdep
&& !m_registered
) {
55 lockdep_register_ceph_context(m_cct
);
57 } else if (!conf
->lockdep
&& m_registered
) {
58 lockdep_unregister_ceph_context(m_cct
);
68 class MempoolObs
: public md_config_obs_t
,
69 public AdminSocketHook
{
74 explicit MempoolObs(CephContext
*cct
)
75 : cct(cct
), lock("mem_pool_obs", false, true) {
76 cct
->_conf
->add_observer(this);
77 int r
= cct
->get_admin_socket()->register_command(
84 ~MempoolObs() override
{
85 cct
->_conf
->remove_observer(this);
86 cct
->get_admin_socket()->unregister_command("dump_mempools");
90 const char** get_tracked_conf_keys() const override
{
91 static const char *KEYS
[] = {
98 void handle_conf_change(const md_config_t
*conf
,
99 const std::set
<std::string
> &changed
) override
{
100 Mutex::Locker
locker(lock
);
101 if (changed
.count("mempool_debug")) {
102 mempool::set_debug_mode(cct
->_conf
->mempool_debug
);
107 bool call(std::string command
, cmdmap_t
& cmdmap
, std::string format
,
108 bufferlist
& out
) override
{
109 if (command
== "dump_mempools") {
110 std::unique_ptr
<Formatter
> f(Formatter::create(format
));
111 f
->open_object_section("mempools");
112 mempool::dump(f
.get());
121 } // anonymous namespace
123 class CephContextServiceThread
: public Thread
126 explicit CephContextServiceThread(CephContext
*cct
)
127 : _lock("CephContextServiceThread::_lock"),
128 _reopen_logs(false), _exit_thread(false), _cct(cct
)
132 ~CephContextServiceThread() override
{}
134 void *entry() override
137 Mutex::Locker
l(_lock
);
139 if (_cct
->_conf
->heartbeat_interval
) {
140 utime_t
interval(_cct
->_conf
->heartbeat_interval
, 0);
141 _cond
.WaitInterval(_lock
, interval
);
150 _cct
->_log
->reopen_log_file();
151 _reopen_logs
= false;
153 _cct
->_heartbeat_map
->check_touch_file();
155 // refresh the perf coutners
156 _cct
->refresh_perf_values();
163 Mutex::Locker
l(_lock
);
170 Mutex::Locker
l(_lock
);
185 * observe logging config changes
187 * The logging subsystem sits below most of the ceph code, including
188 * the config subsystem, to keep it simple and self-contained. Feed
189 * logging-related config changes to the log.
191 class LogObs
: public md_config_obs_t
{
192 ceph::logging::Log
*log
;
196 explicit LogObs(ceph::logging::Log
*l
)
197 : log(l
), lock("log_obs", false, true) {
200 const char** get_tracked_conf_keys() const override
{
201 static const char *KEYS
[] = {
221 void handle_conf_change(const md_config_t
*conf
,
222 const std::set
<std::string
> &changed
) override
{
223 Mutex::Locker
locker(lock
);
225 if (changed
.count("log_to_stderr") || changed
.count("err_to_stderr")) {
226 int l
= conf
->log_to_stderr
? 99 : (conf
->err_to_stderr
? -1 : -2);
227 log
->set_stderr_level(l
, l
);
231 if (changed
.count("log_to_syslog")) {
232 int l
= conf
->log_to_syslog
? 99 : (conf
->err_to_syslog
? -1 : -2);
233 log
->set_syslog_level(l
, l
);
237 if (changed
.count("log_file")) {
238 log
->set_log_file(conf
->log_file
);
239 log
->reopen_log_file();
242 if (changed
.count("log_stderr_prefix")) {
243 log
->set_log_stderr_prefix(conf
->get_val
<string
>("log_stderr_prefix"));
246 if (changed
.count("log_max_new")) {
248 log
->set_max_new(conf
->log_max_new
);
251 if (changed
.count("log_max_recent")) {
252 log
->set_max_recent(conf
->log_max_recent
);
256 if (changed
.count("log_to_graylog") || changed
.count("err_to_graylog")) {
257 int l
= conf
->log_to_graylog
? 99 : (conf
->err_to_graylog
? -1 : -2);
258 log
->set_graylog_level(l
, l
);
260 if (conf
->log_to_graylog
|| conf
->err_to_graylog
) {
261 log
->start_graylog();
262 } else if (! (conf
->log_to_graylog
&& conf
->err_to_graylog
)) {
267 if (log
->graylog() && (changed
.count("log_graylog_host") || changed
.count("log_graylog_port"))) {
268 log
->graylog()->set_destination(conf
->log_graylog_host
, conf
->log_graylog_port
);
272 if (log
->graylog() && changed
.count("host")) {
273 log
->graylog()->set_hostname(conf
->host
);
276 if (log
->graylog() && changed
.count("fsid")) {
277 log
->graylog()->set_fsid(conf
->get_val
<uuid_d
>("fsid"));
283 // cct config watcher
284 class CephContextObs
: public md_config_obs_t
{
288 explicit CephContextObs(CephContext
*cct
) : cct(cct
) {}
290 const char** get_tracked_conf_keys() const override
{
291 static const char *KEYS
[] = {
292 "enable_experimental_unrecoverable_data_corrupting_features",
299 void handle_conf_change(const md_config_t
*conf
,
300 const std::set
<std::string
> &changed
) override
{
302 "enable_experimental_unrecoverable_data_corrupting_features")) {
303 ceph_spin_lock(&cct
->_feature_lock
);
305 conf
->enable_experimental_unrecoverable_data_corrupting_features
,
306 cct
->_experimental_features
);
307 ceph_spin_unlock(&cct
->_feature_lock
);
308 if (getenv("CEPH_DEV") == NULL
) {
309 if (!cct
->_experimental_features
.empty()) {
310 if (cct
->_experimental_features
.count("*")) {
311 lderr(cct
) << "WARNING: all dangerous and experimental features are enabled." << dendl
;
313 lderr(cct
) << "WARNING: the following dangerous and experimental features are enabled: "
314 << cct
->_experimental_features
<< dendl
;
320 if (changed
.count("crush_location")) {
321 cct
->crush_location
.update_from_conf();
326 bool CephContext::check_experimental_feature_enabled(const std::string
& feat
)
328 stringstream message
;
329 bool enabled
= check_experimental_feature_enabled(feat
, &message
);
330 lderr(this) << message
.str() << dendl
;
334 bool CephContext::check_experimental_feature_enabled(const std::string
& feat
,
335 std::ostream
*message
)
337 ceph_spin_lock(&_feature_lock
);
338 bool enabled
= (_experimental_features
.count(feat
) ||
339 _experimental_features
.count("*"));
340 ceph_spin_unlock(&_feature_lock
);
343 (*message
) << "WARNING: experimental feature '" << feat
<< "' is enabled\n";
344 (*message
) << "Please be aware that this feature is experimental, untested,\n";
345 (*message
) << "unsupported, and may result in data corruption, data loss,\n";
346 (*message
) << "and/or irreparable damage to your cluster. Do not use\n";
347 (*message
) << "feature with important data.\n";
349 (*message
) << "*** experimental feature '" << feat
<< "' is not enabled ***\n";
350 (*message
) << "This feature is marked as experimental, which means it\n";
351 (*message
) << " - is untested\n";
352 (*message
) << " - is unsupported\n";
353 (*message
) << " - may corrupt your data\n";
354 (*message
) << " - may break your cluster is an unrecoverable fashion\n";
355 (*message
) << "To enable this feature, add this to your ceph.conf:\n";
356 (*message
) << " enable experimental unrecoverable data corrupting features = " << feat
<< "\n";
363 class CephContextHook
: public AdminSocketHook
{
367 explicit CephContextHook(CephContext
*cct
) : m_cct(cct
) {}
369 bool call(std::string command
, cmdmap_t
& cmdmap
, std::string format
,
370 bufferlist
& out
) override
{
371 m_cct
->do_command(command
, cmdmap
, format
, &out
);
376 void CephContext::do_command(std::string command
, cmdmap_t
& cmdmap
,
377 std::string format
, bufferlist
*out
)
379 Formatter
*f
= Formatter::create(format
, "json-pretty", "json-pretty");
381 for (cmdmap_t::iterator it
= cmdmap
.begin(); it
!= cmdmap
.end(); ++it
) {
382 if (it
->first
!= "prefix") {
383 ss
<< it
->first
<< ":" << cmd_vartype_stringify(it
->second
) << " ";
386 lgeneric_dout(this, 1) << "do_command '" << command
<< "' '"
387 << ss
.str() << dendl
;
388 if (command
== "perfcounters_dump" || command
== "1" ||
389 command
== "perf dump") {
392 cmd_getval(this, cmdmap
, "logger", logger
);
393 cmd_getval(this, cmdmap
, "counter", counter
);
394 _perf_counters_collection
->dump_formatted(f
, false, logger
, counter
);
396 else if (command
== "perfcounters_schema" || command
== "2" ||
397 command
== "perf schema") {
398 _perf_counters_collection
->dump_formatted(f
, true);
400 else if (command
== "perf histogram dump") {
403 cmd_getval(this, cmdmap
, "logger", logger
);
404 cmd_getval(this, cmdmap
, "counter", counter
);
405 _perf_counters_collection
->dump_formatted_histograms(f
, false, logger
,
408 else if (command
== "perf histogram schema") {
409 _perf_counters_collection
->dump_formatted_histograms(f
, true);
411 else if (command
== "perf reset") {
413 string section
= command
;
414 f
->open_object_section(section
.c_str());
415 if (!cmd_getval(this, cmdmap
, "var", var
)) {
416 f
->dump_string("error", "syntax error: 'perf reset <var>'");
418 if(!_perf_counters_collection
->reset(var
))
419 f
->dump_stream("error") << "Not find: " << var
;
421 f
->dump_string("success", command
+ ' ' + var
);
426 string section
= command
;
427 boost::replace_all(section
, " ", "_");
428 f
->open_object_section(section
.c_str());
429 if (command
== "config show") {
430 _conf
->show_config(f
);
432 else if (command
== "config set") {
434 std::vector
<std::string
> val
;
436 if (!(cmd_getval(this, cmdmap
, "var", var
)) ||
437 !(cmd_getval(this, cmdmap
, "val", val
))) {
438 f
->dump_string("error", "syntax error: 'config set <var> <value>'");
440 // val may be multiple words
441 string valstr
= str_join(val
, " ");
442 int r
= _conf
->set_val(var
.c_str(), valstr
.c_str());
444 f
->dump_stream("error") << "error setting '" << var
<< "' to '" << valstr
<< "': " << cpp_strerror(r
);
447 _conf
->apply_changes(&ss
);
448 f
->dump_string("success", ss
.str());
451 } else if (command
== "config get") {
453 if (!cmd_getval(this, cmdmap
, "var", var
)) {
454 f
->dump_string("error", "syntax error: 'config get <var>'");
457 memset(buf
, 0, sizeof(buf
));
459 int r
= _conf
->get_val(var
.c_str(), &tmp
, sizeof(buf
));
461 f
->dump_stream("error") << "error getting '" << var
<< "': " << cpp_strerror(r
);
463 f
->dump_string(var
.c_str(), buf
);
466 } else if (command
== "config help") {
468 if (cmd_getval(this, cmdmap
, "var", var
)) {
469 // Output a single one
470 std::string key
= ConfFile::normalize_key_name(var
);
471 const auto &i
= _conf
->schema
.find(key
);
472 if (i
== _conf
->schema
.end()) {
473 std::ostringstream msg
;
474 msg
<< "Setting not found: '" << key
<< "'";
475 f
->dump_string("error", msg
.str());
481 f
->open_array_section("options");
482 for (const auto &option
: ceph_options
) {
487 } else if (command
== "config diff") {
488 md_config_t def_conf
;
489 def_conf
.set_val("cluster", _conf
->cluster
);
490 def_conf
.name
= _conf
->name
;
491 def_conf
.set_val("host", _conf
->host
);
492 def_conf
.apply_changes(NULL
);
494 map
<string
,pair
<string
,string
> > diff
;
496 def_conf
.diff(_conf
, &diff
, &unknown
);
497 f
->open_object_section("diff");
499 f
->open_object_section("current");
500 for (map
<string
,pair
<string
,string
> >::iterator p
= diff
.begin();
501 p
!= diff
.end(); ++p
) {
502 f
->dump_string(p
->first
.c_str(), p
->second
.second
);
504 f
->close_section(); // current
505 f
->open_object_section("defaults");
506 for (map
<string
,pair
<string
,string
> >::iterator p
= diff
.begin();
507 p
!= diff
.end(); ++p
) {
508 f
->dump_string(p
->first
.c_str(), p
->second
.first
);
510 f
->close_section(); // defaults
511 f
->close_section(); // diff
513 f
->open_array_section("unknown");
514 for (set
<string
>::iterator p
= unknown
.begin();
515 p
!= unknown
.end(); ++p
) {
516 f
->dump_string("option", *p
);
518 f
->close_section(); // unknown
519 } else if (command
== "config diff get") {
521 if (!cmd_getval(this, cmdmap
, "var", setting
)) {
522 f
->dump_string("error", "syntax error: 'config diff get <var>'");
524 md_config_t def_conf
;
525 def_conf
.set_val("cluster", _conf
->cluster
);
526 def_conf
.name
= _conf
->name
;
527 def_conf
.set_val("host", _conf
->host
);
528 def_conf
.apply_changes(NULL
);
530 map
<string
, pair
<string
, string
>> diff
;
532 def_conf
.diff(_conf
, &diff
, &unknown
, setting
);
533 f
->open_object_section("diff");
534 f
->open_object_section("current");
536 for (const auto& p
: diff
) {
537 f
->dump_string(p
.first
.c_str(), p
.second
.second
);
539 f
->close_section(); //-- current
541 f
->open_object_section("defaults");
542 for (const auto& p
: diff
) {
543 f
->dump_string(p
.first
.c_str(), p
.second
.first
);
545 f
->close_section(); //-- defaults
546 f
->close_section(); //-- diff
548 } else if (command
== "log flush") {
551 else if (command
== "log dump") {
554 else if (command
== "log reopen") {
555 _log
->reopen_log_file();
558 assert(0 == "registered under wrong command?");
564 lgeneric_dout(this, 1) << "do_command '" << command
<< "' '" << ss
.str()
565 << "result is " << out
->length() << " bytes" << dendl
;
568 CephContext::CephContext(uint32_t module_type_
,
569 enum code_environment_t code_env
,
572 _conf(new md_config_t(code_env
== CODE_ENVIRONMENT_DAEMON
)),
574 _module_type(module_type_
),
575 _init_flags(init_flags_
),
580 _crypto_inited(false),
581 _service_thread(NULL
),
584 _perf_counters_collection(NULL
),
585 _perf_counters_conf_obs(NULL
),
586 _heartbeat_map(NULL
),
589 _plugin_registry(NULL
),
591 crush_location(this),
594 ceph_spin_init(&_service_thread_lock
);
595 ceph_spin_init(&_associated_objs_lock
);
596 ceph_spin_init(&_fork_watchers_lock
);
597 ceph_spin_init(&_feature_lock
);
598 ceph_spin_init(&_cct_perf_lock
);
600 _log
= new ceph::logging::Log(&_conf
->subsys
);
603 _log_obs
= new LogObs(_log
);
604 _conf
->add_observer(_log_obs
);
606 _cct_obs
= new CephContextObs(this);
607 _conf
->add_observer(_cct_obs
);
609 _lockdep_obs
= new LockdepObs(this);
610 _conf
->add_observer(_lockdep_obs
);
612 _perf_counters_collection
= new PerfCountersCollection(this);
614 _admin_socket
= new AdminSocket(this);
615 _heartbeat_map
= new HeartbeatMap(this);
617 _plugin_registry
= new PluginRegistry(this);
619 _admin_hook
= new CephContextHook(this);
620 _admin_socket
->register_command("perfcounters_dump", "perfcounters_dump", _admin_hook
, "");
621 _admin_socket
->register_command("1", "1", _admin_hook
, "");
622 _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");
623 _admin_socket
->register_command("perfcounters_schema", "perfcounters_schema", _admin_hook
, "");
624 _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");
625 _admin_socket
->register_command("2", "2", _admin_hook
, "");
626 _admin_socket
->register_command("perf schema", "perf schema", _admin_hook
, "dump perfcounters schema");
627 _admin_socket
->register_command("perf histogram schema", "perf histogram schema", _admin_hook
, "dump perf histogram schema");
628 _admin_socket
->register_command("perf reset", "perf reset name=var,type=CephString", _admin_hook
, "perf reset <name>: perf reset all or one perfcounter name");
629 _admin_socket
->register_command("config show", "config show", _admin_hook
, "dump current config settings");
630 _admin_socket
->register_command("config help", "config help name=var,type=CephString,req=false", _admin_hook
, "get config setting schema and descriptions");
631 _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");
632 _admin_socket
->register_command("config get", "config get name=var,type=CephString", _admin_hook
, "config get <field>: get the config value");
633 _admin_socket
->register_command("config diff",
634 "config diff", _admin_hook
,
635 "dump diff of current config and default config");
636 _admin_socket
->register_command("config diff get",
637 "config diff get name=var,type=CephString", _admin_hook
,
638 "dump diff get <field>: dump diff of current and default config setting <field>");
639 _admin_socket
->register_command("log flush", "log flush", _admin_hook
, "flush log entries to log file");
640 _admin_socket
->register_command("log dump", "log dump", _admin_hook
, "dump recent log entries to log file");
641 _admin_socket
->register_command("log reopen", "log reopen", _admin_hook
, "reopen log file");
643 _crypto_none
= CryptoHandler::create(CEPH_CRYPTO_NONE
);
644 _crypto_aes
= CryptoHandler::create(CEPH_CRYPTO_AES
);
646 MempoolObs
*mempool_obs
= 0;
647 lookup_or_create_singleton_object(mempool_obs
, "mempool_obs");
650 CephContext::~CephContext()
652 join_service_thread();
654 for (map
<string
, SingletonWrapper
*>::iterator it
= _associated_objs
.begin();
655 it
!= _associated_objs
.end(); ++it
)
659 _perf_counters_collection
->remove(_cct_perf
);
664 delete _plugin_registry
;
666 _admin_socket
->unregister_command("perfcounters_dump");
667 _admin_socket
->unregister_command("1");
668 _admin_socket
->unregister_command("perf dump");
669 _admin_socket
->unregister_command("perfcounters_schema");
670 _admin_socket
->unregister_command("perf histogram dump");
671 _admin_socket
->unregister_command("2");
672 _admin_socket
->unregister_command("perf schema");
673 _admin_socket
->unregister_command("perf histogram schema");
674 _admin_socket
->unregister_command("perf reset");
675 _admin_socket
->unregister_command("config show");
676 _admin_socket
->unregister_command("config set");
677 _admin_socket
->unregister_command("config get");
678 _admin_socket
->unregister_command("config help");
679 _admin_socket
->unregister_command("config diff");
680 _admin_socket
->unregister_command("config diff get");
681 _admin_socket
->unregister_command("log flush");
682 _admin_socket
->unregister_command("log dump");
683 _admin_socket
->unregister_command("log reopen");
685 delete _admin_socket
;
687 delete _heartbeat_map
;
689 delete _perf_counters_collection
;
690 _perf_counters_collection
= NULL
;
692 delete _perf_counters_conf_obs
;
693 _perf_counters_conf_obs
= NULL
;
695 _conf
->remove_observer(_log_obs
);
699 _conf
->remove_observer(_cct_obs
);
703 _conf
->remove_observer(_lockdep_obs
);
712 ceph_spin_destroy(&_service_thread_lock
);
713 ceph_spin_destroy(&_fork_watchers_lock
);
714 ceph_spin_destroy(&_associated_objs_lock
);
715 ceph_spin_destroy(&_feature_lock
);
716 ceph_spin_destroy(&_cct_perf_lock
);
721 ceph::crypto::shutdown(g_code_env
== CODE_ENVIRONMENT_LIBRARY
);
724 void CephContext::put() {
726 ANNOTATE_HAPPENS_AFTER(&nref
);
727 ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&nref
);
730 ANNOTATE_HAPPENS_BEFORE(&nref
);
734 void CephContext::init_crypto()
736 if (!_crypto_inited
) {
737 ceph::crypto::init(this);
738 _crypto_inited
= true;
742 void CephContext::start_service_thread()
744 ceph_spin_lock(&_service_thread_lock
);
745 if (_service_thread
) {
746 ceph_spin_unlock(&_service_thread_lock
);
749 _service_thread
= new CephContextServiceThread(this);
750 _service_thread
->create("service");
751 ceph_spin_unlock(&_service_thread_lock
);
753 // make logs flush on_exit()
754 if (_conf
->log_flush_on_exit
)
755 _log
->set_flush_on_exit();
757 // Trigger callbacks on any config observers that were waiting for
758 // it to become safe to start threads.
759 _conf
->set_val("internal_safe_to_start_threads", "true");
760 _conf
->call_all_observers();
762 // start admin socket
763 if (_conf
->admin_socket
.length())
764 _admin_socket
->init(_conf
->admin_socket
);
767 void CephContext::reopen_logs()
769 ceph_spin_lock(&_service_thread_lock
);
771 _service_thread
->reopen_logs();
772 ceph_spin_unlock(&_service_thread_lock
);
775 void CephContext::join_service_thread()
777 ceph_spin_lock(&_service_thread_lock
);
778 CephContextServiceThread
*thread
= _service_thread
;
780 ceph_spin_unlock(&_service_thread_lock
);
783 _service_thread
= NULL
;
784 ceph_spin_unlock(&_service_thread_lock
);
786 thread
->exit_thread();
791 uint32_t CephContext::get_module_type() const
796 void CephContext::set_init_flags(int flags
)
801 int CephContext::get_init_flags() const
806 PerfCountersCollection
*CephContext::get_perfcounters_collection()
808 return _perf_counters_collection
;
811 void CephContext::enable_perf_counter()
813 PerfCountersBuilder
plb(this, "cct", l_cct_first
, l_cct_last
);
814 plb
.add_u64(l_cct_total_workers
, "total_workers", "Total workers");
815 plb
.add_u64(l_cct_unhealthy_workers
, "unhealthy_workers", "Unhealthy workers");
816 PerfCounters
*perf_tmp
= plb
.create_perf_counters();
818 ceph_spin_lock(&_cct_perf_lock
);
819 assert(_cct_perf
== NULL
);
820 _cct_perf
= perf_tmp
;
821 ceph_spin_unlock(&_cct_perf_lock
);
823 _perf_counters_collection
->add(_cct_perf
);
826 void CephContext::disable_perf_counter()
828 _perf_counters_collection
->remove(_cct_perf
);
830 ceph_spin_lock(&_cct_perf_lock
);
833 ceph_spin_unlock(&_cct_perf_lock
);
836 void CephContext::refresh_perf_values()
838 ceph_spin_lock(&_cct_perf_lock
);
840 _cct_perf
->set(l_cct_total_workers
, _heartbeat_map
->get_total_workers());
841 _cct_perf
->set(l_cct_unhealthy_workers
, _heartbeat_map
->get_unhealthy_workers());
843 ceph_spin_unlock(&_cct_perf_lock
);
846 AdminSocket
*CephContext::get_admin_socket()
848 return _admin_socket
;
851 CryptoHandler
*CephContext::get_crypto_handler(int type
)
854 case CEPH_CRYPTO_NONE
:
856 case CEPH_CRYPTO_AES
: