]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/ceph_context.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / common / ceph_context.h
CommitLineData
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 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#ifndef CEPH_CEPHCONTEXT_H
16#define CEPH_CEPHCONTEXT_H
17
31f18b77 18#include <atomic>
11fdf7f2
TL
19#include <map>
20#include <memory>
21#include <mutex>
7c673cae 22#include <set>
11fdf7f2
TL
23#include <string>
24#include <string_view>
25#include <typeinfo>
26#include <typeindex>
27
f67539c2
TL
28#include <boost/intrusive_ptr.hpp>
29
11fdf7f2 30#include "include/any.h"
f67539c2
TL
31#include "include/common_fwd.h"
32#include "include/compat.h"
7c673cae 33
7c673cae 34#include "common/cmdparse.h"
c07f9fc5 35#include "common/code_environment.h"
f91f0fd5 36#include "msg/msg_types.h"
9f95a23c 37#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
11fdf7f2
TL
38#include "crimson/common/config_proxy.h"
39#include "crimson/common/perf_counters_collection.h"
40#else
41#include "common/config_proxy.h"
42#include "include/spinlock.h"
43#include "common/perf_counters_collection.h"
44#endif
45
46
7c673cae 47#include "crush/CrushLocation.h"
7c673cae
FG
48
49class AdminSocket;
7c673cae 50class CryptoHandler;
11fdf7f2 51class CryptoRandom;
f91f0fd5 52class MonMap;
7c673cae 53
9f95a23c
TL
54namespace ceph::common {
55 class CephContextServiceThread;
56 class CephContextObs;
57 class CephContextHook;
58}
59
7c673cae
FG
60namespace ceph {
61 class PluginRegistry;
62 class HeartbeatMap;
63 namespace logging {
64 class Log;
65 }
66}
67
9f95a23c
TL
68#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
69namespace crimson::common {
11fdf7f2
TL
70class CephContext {
71public:
72 CephContext();
73 CephContext(uint32_t,
74 code_environment_t=CODE_ENVIRONMENT_UTILITY,
75 int = 0)
76 : CephContext{}
77 {}
9f95a23c 78 CephContext(CephContext&&) = default;
11fdf7f2
TL
79 ~CephContext();
80
81 uint32_t get_module_type() const;
82 bool check_experimental_feature_enabled(const std::string& feature) {
83 // everything crimson is experimental...
84 return true;
85 }
20effc67
TL
86 ceph::PluginRegistry* get_plugin_registry() {
87 return _plugin_registry;
88 }
11fdf7f2
TL
89 CryptoRandom* random() const;
90 PerfCountersCollectionImpl* get_perfcounters_collection();
9f95a23c
TL
91 crimson::common::ConfigProxy& _conf;
92 crimson::common::PerfCountersCollection& _perf_counters_collection;
11fdf7f2
TL
93 CephContext* get();
94 void put();
95private:
96 std::unique_ptr<CryptoRandom> _crypto_random;
97 unsigned nref;
20effc67 98 ceph::PluginRegistry* _plugin_registry;
11fdf7f2 99};
9f95a23c 100}
11fdf7f2 101#else
9f95a23c
TL
102#ifdef __cplusplus
103namespace ceph::common {
104#endif
7c673cae
FG
105/* A CephContext represents the context held by a single library user.
106 * There can be multiple CephContexts in the same process.
107 *
108 * For daemons and utility programs, there will be only one CephContext. The
109 * CephContext contains the configuration, the dout object, and anything else
110 * that you might want to pass to libcommon with every function call.
111 */
112class CephContext {
113public:
c07f9fc5
FG
114 CephContext(uint32_t module_type_,
115 enum code_environment_t code_env=CODE_ENVIRONMENT_UTILITY,
116 int init_flags_ = 0);
7c673cae 117
11fdf7f2
TL
118 CephContext(const CephContext&) = delete;
119 CephContext& operator =(const CephContext&) = delete;
120 CephContext(CephContext&&) = delete;
121 CephContext& operator =(CephContext&&) = delete;
122
123 bool _finished = false;
9f95a23c 124 ~CephContext();
11fdf7f2 125
7c673cae
FG
126 // ref count!
127private:
31f18b77 128 std::atomic<unsigned> nref;
7c673cae
FG
129public:
130 CephContext *get() {
31f18b77 131 ++nref;
7c673cae
FG
132 return this;
133 }
134 void put();
135
11fdf7f2 136 ConfigProxy _conf;
7c673cae
FG
137 ceph::logging::Log *_log;
138
139 /* init ceph::crypto */
140 void init_crypto();
141
11fdf7f2
TL
142 /// shutdown crypto (should match init_crypto calls)
143 void shutdown_crypto();
144
7c673cae
FG
145 /* Start the Ceph Context's service thread */
146 void start_service_thread();
147
148 /* Reopen the log files */
149 void reopen_logs();
150
151 /* Get the module type (client, mon, osd, mds, etc.) */
152 uint32_t get_module_type() const;
153
11fdf7f2
TL
154 // this is here only for testing purposes!
155 void _set_module_type(uint32_t t) {
156 _module_type = t;
157 }
158
7c673cae
FG
159 void set_init_flags(int flags);
160 int get_init_flags() const;
161
162 /* Get the PerfCountersCollection of this CephContext */
163 PerfCountersCollection *get_perfcounters_collection();
164
165 ceph::HeartbeatMap *get_heartbeat_map() {
166 return _heartbeat_map;
167 }
168
7c673cae
FG
169 /**
170 * Get the admin socket associated with this CephContext.
171 *
172 * Currently there is always an admin socket object,
173 * so this will never return NULL.
174 *
175 * @return the admin socket
176 */
177 AdminSocket *get_admin_socket();
178
179 /**
180 * process an admin socket command
181 */
9f95a23c
TL
182 int do_command(std::string_view command, const cmdmap_t& cmdmap,
183 Formatter *f,
184 std::ostream& errss,
185 ceph::bufferlist *out);
186 int _do_command(std::string_view command, const cmdmap_t& cmdmap,
187 Formatter *f,
188 std::ostream& errss,
189 ceph::bufferlist *out);
11fdf7f2
TL
190
191 static constexpr std::size_t largest_singleton = 8 * 72;
192
193 template<typename T, typename... Args>
194 T& lookup_or_create_singleton_object(std::string_view name,
195 bool drop_on_fork,
196 Args&&... args) {
197 static_assert(sizeof(T) <= largest_singleton,
198 "Please increase largest singleton.");
199 std::lock_guard lg(associated_objs_lock);
200 std::type_index type = typeid(T);
201
202 auto i = associated_objs.find(std::make_pair(name, type));
203 if (i == associated_objs.cend()) {
204 if (drop_on_fork) {
205 associated_objs_drop_on_fork.insert(std::string(name));
206 }
207 i = associated_objs.emplace_hint(
208 i,
209 std::piecewise_construct,
210 std::forward_as_tuple(name, type),
211 std::forward_as_tuple(std::in_place_type<T>,
212 std::forward<Args>(args)...));
7c673cae 213 }
11fdf7f2 214 return ceph::any_cast<T&>(i->second);
7c673cae 215 }
11fdf7f2 216
7c673cae
FG
217 /**
218 * get a crypto handler
219 */
220 CryptoHandler *get_crypto_handler(int type);
221
11fdf7f2
TL
222 CryptoRandom* random() const { return _crypto_random.get(); }
223
7c673cae
FG
224 /// check if experimental feature is enable, and emit appropriate warnings
225 bool check_experimental_feature_enabled(const std::string& feature);
226 bool check_experimental_feature_enabled(const std::string& feature,
227 std::ostream *message);
228
9f95a23c 229 ceph::PluginRegistry *get_plugin_registry() {
7c673cae
FG
230 return _plugin_registry;
231 }
232
233 void set_uid_gid(uid_t u, gid_t g) {
234 _set_uid = u;
235 _set_gid = g;
236 }
237 uid_t get_set_uid() const {
238 return _set_uid;
239 }
240 gid_t get_set_gid() const {
241 return _set_gid;
242 }
243
11fdf7f2 244 void set_uid_gid_strings(const std::string &u, const std::string &g) {
7c673cae
FG
245 _set_uid_string = u;
246 _set_gid_string = g;
247 }
248 std::string get_set_uid_string() const {
249 return _set_uid_string;
250 }
251 std::string get_set_gid_string() const {
252 return _set_gid_string;
253 }
254
255 class ForkWatcher {
256 public:
257 virtual ~ForkWatcher() {}
258 virtual void handle_pre_fork() = 0;
259 virtual void handle_post_fork() = 0;
260 };
261
262 void register_fork_watcher(ForkWatcher *w) {
11fdf7f2 263 std::lock_guard lg(_fork_watchers_lock);
7c673cae 264 _fork_watchers.push_back(w);
7c673cae
FG
265 }
266
11fdf7f2
TL
267 void notify_pre_fork();
268 void notify_post_fork();
7c673cae 269
f91f0fd5
TL
270 /**
271 * update CephContext with a copy of the passed in MonMap mon addrs
272 *
273 * @param mm MonMap to extract and update mon addrs
274 */
275 void set_mon_addrs(const MonMap& mm);
276 void set_mon_addrs(const std::vector<entity_addrvec_t>& in) {
277 auto ptr = std::make_shared<std::vector<entity_addrvec_t>>(in);
278 atomic_store_explicit(&_mon_addrs, std::move(ptr), std::memory_order_relaxed);
279 }
280 std::shared_ptr<std::vector<entity_addrvec_t>> get_mon_addrs() const {
281 auto ptr = atomic_load_explicit(&_mon_addrs, std::memory_order_relaxed);
282 return ptr;
283 }
284
7c673cae 285private:
7c673cae 286
7c673cae
FG
287
288 /* Stop and join the Ceph Context's service thread */
289 void join_service_thread();
290
291 uint32_t _module_type;
292
293 int _init_flags;
294
295 uid_t _set_uid; ///< uid to drop privs to
296 gid_t _set_gid; ///< gid to drop privs to
297 std::string _set_uid_string;
298 std::string _set_gid_string;
299
11fdf7f2 300 int _crypto_inited;
7c673cae 301
f91f0fd5
TL
302 std::shared_ptr<std::vector<entity_addrvec_t>> _mon_addrs;
303
7c673cae
FG
304 /* libcommon service thread.
305 * SIGHUP wakes this thread, which then reopens logfiles */
306 friend class CephContextServiceThread;
307 CephContextServiceThread *_service_thread;
308
11fdf7f2
TL
309 using md_config_obs_t = ceph::md_config_obs_impl<ConfigProxy>;
310
7c673cae
FG
311 md_config_obs_t *_log_obs;
312
313 /* The admin socket associated with this context */
314 AdminSocket *_admin_socket;
315
316 /* lock which protects service thread creation, destruction, etc. */
11fdf7f2 317 ceph::spinlock _service_thread_lock;
7c673cae
FG
318
319 /* The collection of profiling loggers associated with this context */
320 PerfCountersCollection *_perf_counters_collection;
321
322 md_config_obs_t *_perf_counters_conf_obs;
323
324 CephContextHook *_admin_hook;
325
326 ceph::HeartbeatMap *_heartbeat_map;
327
11fdf7f2
TL
328 ceph::spinlock associated_objs_lock;
329
330 struct associated_objs_cmp {
331 using is_transparent = std::true_type;
332 template<typename T, typename U>
333 bool operator ()(const std::pair<T, std::type_index>& l,
334 const std::pair<U, std::type_index>& r) const noexcept {
335 return ((l.first < r.first) ||
336 (l.first == r.first && l.second < r.second));
337 }
338 };
7c673cae 339
11fdf7f2
TL
340 std::map<std::pair<std::string, std::type_index>,
341 ceph::immobile_any<largest_singleton>,
342 associated_objs_cmp> associated_objs;
343 std::set<std::string> associated_objs_drop_on_fork;
344
345 ceph::spinlock _fork_watchers_lock;
7c673cae
FG
346 std::vector<ForkWatcher*> _fork_watchers;
347
348 // crypto
349 CryptoHandler *_crypto_none;
350 CryptoHandler *_crypto_aes;
11fdf7f2 351 std::unique_ptr<CryptoRandom> _crypto_random;
7c673cae
FG
352
353 // experimental
354 CephContextObs *_cct_obs;
11fdf7f2 355 ceph::spinlock _feature_lock;
7c673cae
FG
356 std::set<std::string> _experimental_features;
357
9f95a23c 358 ceph::PluginRegistry* _plugin_registry;
20effc67 359#ifdef CEPH_DEBUG_MUTEX
7c673cae 360 md_config_obs_t *_lockdep_obs;
20effc67 361#endif
7c673cae 362public:
9f95a23c 363 TOPNSPC::crush::CrushLocation crush_location;
7c673cae
FG
364private:
365
366 enum {
367 l_cct_first,
368 l_cct_total_workers,
369 l_cct_unhealthy_workers,
370 l_cct_last
371 };
11fdf7f2
TL
372 enum {
373 l_mempool_first = 873222,
374 l_mempool_bytes,
375 l_mempool_items,
376 l_mempool_last
377 };
378 PerfCounters *_cct_perf = nullptr;
379 PerfCounters* _mempool_perf = nullptr;
380 std::vector<std::string> _mempool_perf_names, _mempool_perf_descriptions;
381
382 /**
383 * Enable the performance counters.
384 */
385 void _enable_perf_counter();
386
387 /**
388 * Disable the performance counter.
389 */
390 void _disable_perf_counter();
391
392 /**
393 * Refresh perf counter values.
394 */
395 void _refresh_perf_values();
7c673cae
FG
396
397 friend class CephContextObs;
398};
9f95a23c
TL
399#ifdef __cplusplus
400}
401#endif
11fdf7f2 402#endif // WITH_SEASTAR
7c673cae 403
f67539c2
TL
404#if !(defined(WITH_SEASTAR) && !defined(WITH_ALIEN)) && defined(__cplusplus)
405namespace ceph::common {
406inline void intrusive_ptr_add_ref(CephContext* cct)
407{
408 cct->get();
409}
410
411inline void intrusive_ptr_release(CephContext* cct)
412{
413 cct->put();
414}
415}
416#endif // !(defined(WITH_SEASTAR) && !defined(WITH_ALIEN)) && defined(__cplusplus)
7c673cae 417#endif