Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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 <set>
20 #include <boost/noncopyable.hpp>
21
22 #include "common/cmdparse.h"
23 #include "common/code_environment.h"
24 #include "crush/CrushLocation.h"
25 #include "include/Spinlock.h"
26
27 class AdminSocket;
28 class CephContextServiceThread;
29 class PerfCountersCollection;
30 class PerfCounters;
31 class md_config_obs_t;
32 struct md_config_t;
33 class CephContextHook;
34 class CephContextObs;
35 class CryptoHandler;
36
37 namespace ceph {
38   class PluginRegistry;
39   class HeartbeatMap;
40   namespace logging {
41     class Log;
42   }
43 }
44
45 /* A CephContext represents the context held by a single library user.
46  * There can be multiple CephContexts in the same process.
47  *
48  * For daemons and utility programs, there will be only one CephContext.  The
49  * CephContext contains the configuration, the dout object, and anything else
50  * that you might want to pass to libcommon with every function call.
51  */
52 class CephContext {
53 public:
54   CephContext(uint32_t module_type_,
55               enum code_environment_t code_env=CODE_ENVIRONMENT_UTILITY,
56               int init_flags_ = 0);
57
58   // ref count!
59 private:
60   ~CephContext();
61   std::atomic<unsigned> nref;
62 public:
63   CephContext *get() {
64     ++nref;
65     return this;
66   }
67   void put();
68
69   md_config_t *_conf;
70   ceph::logging::Log *_log;
71
72   /* init ceph::crypto */
73   void init_crypto();
74
75   /* Start the Ceph Context's service thread */
76   void start_service_thread();
77
78   /* Reopen the log files */
79   void reopen_logs();
80
81   /* Get the module type (client, mon, osd, mds, etc.) */
82   uint32_t get_module_type() const;
83
84   void set_init_flags(int flags);
85   int get_init_flags() const;
86
87   /* Get the PerfCountersCollection of this CephContext */
88   PerfCountersCollection *get_perfcounters_collection();
89
90   ceph::HeartbeatMap *get_heartbeat_map() {
91     return _heartbeat_map;
92   }
93
94   /**
95    * Enable the performance counter, currently we only have counter for the
96    * number of total/unhealthy workers.
97    */
98   void enable_perf_counter();
99
100   /**
101    * Disable the performance counter.
102    */
103   void disable_perf_counter();
104
105   /**
106    * Refresh perf counter values.
107    */
108   void refresh_perf_values();
109
110   /**
111    * Get the admin socket associated with this CephContext.
112    *
113    * Currently there is always an admin socket object,
114    * so this will never return NULL.
115    *
116    * @return the admin socket
117    */
118   AdminSocket *get_admin_socket();
119
120   /**
121    * process an admin socket command
122    */
123   void do_command(std::string command, cmdmap_t& cmdmap, std::string format,
124                   ceph::bufferlist *out);
125
126   template<typename T>
127   void lookup_or_create_singleton_object(T*& p, const std::string &name) {
128     ceph_spin_lock(&_associated_objs_lock);
129     if (!_associated_objs.count(name)) {
130       p = new T(this);
131       _associated_objs[name] = new TypedSingletonWrapper<T>(p);
132     } else {
133       TypedSingletonWrapper<T> *wrapper =
134         dynamic_cast<TypedSingletonWrapper<T> *>(_associated_objs[name]);
135       assert(wrapper != NULL);
136       p = wrapper->singleton;
137     }
138     ceph_spin_unlock(&_associated_objs_lock);
139   }
140   /**
141    * get a crypto handler
142    */
143   CryptoHandler *get_crypto_handler(int type);
144
145   /// check if experimental feature is enable, and emit appropriate warnings
146   bool check_experimental_feature_enabled(const std::string& feature);
147   bool check_experimental_feature_enabled(const std::string& feature,
148                                           std::ostream *message);
149
150   PluginRegistry *get_plugin_registry() {
151     return _plugin_registry;
152   }
153
154   void set_uid_gid(uid_t u, gid_t g) {
155     _set_uid = u;
156     _set_gid = g;
157   }
158   uid_t get_set_uid() const {
159     return _set_uid;
160   }
161   gid_t get_set_gid() const {
162     return _set_gid;
163   }
164
165   void set_uid_gid_strings(std::string u, std::string g) {
166     _set_uid_string = u;
167     _set_gid_string = g;
168   }
169   std::string get_set_uid_string() const {
170     return _set_uid_string;
171   }
172   std::string get_set_gid_string() const {
173     return _set_gid_string;
174   }
175
176   class ForkWatcher {
177    public:
178     virtual ~ForkWatcher() {}
179     virtual void handle_pre_fork() = 0;
180     virtual void handle_post_fork() = 0;
181   };
182
183   void register_fork_watcher(ForkWatcher *w) {
184     ceph_spin_lock(&_fork_watchers_lock);
185     _fork_watchers.push_back(w);
186     ceph_spin_unlock(&_fork_watchers_lock);
187   }
188
189   void notify_pre_fork() {
190     ceph_spin_lock(&_fork_watchers_lock);
191     for (auto &&t : _fork_watchers)
192       t->handle_pre_fork();
193     ceph_spin_unlock(&_fork_watchers_lock);
194   }
195
196   void notify_post_fork() {
197     ceph_spin_lock(&_fork_watchers_lock);
198     for (auto &&t : _fork_watchers)
199       t->handle_post_fork();
200     ceph_spin_unlock(&_fork_watchers_lock);
201   }
202
203 private:
204   struct SingletonWrapper : boost::noncopyable {
205     virtual ~SingletonWrapper() {}
206   };
207
208   template <typename T>
209   struct TypedSingletonWrapper : public SingletonWrapper {
210     TypedSingletonWrapper(T *p) : singleton(p) {
211     }
212     ~TypedSingletonWrapper() override {
213       delete singleton;
214     }
215
216     T *singleton;
217   };
218
219   CephContext(const CephContext &rhs);
220   CephContext &operator=(const CephContext &rhs);
221
222   /* Stop and join the Ceph Context's service thread */
223   void join_service_thread();
224
225   uint32_t _module_type;
226
227   int _init_flags;
228
229   uid_t _set_uid; ///< uid to drop privs to
230   gid_t _set_gid; ///< gid to drop privs to
231   std::string _set_uid_string;
232   std::string _set_gid_string;
233
234   bool _crypto_inited;
235
236   /* libcommon service thread.
237    * SIGHUP wakes this thread, which then reopens logfiles */
238   friend class CephContextServiceThread;
239   CephContextServiceThread *_service_thread;
240
241   md_config_obs_t *_log_obs;
242
243   /* The admin socket associated with this context */
244   AdminSocket *_admin_socket;
245
246   /* lock which protects service thread creation, destruction, etc. */
247   ceph_spinlock_t _service_thread_lock;
248
249   /* The collection of profiling loggers associated with this context */
250   PerfCountersCollection *_perf_counters_collection;
251
252   md_config_obs_t *_perf_counters_conf_obs;
253
254   CephContextHook *_admin_hook;
255
256   ceph::HeartbeatMap *_heartbeat_map;
257
258   ceph_spinlock_t _associated_objs_lock;
259   std::map<std::string, SingletonWrapper*> _associated_objs;
260
261   ceph_spinlock_t _fork_watchers_lock;
262   std::vector<ForkWatcher*> _fork_watchers;
263
264   // crypto
265   CryptoHandler *_crypto_none;
266   CryptoHandler *_crypto_aes;
267
268   // experimental
269   CephContextObs *_cct_obs;
270   ceph_spinlock_t _feature_lock;
271   std::set<std::string> _experimental_features;
272
273   PluginRegistry *_plugin_registry;
274
275   md_config_obs_t *_lockdep_obs;
276
277 public:
278   CrushLocation crush_location;
279 private:
280
281   enum {
282     l_cct_first,
283     l_cct_total_workers,
284     l_cct_unhealthy_workers,
285     l_cct_last
286   };
287   PerfCounters *_cct_perf;
288   ceph_spinlock_t _cct_perf_lock;
289
290   friend class CephContextObs;
291 };
292
293 #endif