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