1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
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.
15 #ifndef CEPH_CEPHCONTEXT_H
16 #define CEPH_CEPHCONTEXT_H
24 #include <string_view>
28 #include <boost/intrusive_ptr.hpp>
30 #include "include/any.h"
31 #include "include/common_fwd.h"
32 #include "include/compat.h"
34 #include "common/cmdparse.h"
35 #include "common/code_environment.h"
36 #include "msg/msg_types.h"
37 #if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
38 #include "crimson/common/config_proxy.h"
39 #include "crimson/common/perf_counters_collection.h"
41 #include "common/config_proxy.h"
42 #include "include/spinlock.h"
43 #include "common/perf_counters_collection.h"
47 #include "crush/CrushLocation.h"
54 namespace ceph::common
{
55 class CephContextServiceThread
;
57 class CephContextHook
;
69 #if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
70 namespace crimson::common
{
75 code_environment_t
=CODE_ENVIRONMENT_UTILITY
,
79 CephContext(CephContext
&&) = default;
82 uint32_t get_module_type() const;
83 bool check_experimental_feature_enabled(const std::string
& feature
) {
84 // everything crimson is experimental...
87 ceph::PluginRegistry
* get_plugin_registry() {
88 return _plugin_registry
;
90 CryptoRandom
* random() const;
91 PerfCountersCollectionImpl
* get_perfcounters_collection();
92 crimson::common::ConfigProxy
& _conf
;
93 crimson::common::PerfCountersCollection
& _perf_counters_collection
;
97 std::unique_ptr
<CryptoRandom
> _crypto_random
;
99 ceph::PluginRegistry
* _plugin_registry
;
104 namespace ceph::common
{
106 /* A CephContext represents the context held by a single library user.
107 * There can be multiple CephContexts in the same process.
109 * For daemons and utility programs, there will be only one CephContext. The
110 * CephContext contains the configuration, the dout object, and anything else
111 * that you might want to pass to libcommon with every function call.
115 CephContext(uint32_t module_type_
,
116 enum code_environment_t code_env
=CODE_ENVIRONMENT_UTILITY
,
117 int init_flags_
= 0);
118 struct create_options
{
119 enum code_environment_t code_env
=CODE_ENVIRONMENT_UTILITY
;
121 std::function
<ceph::logging::Log
* (const ceph::logging::SubsystemMap
*)> create_log
;
123 CephContext(uint32_t module_type_
,
124 const create_options
& options
);
125 CephContext(const CephContext
&) = delete;
126 CephContext
& operator =(const CephContext
&) = delete;
127 CephContext(CephContext
&&) = delete;
128 CephContext
& operator =(CephContext
&&) = delete;
130 bool _finished
= false;
135 std::atomic
<unsigned> nref
;
144 ceph::logging::Log
*_log
;
146 /* init ceph::crypto */
149 /// shutdown crypto (should match init_crypto calls)
150 void shutdown_crypto();
152 /* Start the Ceph Context's service thread */
153 void start_service_thread();
155 /* Reopen the log files */
158 /* Get the module type (client, mon, osd, mds, etc.) */
159 uint32_t get_module_type() const;
161 // this is here only for testing purposes!
162 void _set_module_type(uint32_t t
) {
166 void set_init_flags(int flags
);
167 int get_init_flags() const;
169 /* Get the PerfCountersCollection of this CephContext */
170 PerfCountersCollection
*get_perfcounters_collection();
172 ceph::HeartbeatMap
*get_heartbeat_map() {
173 return _heartbeat_map
;
177 * Get the admin socket associated with this CephContext.
179 * Currently there is always an admin socket object,
180 * so this will never return NULL.
182 * @return the admin socket
184 AdminSocket
*get_admin_socket();
187 * process an admin socket command
189 int do_command(std::string_view command
, const cmdmap_t
& cmdmap
,
192 ceph::bufferlist
*out
);
193 int _do_command(std::string_view command
, const cmdmap_t
& cmdmap
,
196 ceph::bufferlist
*out
);
198 static constexpr std::size_t largest_singleton
= 8 * 72;
200 template<typename T
, typename
... Args
>
201 T
& lookup_or_create_singleton_object(std::string_view name
,
204 static_assert(sizeof(T
) <= largest_singleton
,
205 "Please increase largest singleton.");
206 std::lock_guard
lg(associated_objs_lock
);
207 std::type_index type
= typeid(T
);
209 auto i
= associated_objs
.find(std::make_pair(name
, type
));
210 if (i
== associated_objs
.cend()) {
212 associated_objs_drop_on_fork
.insert(std::string(name
));
214 i
= associated_objs
.emplace_hint(
216 std::piecewise_construct
,
217 std::forward_as_tuple(name
, type
),
218 std::forward_as_tuple(std::in_place_type
<T
>,
219 std::forward
<Args
>(args
)...));
221 return ceph::any_cast
<T
&>(i
->second
);
225 * get a crypto handler
227 CryptoHandler
*get_crypto_handler(int type
);
229 CryptoRandom
* random() const { return _crypto_random
.get(); }
231 /// check if experimental feature is enable, and emit appropriate warnings
232 bool check_experimental_feature_enabled(const std::string
& feature
);
233 bool check_experimental_feature_enabled(const std::string
& feature
,
234 std::ostream
*message
);
236 ceph::PluginRegistry
*get_plugin_registry() {
237 return _plugin_registry
;
240 void set_uid_gid(uid_t u
, gid_t g
) {
244 uid_t
get_set_uid() const {
247 gid_t
get_set_gid() const {
251 void set_uid_gid_strings(const std::string
&u
, const std::string
&g
) {
255 std::string
get_set_uid_string() const {
256 return _set_uid_string
;
258 std::string
get_set_gid_string() const {
259 return _set_gid_string
;
264 virtual ~ForkWatcher() {}
265 virtual void handle_pre_fork() = 0;
266 virtual void handle_post_fork() = 0;
269 void register_fork_watcher(ForkWatcher
*w
) {
270 std::lock_guard
lg(_fork_watchers_lock
);
271 _fork_watchers
.push_back(w
);
274 void notify_pre_fork();
275 void notify_post_fork();
278 * update CephContext with a copy of the passed in MonMap mon addrs
280 * @param mm MonMap to extract and update mon addrs
282 void set_mon_addrs(const MonMap
& mm
);
283 void set_mon_addrs(const std::vector
<entity_addrvec_t
>& in
) {
284 auto ptr
= std::make_shared
<std::vector
<entity_addrvec_t
>>(in
);
285 atomic_store_explicit(&_mon_addrs
, std::move(ptr
), std::memory_order_relaxed
);
287 std::shared_ptr
<std::vector
<entity_addrvec_t
>> get_mon_addrs() const {
288 auto ptr
= atomic_load_explicit(&_mon_addrs
, std::memory_order_relaxed
);
295 /* Stop and join the Ceph Context's service thread */
296 void join_service_thread();
298 uint32_t _module_type
;
302 uid_t _set_uid
; ///< uid to drop privs to
303 gid_t _set_gid
; ///< gid to drop privs to
304 std::string _set_uid_string
;
305 std::string _set_gid_string
;
309 std::shared_ptr
<std::vector
<entity_addrvec_t
>> _mon_addrs
;
311 /* libcommon service thread.
312 * SIGHUP wakes this thread, which then reopens logfiles */
313 friend class CephContextServiceThread
;
314 CephContextServiceThread
*_service_thread
;
316 using md_config_obs_t
= ceph::md_config_obs_impl
<ConfigProxy
>;
318 md_config_obs_t
*_log_obs
;
320 /* The admin socket associated with this context */
321 AdminSocket
*_admin_socket
;
323 /* lock which protects service thread creation, destruction, etc. */
324 ceph::spinlock _service_thread_lock
;
326 /* The collection of profiling loggers associated with this context */
327 PerfCountersCollection
*_perf_counters_collection
;
329 md_config_obs_t
*_perf_counters_conf_obs
;
331 CephContextHook
*_admin_hook
;
333 ceph::HeartbeatMap
*_heartbeat_map
;
335 ceph::spinlock associated_objs_lock
;
337 struct associated_objs_cmp
{
338 using is_transparent
= std::true_type
;
339 template<typename T
, typename U
>
340 bool operator ()(const std::pair
<T
, std::type_index
>& l
,
341 const std::pair
<U
, std::type_index
>& r
) const noexcept
{
342 return ((l
.first
< r
.first
) ||
343 (l
.first
== r
.first
&& l
.second
< r
.second
));
347 std::map
<std::pair
<std::string
, std::type_index
>,
348 ceph::immobile_any
<largest_singleton
>,
349 associated_objs_cmp
> associated_objs
;
350 std::set
<std::string
> associated_objs_drop_on_fork
;
352 ceph::spinlock _fork_watchers_lock
;
353 std::vector
<ForkWatcher
*> _fork_watchers
;
356 CryptoHandler
*_crypto_none
;
357 CryptoHandler
*_crypto_aes
;
358 std::unique_ptr
<CryptoRandom
> _crypto_random
;
361 CephContextObs
*_cct_obs
;
362 ceph::spinlock _feature_lock
;
363 std::set
<std::string
> _experimental_features
;
365 ceph::PluginRegistry
* _plugin_registry
;
366 #ifdef CEPH_DEBUG_MUTEX
367 md_config_obs_t
*_lockdep_obs
;
370 TOPNSPC::crush::CrushLocation crush_location
;
376 l_cct_unhealthy_workers
,
380 l_mempool_first
= 873222,
385 PerfCounters
*_cct_perf
= nullptr;
386 PerfCounters
* _mempool_perf
= nullptr;
387 std::vector
<std::string
> _mempool_perf_names
, _mempool_perf_descriptions
;
390 * Enable the performance counters.
392 void _enable_perf_counter();
395 * Disable the performance counter.
397 void _disable_perf_counter();
400 * Refresh perf counter values.
402 void _refresh_perf_values();
404 friend class CephContextObs
;
409 #endif // WITH_SEASTAR
411 #if !(defined(WITH_SEASTAR) && !defined(WITH_ALIEN)) && defined(__cplusplus)
412 namespace ceph::common
{
413 inline void intrusive_ptr_add_ref(CephContext
* cct
)
418 inline void intrusive_ptr_release(CephContext
* cct
)
423 #endif // !(defined(WITH_SEASTAR) && !defined(WITH_ALIEN)) && defined(__cplusplus)