]>
git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/api/Config.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/api/Config.h"
5 #include "cls/rbd/cls_rbd_client.h"
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/Utils.h"
10 #include "librbd/api/PoolMetadata.h"
11 #include <boost/algorithm/string/predicate.hpp>
13 #define dout_subsys ceph_subsys_rbd
15 #define dout_prefix *_dout << "librbd::Config: " << __func__ << ": "
22 const uint32_t MAX_KEYS
= 64;
24 typedef std::map
<std::string
, std::pair
<std::string
, config_source_t
>> Parent
;
26 static std::set
<std::string
> EXCLUDE_OPTIONS
{
27 "rbd_auto_exclusive_lock_until_manual_request",
29 "rbd_default_map_options",
31 "rbd_discard_on_zeroed_write_same",
32 "rbd_op_thread_timeout",
37 "rbd_mirror_pool_replayers_refresh_interval"
39 static std::set
<std::string
> EXCLUDE_IMAGE_OPTIONS
{
40 "rbd_default_clone_format",
41 "rbd_default_data_pool",
42 "rbd_default_features",
45 "rbd_default_stripe_count",
46 "rbd_default_stripe_unit",
49 "rbd_journal_splay_width"
52 struct Options
: Parent
{
53 librados::IoCtx m_io_ctx
;
55 Options(librados::IoCtx
& io_ctx
, bool image_apply_only_options
) {
57 m_io_ctx
.set_namespace("");
59 CephContext
*cct
= reinterpret_cast<CephContext
*>(m_io_ctx
.cct());
61 const std::string
rbd_key_prefix("rbd_");
62 const std::string
rbd_mirror_key_prefix("rbd_mirror_");
63 auto& schema
= cct
->_conf
.get_schema();
64 for (auto& pair
: schema
) {
65 if (!boost::starts_with(pair
.first
, rbd_key_prefix
)) {
67 } else if (EXCLUDE_OPTIONS
.count(pair
.first
) != 0) {
69 } else if (image_apply_only_options
&&
70 EXCLUDE_IMAGE_OPTIONS
.count(pair
.first
) != 0) {
72 } else if (image_apply_only_options
&&
73 boost::starts_with(pair
.first
, rbd_mirror_key_prefix
)) {
77 insert({pair
.first
, {}});
82 CephContext
*cct
= (CephContext
*)m_io_ctx
.cct();
84 for (auto &it
: *this) {
85 int r
= cct
->_conf
.get_val(it
.first
.c_str(), &it
.second
.first
);
87 it
.second
.second
= RBD_CONFIG_SOURCE_CONFIG
;
90 std::string last_key
= ImageCtx::METADATA_CONF_PREFIX
;
91 bool more_results
= true;
93 while (more_results
) {
94 std::map
<std::string
, bufferlist
> pairs
;
96 int r
= librbd::api::PoolMetadata
<>::list(m_io_ctx
, last_key
, MAX_KEYS
,
106 more_results
= (pairs
.size() == MAX_KEYS
);
107 last_key
= pairs
.rbegin()->first
;
109 for (auto kv
: pairs
) {
111 if (!util::is_metadata_config_override(kv
.first
, &key
)) {
112 more_results
= false;
117 it
->second
= {{kv
.second
.c_str(), kv
.second
.length()},
118 RBD_CONFIG_SOURCE_POOL
};
126 } // anonymous namespace
128 template <typename I
>
129 bool Config
<I
>::is_option_name(librados::IoCtx
& io_ctx
,
130 const std::string
&name
) {
131 Options
opts(io_ctx
, false);
133 return (opts
.find(name
) != opts
.end());
136 template <typename I
>
137 int Config
<I
>::list(librados::IoCtx
& io_ctx
,
138 std::vector
<config_option_t
> *options
) {
139 Options
opts(io_ctx
, false);
146 for (auto &it
: opts
) {
147 options
->push_back({it
.first
, it
.second
.first
, it
.second
.second
});
153 template <typename I
>
154 bool Config
<I
>::is_option_name(I
*image_ctx
, const std::string
&name
) {
155 Options
opts(image_ctx
->md_ctx
, true);
157 return (opts
.find(name
) != opts
.end());
160 template <typename I
>
161 int Config
<I
>::list(I
*image_ctx
, std::vector
<config_option_t
> *options
) {
162 CephContext
*cct
= image_ctx
->cct
;
163 Options
opts(image_ctx
->md_ctx
, true);
170 std::string last_key
= ImageCtx::METADATA_CONF_PREFIX
;
171 bool more_results
= true;
173 while (more_results
) {
174 std::map
<std::string
, bufferlist
> pairs
;
176 r
= cls_client::metadata_list(&image_ctx
->md_ctx
, image_ctx
->header_oid
,
177 last_key
, MAX_KEYS
, &pairs
);
179 lderr(cct
) << "failed reading image metadata: " << cpp_strerror(r
)
188 more_results
= (pairs
.size() == MAX_KEYS
);
189 last_key
= pairs
.rbegin()->first
;
191 for (auto kv
: pairs
) {
193 if (!util::is_metadata_config_override(kv
.first
, &key
)) {
194 more_results
= false;
197 auto it
= opts
.find(key
);
198 if (it
!= opts
.end()) {
199 it
->second
= {{kv
.second
.c_str(), kv
.second
.length()},
200 RBD_CONFIG_SOURCE_IMAGE
};
205 for (auto &it
: opts
) {
206 options
->push_back({it
.first
, it
.second
.first
, it
.second
.second
});
212 template <typename I
>
213 void Config
<I
>::apply_pool_overrides(librados::IoCtx
& io_ctx
,
214 ConfigProxy
* config
) {
215 CephContext
*cct
= reinterpret_cast<CephContext
*>(io_ctx
.cct());
217 Options
opts(io_ctx
, false);
220 lderr(cct
) << "failed to read pool config overrides: " << cpp_strerror(r
)
225 for (auto& pair
: opts
) {
226 if (pair
.second
.second
== RBD_CONFIG_SOURCE_POOL
) {
227 r
= config
->set_val(pair
.first
, pair
.second
.first
);
229 lderr(cct
) << "failed to override pool config " << pair
.first
<< "="
230 << pair
.second
.first
<< ": " << cpp_strerror(r
) << dendl
;
237 } // namespace librbd
239 template class librbd::api::Config
<librbd::ImageCtx
>;