]>
git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/ConfigWatcher.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/ConfigWatcher.h"
5 #include "common/config_obs.h"
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/ImageState.h"
10 #include "librbd/api/Config.h"
14 #include <boost/algorithm/string/predicate.hpp>
16 #define dout_subsys ceph_subsys_rbd
18 #define dout_prefix *_dout << "librbd::ConfigWatcher: " \
24 struct ConfigWatcher
<I
>::Observer
: public md_config_obs_t
{
25 ConfigWatcher
<I
>* m_config_watcher
;
27 std::deque
<std::string
> m_config_key_strs
;
28 mutable std::vector
<const char*> m_config_keys
;
30 Observer(CephContext
* cct
, ConfigWatcher
<I
>* config_watcher
)
31 : m_config_watcher(config_watcher
) {
32 const std::string
rbd_key_prefix("rbd_");
33 auto& schema
= cct
->_conf
.get_schema();
34 for (auto& pair
: schema
) {
35 // watch all "rbd_" keys for simplicity
36 if (!boost::starts_with(pair
.first
, rbd_key_prefix
)) {
40 m_config_key_strs
.emplace_back(pair
.first
);
43 m_config_keys
.reserve(m_config_key_strs
.size());
44 for (auto& key
: m_config_key_strs
) {
45 m_config_keys
.emplace_back(key
.c_str());
47 m_config_keys
.emplace_back(nullptr);
50 const char** get_tracked_conf_keys() const override
{
51 ceph_assert(!m_config_keys
.empty());
52 return &m_config_keys
[0];
55 void handle_conf_change(const ConfigProxy
& conf
,
56 const std::set
<std::string
> &changed
) override
{
57 m_config_watcher
->handle_global_config_change(changed
);
62 ConfigWatcher
<I
>::ConfigWatcher(I
& image_ctx
)
63 : m_image_ctx(image_ctx
) {
67 ConfigWatcher
<I
>::~ConfigWatcher() {
68 ceph_assert(m_observer
== nullptr);
72 void ConfigWatcher
<I
>::init() {
73 auto cct
= m_image_ctx
.cct
;
74 ldout(cct
, 10) << dendl
;
76 m_observer
= new Observer(cct
, this);
77 cct
->_conf
.add_observer(m_observer
);
81 void ConfigWatcher
<I
>::shut_down() {
82 auto cct
= m_image_ctx
.cct
;
83 ldout(cct
, 10) << dendl
;
85 ceph_assert(m_observer
!= nullptr);
86 cct
->_conf
.remove_observer(m_observer
);
93 void ConfigWatcher
<I
>::handle_global_config_change(
94 std::set
<std::string
> changed_keys
) {
97 // ignore any global changes that are being overridden
98 std::shared_lock image_locker
{m_image_ctx
.image_lock
};
99 for (auto& key
: m_image_ctx
.config_overrides
) {
100 changed_keys
.erase(key
);
103 if (changed_keys
.empty()) {
107 auto cct
= m_image_ctx
.cct
;
108 ldout(cct
, 10) << "changed_keys=" << changed_keys
<< dendl
;
110 // refresh the image to pick up any global config overrides
111 m_image_ctx
.state
->handle_update_notification();
114 } // namespace librbd
116 template class librbd::ConfigWatcher
<librbd::ImageCtx
>;