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