]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2011 New Dream Network | |
7 | * Copyright (C) 2017 OVH | |
8 | * | |
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. | |
13 | * | |
14 | */ | |
15 | ||
11fdf7f2 TL |
16 | #include "common/ceph_context.h" |
17 | ||
18 | #include <mutex> | |
19 | #include <iostream> | |
20 | ||
21 | #include <pthread.h> | |
22 | ||
7c673cae FG |
23 | #include <boost/algorithm/string.hpp> |
24 | ||
9f95a23c | 25 | #include "include/common_fwd.h" |
7c673cae | 26 | #include "include/mempool.h" |
9f95a23c | 27 | #include "include/stringify.h" |
7c673cae | 28 | #include "common/admin_socket.h" |
7c673cae | 29 | #include "common/code_environment.h" |
11fdf7f2 TL |
30 | #include "common/ceph_mutex.h" |
31 | #include "common/debug.h" | |
32 | #include "common/config.h" | |
7c673cae | 33 | #include "common/ceph_crypto.h" |
20effc67 | 34 | #include "common/hostname.h" |
7c673cae FG |
35 | #include "common/HeartbeatMap.h" |
36 | #include "common/errno.h" | |
7c673cae | 37 | #include "common/Graylog.h" |
20effc67 TL |
38 | #ifdef CEPH_DEBUG_MUTEX |
39 | #include "common/lockdep.h" | |
40 | #endif | |
11fdf7f2 TL |
41 | |
42 | #include "log/Log.h" | |
43 | ||
7c673cae FG |
44 | #include "auth/Crypto.h" |
45 | #include "include/str_list.h" | |
11fdf7f2 TL |
46 | #include "common/config.h" |
47 | #include "common/config_obs.h" | |
7c673cae | 48 | #include "common/PluginRegistry.h" |
11fdf7f2 TL |
49 | #include "common/valgrind.h" |
50 | #include "include/spinlock.h" | |
f91f0fd5 TL |
51 | #if !(defined(WITH_SEASTAR) && !defined(WITH_ALIEN)) |
52 | #include "mon/MonMap.h" | |
53 | #endif | |
7c673cae | 54 | |
11fdf7f2 TL |
55 | // for CINIT_FLAGS |
56 | #include "common/common_init.h" | |
57 | ||
58 | #include <iostream> | |
59 | #include <pthread.h> | |
60 | ||
f67539c2 TL |
61 | using namespace std::literals; |
62 | ||
63 | using ceph::bufferlist; | |
64 | using ceph::HeartbeatMap; | |
65 | ||
66 | ||
9f95a23c TL |
67 | #if defined(WITH_SEASTAR) && !defined(WITH_ALIEN) |
68 | namespace crimson::common { | |
11fdf7f2 | 69 | CephContext::CephContext() |
9f95a23c TL |
70 | : _conf{crimson::common::local_conf()}, |
71 | _perf_counters_collection{crimson::common::local_perf_coll()}, | |
11fdf7f2 TL |
72 | _crypto_random{std::make_unique<CryptoRandom>()} |
73 | {} | |
74 | ||
75 | // define the dtor in .cc as CryptoRandom is an incomplete type in the header | |
76 | CephContext::~CephContext() | |
77 | {} | |
78 | ||
79 | uint32_t CephContext::get_module_type() const | |
80 | { | |
81 | return CEPH_ENTITY_TYPE_OSD; | |
82 | } | |
83 | ||
84 | CryptoRandom* CephContext::random() const | |
85 | { | |
86 | return _crypto_random.get(); | |
87 | } | |
88 | ||
89 | CephContext* CephContext::get() | |
90 | { | |
91 | ++nref; | |
92 | return this; | |
93 | } | |
94 | ||
95 | void CephContext::put() | |
96 | { | |
97 | if (--nref == 0) { | |
98 | delete this; | |
99 | } | |
100 | } | |
101 | ||
102 | PerfCountersCollectionImpl* CephContext::get_perfcounters_collection() | |
103 | { | |
104 | return _perf_counters_collection.get_perf_collection(); | |
105 | } | |
106 | ||
9f95a23c | 107 | } |
11fdf7f2 | 108 | #else // WITH_SEASTAR |
7c673cae FG |
109 | namespace { |
110 | ||
20effc67 | 111 | #ifdef CEPH_DEBUG_MUTEX |
7c673cae FG |
112 | class LockdepObs : public md_config_obs_t { |
113 | public: | |
f64942e4 | 114 | explicit LockdepObs(CephContext *cct) |
11fdf7f2 | 115 | : m_cct(cct), m_registered(false), lock(ceph::make_mutex("lock_dep_obs")) { |
7c673cae FG |
116 | } |
117 | ~LockdepObs() override { | |
118 | if (m_registered) { | |
119 | lockdep_unregister_ceph_context(m_cct); | |
120 | } | |
121 | } | |
122 | ||
123 | const char** get_tracked_conf_keys() const override { | |
124 | static const char *KEYS[] = {"lockdep", NULL}; | |
125 | return KEYS; | |
126 | } | |
127 | ||
11fdf7f2 | 128 | void handle_conf_change(const ConfigProxy& conf, |
7c673cae | 129 | const std::set <std::string> &changed) override { |
11fdf7f2 | 130 | std::unique_lock locker(lock); |
7c673cae FG |
131 | if (conf->lockdep && !m_registered) { |
132 | lockdep_register_ceph_context(m_cct); | |
133 | m_registered = true; | |
134 | } else if (!conf->lockdep && m_registered) { | |
135 | lockdep_unregister_ceph_context(m_cct); | |
136 | m_registered = false; | |
137 | } | |
138 | } | |
139 | private: | |
140 | CephContext *m_cct; | |
141 | bool m_registered; | |
11fdf7f2 | 142 | ceph::mutex lock; |
7c673cae | 143 | }; |
20effc67 | 144 | #endif // CEPH_DEBUG_MUTEX |
7c673cae FG |
145 | |
146 | class MempoolObs : public md_config_obs_t, | |
147 | public AdminSocketHook { | |
148 | CephContext *cct; | |
11fdf7f2 | 149 | ceph::mutex lock; |
7c673cae FG |
150 | |
151 | public: | |
f64942e4 | 152 | explicit MempoolObs(CephContext *cct) |
11fdf7f2 TL |
153 | : cct(cct), lock(ceph::make_mutex("mem_pool_obs")) { |
154 | cct->_conf.add_observer(this); | |
7c673cae | 155 | int r = cct->get_admin_socket()->register_command( |
7c673cae FG |
156 | "dump_mempools", |
157 | this, | |
158 | "get mempool stats"); | |
11fdf7f2 | 159 | ceph_assert(r == 0); |
7c673cae FG |
160 | } |
161 | ~MempoolObs() override { | |
11fdf7f2 | 162 | cct->_conf.remove_observer(this); |
9f95a23c | 163 | cct->get_admin_socket()->unregister_commands(this); |
7c673cae FG |
164 | } |
165 | ||
166 | // md_config_obs_t | |
167 | const char** get_tracked_conf_keys() const override { | |
168 | static const char *KEYS[] = { | |
169 | "mempool_debug", | |
170 | NULL | |
171 | }; | |
172 | return KEYS; | |
173 | } | |
174 | ||
11fdf7f2 | 175 | void handle_conf_change(const ConfigProxy& conf, |
7c673cae | 176 | const std::set <std::string> &changed) override { |
11fdf7f2 | 177 | std::unique_lock locker(lock); |
7c673cae FG |
178 | if (changed.count("mempool_debug")) { |
179 | mempool::set_debug_mode(cct->_conf->mempool_debug); | |
180 | } | |
181 | } | |
182 | ||
183 | // AdminSocketHook | |
9f95a23c | 184 | int call(std::string_view command, const cmdmap_t& cmdmap, |
39ae355f | 185 | const bufferlist& inbl, |
f67539c2 | 186 | ceph::Formatter *f, |
9f95a23c TL |
187 | std::ostream& errss, |
188 | bufferlist& out) override { | |
7c673cae | 189 | if (command == "dump_mempools") { |
7c673cae | 190 | f->open_object_section("mempools"); |
9f95a23c | 191 | mempool::dump(f); |
7c673cae | 192 | f->close_section(); |
9f95a23c | 193 | return 0; |
7c673cae | 194 | } |
9f95a23c | 195 | return -ENOSYS; |
7c673cae FG |
196 | } |
197 | }; | |
198 | ||
199 | } // anonymous namespace | |
200 | ||
9f95a23c | 201 | namespace ceph::common { |
7c673cae FG |
202 | class CephContextServiceThread : public Thread |
203 | { | |
204 | public: | |
205 | explicit CephContextServiceThread(CephContext *cct) | |
11fdf7f2 | 206 | : _reopen_logs(false), _exit_thread(false), _cct(cct) |
7c673cae FG |
207 | { |
208 | } | |
209 | ||
210 | ~CephContextServiceThread() override {} | |
211 | ||
212 | void *entry() override | |
213 | { | |
214 | while (1) { | |
11fdf7f2 | 215 | std::unique_lock l(_lock); |
eafe8130 TL |
216 | if (_exit_thread) { |
217 | break; | |
218 | } | |
7c673cae FG |
219 | |
220 | if (_cct->_conf->heartbeat_interval) { | |
11fdf7f2 TL |
221 | auto interval = ceph::make_timespan(_cct->_conf->heartbeat_interval); |
222 | _cond.wait_for(l, interval); | |
7c673cae | 223 | } else |
11fdf7f2 | 224 | _cond.wait(l); |
7c673cae FG |
225 | |
226 | if (_exit_thread) { | |
227 | break; | |
228 | } | |
229 | ||
230 | if (_reopen_logs) { | |
231 | _cct->_log->reopen_log_file(); | |
232 | _reopen_logs = false; | |
233 | } | |
234 | _cct->_heartbeat_map->check_touch_file(); | |
235 | ||
236 | // refresh the perf coutners | |
11fdf7f2 | 237 | _cct->_refresh_perf_values(); |
7c673cae FG |
238 | } |
239 | return NULL; | |
240 | } | |
241 | ||
242 | void reopen_logs() | |
243 | { | |
11fdf7f2 | 244 | std::lock_guard l(_lock); |
7c673cae | 245 | _reopen_logs = true; |
11fdf7f2 | 246 | _cond.notify_all(); |
7c673cae FG |
247 | } |
248 | ||
249 | void exit_thread() | |
250 | { | |
11fdf7f2 | 251 | std::lock_guard l(_lock); |
7c673cae | 252 | _exit_thread = true; |
11fdf7f2 | 253 | _cond.notify_all(); |
7c673cae FG |
254 | } |
255 | ||
256 | private: | |
11fdf7f2 TL |
257 | ceph::mutex _lock = ceph::make_mutex("CephContextServiceThread::_lock"); |
258 | ceph::condition_variable _cond; | |
7c673cae FG |
259 | bool _reopen_logs; |
260 | bool _exit_thread; | |
261 | CephContext *_cct; | |
262 | }; | |
9f95a23c | 263 | } |
7c673cae FG |
264 | |
265 | /** | |
266 | * observe logging config changes | |
267 | * | |
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. | |
271 | */ | |
272 | class LogObs : public md_config_obs_t { | |
273 | ceph::logging::Log *log; | |
11fdf7f2 | 274 | ceph::mutex lock; |
7c673cae FG |
275 | |
276 | public: | |
f64942e4 | 277 | explicit LogObs(ceph::logging::Log *l) |
11fdf7f2 | 278 | : log(l), lock(ceph::make_mutex("log_obs")) { |
f64942e4 | 279 | } |
7c673cae FG |
280 | |
281 | const char** get_tracked_conf_keys() const override { | |
282 | static const char *KEYS[] = { | |
283 | "log_file", | |
284 | "log_max_new", | |
285 | "log_max_recent", | |
11fdf7f2 | 286 | "log_to_file", |
7c673cae FG |
287 | "log_to_syslog", |
288 | "err_to_syslog", | |
b32b8144 | 289 | "log_stderr_prefix", |
7c673cae FG |
290 | "log_to_stderr", |
291 | "err_to_stderr", | |
292 | "log_to_graylog", | |
293 | "err_to_graylog", | |
294 | "log_graylog_host", | |
295 | "log_graylog_port", | |
20effc67 TL |
296 | "log_to_journald", |
297 | "err_to_journald", | |
11fdf7f2 | 298 | "log_coarse_timestamps", |
7c673cae FG |
299 | "fsid", |
300 | "host", | |
301 | NULL | |
302 | }; | |
303 | return KEYS; | |
304 | } | |
305 | ||
11fdf7f2 | 306 | void handle_conf_change(const ConfigProxy& conf, |
7c673cae | 307 | const std::set <std::string> &changed) override { |
11fdf7f2 | 308 | std::unique_lock locker(lock); |
7c673cae FG |
309 | // stderr |
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); | |
313 | } | |
314 | ||
315 | // syslog | |
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); | |
319 | } | |
320 | ||
321 | // file | |
11fdf7f2 TL |
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); | |
326 | } else { | |
327 | log->set_log_file({}); | |
328 | } | |
7c673cae FG |
329 | log->reopen_log_file(); |
330 | } | |
331 | ||
b32b8144 | 332 | if (changed.count("log_stderr_prefix")) { |
f67539c2 | 333 | log->set_log_stderr_prefix(conf.get_val<std::string>("log_stderr_prefix")); |
b32b8144 FG |
334 | } |
335 | ||
7c673cae FG |
336 | if (changed.count("log_max_new")) { |
337 | ||
338 | log->set_max_new(conf->log_max_new); | |
339 | } | |
340 | ||
341 | if (changed.count("log_max_recent")) { | |
342 | log->set_max_recent(conf->log_max_recent); | |
343 | } | |
344 | ||
345 | // graylog | |
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); | |
349 | ||
350 | if (conf->log_to_graylog || conf->err_to_graylog) { | |
20effc67 | 351 | log->start_graylog(conf->host, conf.get_val<uuid_d>("fsid")); |
7c673cae FG |
352 | } else if (! (conf->log_to_graylog && conf->err_to_graylog)) { |
353 | log->stop_graylog(); | |
354 | } | |
355 | } | |
356 | ||
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); | |
359 | } | |
360 | ||
20effc67 TL |
361 | // journald |
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); | |
365 | ||
366 | if (l > -2) { | |
367 | log->start_journald_logger(); | |
368 | } else { | |
369 | log->stop_journald_logger(); | |
370 | } | |
371 | } | |
372 | ||
11fdf7f2 TL |
373 | if (changed.find("log_coarse_timestamps") != changed.end()) { |
374 | log->set_coarse_timestamps(conf.get_val<bool>("log_coarse_timestamps")); | |
375 | } | |
376 | ||
7c673cae FG |
377 | // metadata |
378 | if (log->graylog() && changed.count("host")) { | |
379 | log->graylog()->set_hostname(conf->host); | |
380 | } | |
381 | ||
382 | if (log->graylog() && changed.count("fsid")) { | |
11fdf7f2 | 383 | log->graylog()->set_fsid(conf.get_val<uuid_d>("fsid")); |
7c673cae FG |
384 | } |
385 | } | |
386 | }; | |
387 | ||
388 | ||
9f95a23c | 389 | namespace ceph::common { |
7c673cae FG |
390 | // cct config watcher |
391 | class CephContextObs : public md_config_obs_t { | |
392 | CephContext *cct; | |
393 | ||
394 | public: | |
395 | explicit CephContextObs(CephContext *cct) : cct(cct) {} | |
396 | ||
397 | const char** get_tracked_conf_keys() const override { | |
398 | static const char *KEYS[] = { | |
399 | "enable_experimental_unrecoverable_data_corrupting_features", | |
400 | "crush_location", | |
9f95a23c | 401 | "container_image", // just so we don't hear complaints about it! |
7c673cae FG |
402 | NULL |
403 | }; | |
404 | return KEYS; | |
405 | } | |
406 | ||
11fdf7f2 | 407 | void handle_conf_change(const ConfigProxy& conf, |
7c673cae FG |
408 | const std::set <std::string> &changed) override { |
409 | if (changed.count( | |
410 | "enable_experimental_unrecoverable_data_corrupting_features")) { | |
11fdf7f2 | 411 | std::lock_guard lg(cct->_feature_lock); |
f67539c2 TL |
412 | |
413 | cct->_experimental_features.clear(); | |
414 | auto add_experimental_feature = [this] (auto feature) { | |
415 | cct->_experimental_features.emplace(std::string{feature}); | |
416 | }; | |
417 | for_each_substr(conf->enable_experimental_unrecoverable_data_corrupting_features, | |
418 | ";,= \t", add_experimental_feature); | |
419 | ||
7c673cae FG |
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; | |
424 | } else { | |
425 | lderr(cct) << "WARNING: the following dangerous and experimental features are enabled: " | |
426 | << cct->_experimental_features << dendl; | |
427 | } | |
428 | } | |
429 | } | |
430 | ||
431 | } | |
432 | if (changed.count("crush_location")) { | |
433 | cct->crush_location.update_from_conf(); | |
434 | } | |
435 | } | |
436 | }; | |
9f95a23c TL |
437 | // perfcounter hooks |
438 | ||
439 | class CephContextHook : public AdminSocketHook { | |
440 | CephContext *m_cct; | |
441 | ||
442 | public: | |
443 | explicit CephContextHook(CephContext *cct) : m_cct(cct) {} | |
444 | ||
445 | int call(std::string_view command, const cmdmap_t& cmdmap, | |
39ae355f | 446 | const bufferlist& inbl, |
9f95a23c TL |
447 | Formatter *f, |
448 | std::ostream& errss, | |
449 | bufferlist& out) override { | |
450 | try { | |
451 | return m_cct->do_command(command, cmdmap, f, errss, &out); | |
452 | } catch (const bad_cmd_get& e) { | |
453 | return -EINVAL; | |
454 | } | |
455 | } | |
456 | }; | |
457 | ||
7c673cae FG |
458 | |
459 | bool CephContext::check_experimental_feature_enabled(const std::string& feat) | |
460 | { | |
f67539c2 | 461 | std::stringstream message; |
7c673cae FG |
462 | bool enabled = check_experimental_feature_enabled(feat, &message); |
463 | lderr(this) << message.str() << dendl; | |
464 | return enabled; | |
465 | } | |
466 | ||
467 | bool CephContext::check_experimental_feature_enabled(const std::string& feat, | |
468 | std::ostream *message) | |
469 | { | |
11fdf7f2 TL |
470 | std::unique_lock<ceph::spinlock> lg(_feature_lock); |
471 | ||
7c673cae FG |
472 | bool enabled = (_experimental_features.count(feat) || |
473 | _experimental_features.count("*")); | |
7c673cae FG |
474 | |
475 | if (enabled) { | |
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"; | |
481 | } else { | |
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"; | |
490 | } | |
491 | return enabled; | |
492 | } | |
493 | ||
9f95a23c TL |
494 | int CephContext::do_command(std::string_view command, const cmdmap_t& cmdmap, |
495 | Formatter *f, | |
496 | std::ostream& ss, | |
497 | bufferlist *out) | |
498 | { | |
499 | try { | |
500 | return _do_command(command, cmdmap, f, ss, out); | |
501 | } catch (const bad_cmd_get& e) { | |
502 | ss << e.what(); | |
503 | return -EINVAL; | |
7c673cae | 504 | } |
9f95a23c | 505 | } |
7c673cae | 506 | |
39ae355f TL |
507 | #pragma GCC push_options |
508 | #pragma GCC optimize ("O0") | |
509 | static void leak_some_memory() { | |
510 | volatile char *foo = new char[1234]; | |
511 | (void)foo; | |
512 | } | |
513 | #pragma GCC pop_options | |
514 | ||
9f95a23c TL |
515 | int CephContext::_do_command( |
516 | std::string_view command, const cmdmap_t& cmdmap, | |
517 | Formatter *f, | |
518 | std::ostream& ss, | |
519 | bufferlist *out) | |
7c673cae | 520 | { |
9f95a23c TL |
521 | int r = 0; |
522 | lgeneric_dout(this, 1) << "do_command '" << command << "' '" << cmdmap << "'" | |
523 | << dendl; | |
524 | ceph_assert_always(!(command == "assert" && _conf->debug_asok_assert_abort)); | |
525 | if (command == "abort") { | |
526 | if (_conf->debug_asok_assert_abort) { | |
527 | ceph_abort(); | |
528 | } else { | |
529 | return -EPERM; | |
7c673cae FG |
530 | } |
531 | } | |
9f95a23c | 532 | if (command == "leak_some_memory") { |
39ae355f | 533 | leak_some_memory(); |
11fdf7f2 | 534 | } |
9f95a23c | 535 | else if (command == "perfcounters_dump" || command == "1" || |
7c673cae FG |
536 | command == "perf dump") { |
537 | std::string logger; | |
538 | std::string counter; | |
9f95a23c TL |
539 | cmd_getval(cmdmap, "logger", logger); |
540 | cmd_getval(cmdmap, "counter", counter); | |
1e59de90 | 541 | _perf_counters_collection->dump_formatted(f, false, false, logger, counter); |
7c673cae FG |
542 | } |
543 | else if (command == "perfcounters_schema" || command == "2" || | |
544 | command == "perf schema") { | |
1e59de90 TL |
545 | _perf_counters_collection->dump_formatted(f, true, false); |
546 | } | |
547 | else if (command == "counter dump") { | |
548 | _perf_counters_collection->dump_formatted(f, false, true); | |
549 | } | |
550 | else if (command == "counter schema") { | |
551 | _perf_counters_collection->dump_formatted(f, true, true); | |
7c673cae FG |
552 | } |
553 | else if (command == "perf histogram dump") { | |
554 | std::string logger; | |
555 | std::string counter; | |
9f95a23c TL |
556 | cmd_getval(cmdmap, "logger", logger); |
557 | cmd_getval(cmdmap, "counter", counter); | |
7c673cae FG |
558 | _perf_counters_collection->dump_formatted_histograms(f, false, logger, |
559 | counter); | |
560 | } | |
561 | else if (command == "perf histogram schema") { | |
562 | _perf_counters_collection->dump_formatted_histograms(f, true); | |
563 | } | |
564 | else if (command == "perf reset") { | |
565 | std::string var; | |
11fdf7f2 | 566 | std::string section(command); |
7c673cae | 567 | f->open_object_section(section.c_str()); |
9f95a23c | 568 | if (!cmd_getval(cmdmap, "var", var)) { |
7c673cae FG |
569 | f->dump_string("error", "syntax error: 'perf reset <var>'"); |
570 | } else { | |
571 | if(!_perf_counters_collection->reset(var)) | |
572 | f->dump_stream("error") << "Not find: " << var; | |
573 | else | |
11fdf7f2 | 574 | f->dump_string("success", std::string(command) + ' ' + var); |
7c673cae FG |
575 | } |
576 | f->close_section(); | |
577 | } | |
578 | else { | |
11fdf7f2 | 579 | std::string section(command); |
7c673cae FG |
580 | boost::replace_all(section, " ", "_"); |
581 | f->open_object_section(section.c_str()); | |
582 | if (command == "config show") { | |
11fdf7f2 TL |
583 | _conf.show_config(f); |
584 | } | |
585 | else if (command == "config unset") { | |
586 | std::string var; | |
9f95a23c TL |
587 | if (!(cmd_getval(cmdmap, "var", var))) { |
588 | r = -EINVAL; | |
11fdf7f2 | 589 | } else { |
9f95a23c | 590 | r = _conf.rm_val(var.c_str()); |
11fdf7f2 | 591 | if (r < 0 && r != -ENOENT) { |
9f95a23c TL |
592 | ss << "error unsetting '" << var << "': " |
593 | << cpp_strerror(r); | |
11fdf7f2 | 594 | } else { |
11fdf7f2 | 595 | _conf.apply_changes(&ss); |
9f95a23c | 596 | r = 0; |
11fdf7f2 TL |
597 | } |
598 | } | |
599 | ||
7c673cae FG |
600 | } |
601 | else if (command == "config set") { | |
602 | std::string var; | |
603 | std::vector<std::string> val; | |
604 | ||
9f95a23c TL |
605 | if (!(cmd_getval(cmdmap, "var", var)) || |
606 | !(cmd_getval(cmdmap, "val", val))) { | |
607 | r = -EINVAL; | |
7c673cae FG |
608 | } else { |
609 | // val may be multiple words | |
f67539c2 | 610 | auto valstr = str_join(val, " "); |
9f95a23c | 611 | r = _conf.set_val(var.c_str(), valstr.c_str()); |
7c673cae | 612 | if (r < 0) { |
9f95a23c TL |
613 | ss << "error setting '" << var << "' to '" << valstr << "': " |
614 | << cpp_strerror(r); | |
7c673cae | 615 | } else { |
f67539c2 | 616 | std::stringstream ss; |
11fdf7f2 | 617 | _conf.apply_changes(&ss); |
9f95a23c | 618 | f->dump_string("success", ss.str()); |
7c673cae FG |
619 | } |
620 | } | |
621 | } else if (command == "config get") { | |
622 | std::string var; | |
9f95a23c TL |
623 | if (!cmd_getval(cmdmap, "var", var)) { |
624 | r = -EINVAL; | |
7c673cae FG |
625 | } else { |
626 | char buf[4096]; | |
92f5a8d4 | 627 | // FIPS zeroization audit 20191115: this memset is not security related. |
7c673cae FG |
628 | memset(buf, 0, sizeof(buf)); |
629 | char *tmp = buf; | |
9f95a23c | 630 | r = _conf.get_val(var.c_str(), &tmp, sizeof(buf)); |
7c673cae | 631 | if (r < 0) { |
9f95a23c | 632 | ss << "error getting '" << var << "': " << cpp_strerror(r); |
7c673cae | 633 | } else { |
9f95a23c | 634 | f->dump_string(var.c_str(), buf); |
7c673cae FG |
635 | } |
636 | } | |
c07f9fc5 FG |
637 | } else if (command == "config help") { |
638 | std::string var; | |
9f95a23c | 639 | if (cmd_getval(cmdmap, "var", var)) { |
c07f9fc5 FG |
640 | // Output a single one |
641 | std::string key = ConfFile::normalize_key_name(var); | |
11fdf7f2 TL |
642 | auto schema = _conf.get_schema(key); |
643 | if (!schema) { | |
9f95a23c TL |
644 | ss << "Setting not found: '" << key << "'"; |
645 | r = -ENOENT; | |
c07f9fc5 | 646 | } else { |
11fdf7f2 | 647 | f->dump_object("option", *schema); |
c07f9fc5 FG |
648 | } |
649 | } else { | |
650 | // Output all | |
651 | f->open_array_section("options"); | |
652 | for (const auto &option : ceph_options) { | |
11fdf7f2 | 653 | f->dump_object("option", option); |
c07f9fc5 FG |
654 | } |
655 | f->close_section(); | |
656 | } | |
7c673cae | 657 | } else if (command == "config diff") { |
7c673cae | 658 | f->open_object_section("diff"); |
11fdf7f2 | 659 | _conf.diff(f); |
7c673cae | 660 | f->close_section(); // unknown |
31f18b77 FG |
661 | } else if (command == "config diff get") { |
662 | std::string setting; | |
11fdf7f2 TL |
663 | f->open_object_section("diff"); |
664 | _conf.diff(f, setting); | |
665 | f->close_section(); // unknown | |
9f95a23c TL |
666 | } |
667 | else if (command == "injectargs") { | |
f67539c2 | 668 | std::vector<std::string> argsvec; |
9f95a23c TL |
669 | cmd_getval(cmdmap, "injected_args", argsvec); |
670 | if (!argsvec.empty()) { | |
f67539c2 | 671 | auto args = joinify<std::string>(argsvec.begin(), argsvec.end(), " "); |
9f95a23c TL |
672 | r = _conf.injectargs(args, &ss); |
673 | } | |
674 | } | |
675 | else if (command == "log flush") { | |
7c673cae FG |
676 | _log->flush(); |
677 | } | |
678 | else if (command == "log dump") { | |
679 | _log->dump_recent(); | |
680 | } | |
681 | else if (command == "log reopen") { | |
682 | _log->reopen_log_file(); | |
683 | } | |
684 | else { | |
11fdf7f2 | 685 | ceph_abort_msg("registered under wrong command?"); |
7c673cae FG |
686 | } |
687 | f->close_section(); | |
688 | } | |
9f95a23c TL |
689 | lgeneric_dout(this, 1) << "do_command '" << command << "' '" << cmdmap |
690 | << "' result is " << out->length() << " bytes" << dendl; | |
691 | return r; | |
7c673cae FG |
692 | } |
693 | ||
c07f9fc5 FG |
694 | CephContext::CephContext(uint32_t module_type_, |
695 | enum code_environment_t code_env, | |
696 | int init_flags_) | |
1e59de90 TL |
697 | : CephContext(module_type_, create_options{code_env, init_flags_, nullptr}) |
698 | {} | |
699 | ||
700 | CephContext::CephContext(uint32_t module_type_, | |
701 | const create_options& options) | |
7c673cae | 702 | : nref(1), |
1e59de90 | 703 | _conf{options.code_env == CODE_ENVIRONMENT_DAEMON}, |
7c673cae FG |
704 | _log(NULL), |
705 | _module_type(module_type_), | |
1e59de90 | 706 | _init_flags(options.init_flags), |
7c673cae FG |
707 | _set_uid(0), |
708 | _set_gid(0), | |
709 | _set_uid_string(), | |
710 | _set_gid_string(), | |
11fdf7f2 | 711 | _crypto_inited(0), |
7c673cae FG |
712 | _service_thread(NULL), |
713 | _log_obs(NULL), | |
714 | _admin_socket(NULL), | |
715 | _perf_counters_collection(NULL), | |
716 | _perf_counters_conf_obs(NULL), | |
717 | _heartbeat_map(NULL), | |
718 | _crypto_none(NULL), | |
719 | _crypto_aes(NULL), | |
720 | _plugin_registry(NULL), | |
20effc67 | 721 | #ifdef CEPH_DEBUG_MUTEX |
7c673cae | 722 | _lockdep_obs(NULL), |
20effc67 | 723 | #endif |
11fdf7f2 | 724 | crush_location(this) |
7c673cae | 725 | { |
1e59de90 TL |
726 | if (options.create_log) { |
727 | _log = options.create_log(&_conf->subsys); | |
728 | } else { | |
729 | _log = new ceph::logging::Log(&_conf->subsys); | |
730 | } | |
7c673cae FG |
731 | |
732 | _log_obs = new LogObs(_log); | |
11fdf7f2 | 733 | _conf.add_observer(_log_obs); |
7c673cae FG |
734 | |
735 | _cct_obs = new CephContextObs(this); | |
11fdf7f2 | 736 | _conf.add_observer(_cct_obs); |
20effc67 | 737 | #ifdef CEPH_DEBUG_MUTEX |
7c673cae | 738 | _lockdep_obs = new LockdepObs(this); |
11fdf7f2 | 739 | _conf.add_observer(_lockdep_obs); |
20effc67 | 740 | #endif |
7c673cae FG |
741 | _perf_counters_collection = new PerfCountersCollection(this); |
742 | ||
743 | _admin_socket = new AdminSocket(this); | |
744 | _heartbeat_map = new HeartbeatMap(this); | |
745 | ||
746 | _plugin_registry = new PluginRegistry(this); | |
747 | ||
748 | _admin_hook = new CephContextHook(this); | |
9f95a23c TL |
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, ""); | |
1e59de90 | 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"); |
9f95a23c TL |
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, ""); | |
1e59de90 TL |
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"); | |
9f95a23c TL |
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( | |
7c673cae FG |
769 | "config diff", _admin_hook, |
770 | "dump diff of current config and default config"); | |
9f95a23c | 771 | _admin_socket->register_command( |
31f18b77 FG |
772 | "config diff get name=var,type=CephString", _admin_hook, |
773 | "dump diff get <field>: dump diff of current and default config setting <field>"); | |
9f95a23c TL |
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"); | |
7c673cae FG |
778 | |
779 | _crypto_none = CryptoHandler::create(CEPH_CRYPTO_NONE); | |
780 | _crypto_aes = CryptoHandler::create(CEPH_CRYPTO_AES); | |
11fdf7f2 | 781 | _crypto_random.reset(new CryptoRandom()); |
7c673cae | 782 | |
11fdf7f2 | 783 | lookup_or_create_singleton_object<MempoolObs>("mempool_obs", false, this); |
7c673cae FG |
784 | } |
785 | ||
786 | CephContext::~CephContext() | |
787 | { | |
11fdf7f2 | 788 | associated_objs.clear(); |
7c673cae FG |
789 | join_service_thread(); |
790 | ||
7c673cae FG |
791 | if (_cct_perf) { |
792 | _perf_counters_collection->remove(_cct_perf); | |
793 | delete _cct_perf; | |
794 | _cct_perf = NULL; | |
795 | } | |
796 | ||
797 | delete _plugin_registry; | |
798 | ||
11fdf7f2 | 799 | _admin_socket->unregister_commands(_admin_hook); |
7c673cae FG |
800 | delete _admin_hook; |
801 | delete _admin_socket; | |
802 | ||
803 | delete _heartbeat_map; | |
804 | ||
805 | delete _perf_counters_collection; | |
806 | _perf_counters_collection = NULL; | |
807 | ||
808 | delete _perf_counters_conf_obs; | |
809 | _perf_counters_conf_obs = NULL; | |
810 | ||
11fdf7f2 | 811 | _conf.remove_observer(_log_obs); |
7c673cae FG |
812 | delete _log_obs; |
813 | _log_obs = NULL; | |
814 | ||
11fdf7f2 | 815 | _conf.remove_observer(_cct_obs); |
7c673cae FG |
816 | delete _cct_obs; |
817 | _cct_obs = NULL; | |
20effc67 | 818 | #ifdef CEPH_DEBUG_MUTEX |
11fdf7f2 | 819 | _conf.remove_observer(_lockdep_obs); |
7c673cae FG |
820 | delete _lockdep_obs; |
821 | _lockdep_obs = NULL; | |
20effc67 | 822 | #endif |
7c673cae FG |
823 | _log->stop(); |
824 | delete _log; | |
825 | _log = NULL; | |
826 | ||
7c673cae FG |
827 | delete _crypto_none; |
828 | delete _crypto_aes; | |
11fdf7f2 TL |
829 | if (_crypto_inited > 0) { |
830 | ceph_assert(_crypto_inited == 1); // or else someone explicitly did | |
831 | // init but not shutdown | |
832 | shutdown_crypto(); | |
833 | } | |
7c673cae FG |
834 | } |
835 | ||
836 | void CephContext::put() { | |
31f18b77 | 837 | if (--nref == 0) { |
7c673cae FG |
838 | ANNOTATE_HAPPENS_AFTER(&nref); |
839 | ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&nref); | |
f67539c2 TL |
840 | if (g_ceph_context == this) |
841 | g_ceph_context = nullptr; | |
7c673cae FG |
842 | delete this; |
843 | } else { | |
844 | ANNOTATE_HAPPENS_BEFORE(&nref); | |
845 | } | |
846 | } | |
847 | ||
848 | void CephContext::init_crypto() | |
849 | { | |
11fdf7f2 | 850 | if (_crypto_inited++ == 0) { |
9f95a23c | 851 | TOPNSPC::crypto::init(); |
11fdf7f2 TL |
852 | } |
853 | } | |
854 | ||
855 | void CephContext::shutdown_crypto() | |
856 | { | |
857 | if (--_crypto_inited == 0) { | |
9f95a23c | 858 | TOPNSPC::crypto::shutdown(g_code_env == CODE_ENVIRONMENT_LIBRARY); |
7c673cae FG |
859 | } |
860 | } | |
861 | ||
862 | void CephContext::start_service_thread() | |
863 | { | |
11fdf7f2 TL |
864 | { |
865 | std::lock_guard lg(_service_thread_lock); | |
866 | if (_service_thread) { | |
867 | return; | |
868 | } | |
869 | _service_thread = new CephContextServiceThread(this); | |
870 | _service_thread->create("service"); | |
7c673cae | 871 | } |
11fdf7f2 TL |
872 | |
873 | if (!(get_init_flags() & CINIT_FLAG_NO_CCT_PERF_COUNTERS)) | |
874 | _enable_perf_counter(); | |
7c673cae FG |
875 | |
876 | // make logs flush on_exit() | |
877 | if (_conf->log_flush_on_exit) | |
878 | _log->set_flush_on_exit(); | |
879 | ||
880 | // Trigger callbacks on any config observers that were waiting for | |
881 | // it to become safe to start threads. | |
11fdf7f2 TL |
882 | _conf.set_safe_to_start_threads(); |
883 | _conf.call_all_observers(); | |
7c673cae FG |
884 | |
885 | // start admin socket | |
886 | if (_conf->admin_socket.length()) | |
887 | _admin_socket->init(_conf->admin_socket); | |
888 | } | |
889 | ||
890 | void CephContext::reopen_logs() | |
891 | { | |
11fdf7f2 | 892 | std::lock_guard lg(_service_thread_lock); |
7c673cae FG |
893 | if (_service_thread) |
894 | _service_thread->reopen_logs(); | |
7c673cae FG |
895 | } |
896 | ||
897 | void CephContext::join_service_thread() | |
898 | { | |
11fdf7f2 TL |
899 | std::unique_lock<ceph::spinlock> lg(_service_thread_lock); |
900 | ||
7c673cae FG |
901 | CephContextServiceThread *thread = _service_thread; |
902 | if (!thread) { | |
7c673cae FG |
903 | return; |
904 | } | |
905 | _service_thread = NULL; | |
11fdf7f2 TL |
906 | |
907 | lg.unlock(); | |
7c673cae FG |
908 | |
909 | thread->exit_thread(); | |
910 | thread->join(); | |
911 | delete thread; | |
11fdf7f2 TL |
912 | |
913 | if (!(get_init_flags() & CINIT_FLAG_NO_CCT_PERF_COUNTERS)) | |
914 | _disable_perf_counter(); | |
7c673cae FG |
915 | } |
916 | ||
917 | uint32_t CephContext::get_module_type() const | |
918 | { | |
919 | return _module_type; | |
920 | } | |
921 | ||
922 | void CephContext::set_init_flags(int flags) | |
923 | { | |
924 | _init_flags = flags; | |
925 | } | |
926 | ||
927 | int CephContext::get_init_flags() const | |
928 | { | |
929 | return _init_flags; | |
930 | } | |
931 | ||
932 | PerfCountersCollection *CephContext::get_perfcounters_collection() | |
933 | { | |
934 | return _perf_counters_collection; | |
935 | } | |
936 | ||
11fdf7f2 | 937 | void CephContext::_enable_perf_counter() |
7c673cae | 938 | { |
11fdf7f2 | 939 | assert(!_cct_perf); |
7c673cae FG |
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"); | |
11fdf7f2 | 943 | _cct_perf = plb.create_perf_counters(); |
7c673cae | 944 | _perf_counters_collection->add(_cct_perf); |
11fdf7f2 TL |
945 | |
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) { | |
f67539c2 TL |
951 | std::string n = mempool::get_pool_name(mempool::pool_index_t(i)); |
952 | _mempool_perf_names.push_back(n + "_bytes"s); | |
11fdf7f2 | 953 | _mempool_perf_descriptions.push_back( |
f67539c2 TL |
954 | "mempool "s + n + " total bytes"); |
955 | _mempool_perf_names.push_back(n + "_items"s); | |
11fdf7f2 | 956 | _mempool_perf_descriptions.push_back( |
f67539c2 | 957 | "mempool "s + n + " total items"s); |
11fdf7f2 TL |
958 | } |
959 | ||
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()); | |
968 | } | |
969 | _mempool_perf = plb2.create_perf_counters(); | |
970 | _perf_counters_collection->add(_mempool_perf); | |
7c673cae FG |
971 | } |
972 | ||
11fdf7f2 | 973 | void CephContext::_disable_perf_counter() |
7c673cae | 974 | { |
11fdf7f2 TL |
975 | if (!_cct_perf) { |
976 | return; | |
977 | } | |
7c673cae | 978 | _perf_counters_collection->remove(_cct_perf); |
7c673cae | 979 | delete _cct_perf; |
11fdf7f2 TL |
980 | _cct_perf = nullptr; |
981 | ||
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(); | |
7c673cae FG |
987 | } |
988 | ||
11fdf7f2 | 989 | void CephContext::_refresh_perf_values() |
7c673cae | 990 | { |
7c673cae FG |
991 | if (_cct_perf) { |
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()); | |
994 | } | |
11fdf7f2 TL |
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()); | |
1000 | } | |
7c673cae FG |
1001 | } |
1002 | ||
1003 | AdminSocket *CephContext::get_admin_socket() | |
1004 | { | |
1005 | return _admin_socket; | |
1006 | } | |
1007 | ||
1008 | CryptoHandler *CephContext::get_crypto_handler(int type) | |
1009 | { | |
1010 | switch (type) { | |
1011 | case CEPH_CRYPTO_NONE: | |
1012 | return _crypto_none; | |
1013 | case CEPH_CRYPTO_AES: | |
1014 | return _crypto_aes; | |
1015 | default: | |
1016 | return NULL; | |
1017 | } | |
1018 | } | |
11fdf7f2 TL |
1019 | |
1020 | void CephContext::notify_pre_fork() | |
1021 | { | |
1022 | { | |
1023 | std::lock_guard lg(_fork_watchers_lock); | |
1024 | for (auto &&t : _fork_watchers) { | |
1025 | t->handle_pre_fork(); | |
1026 | } | |
1027 | } | |
1028 | { | |
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); | |
1035 | } else { | |
1036 | ++i; | |
1037 | } | |
1038 | } | |
1039 | associated_objs_drop_on_fork.clear(); | |
1040 | } | |
1041 | } | |
1042 | ||
1043 | void CephContext::notify_post_fork() | |
1044 | { | |
1045 | ceph::spin_unlock(&_fork_watchers_lock); | |
1046 | for (auto &&t : _fork_watchers) | |
1047 | t->handle_post_fork(); | |
1048 | } | |
f91f0fd5 TL |
1049 | |
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); | |
1054 | } | |
1055 | ||
1056 | set_mon_addrs(mon_addrs); | |
1057 | } | |
9f95a23c | 1058 | } |
11fdf7f2 | 1059 | #endif // WITH_SEASTAR |