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