]>
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 "common/dout.h"
6 #include "common/errno.h"
7 #include "common/Cond.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/Utils.h"
10 #include "librbd/api/PoolMetadata.h"
11 #include "librbd/image/GetMetadataRequest.h"
13 #include <boost/algorithm/string/predicate.hpp>
15 #define dout_subsys ceph_subsys_rbd
17 #define dout_prefix *_dout << "librbd::Config: " << __func__ << ": "
24 const uint32_t MAX_KEYS
= 64;
26 typedef std::map
<std::string_view
, std::pair
<std::string
, config_source_t
>> Parent
;
28 static std::set
<std::string_view
> EXCLUDE_OPTIONS
{
29 "rbd_auto_exclusive_lock_until_manual_request",
32 "rbd_discard_on_zeroed_write_same",
33 "rbd_op_thread_timeout",
38 "rbd_mirror_pool_replayers_refresh_interval",
39 "rbd_config_pool_override_update_timestamp"
41 static std::set
<std::string_view
> EXCLUDE_IMAGE_OPTIONS
{
42 "rbd_default_clone_format",
43 "rbd_default_data_pool",
44 "rbd_default_features",
47 "rbd_default_stripe_count",
48 "rbd_default_stripe_unit",
51 "rbd_journal_splay_width"
54 struct Options
: Parent
{
55 librados::IoCtx m_io_ctx
;
57 Options(librados::IoCtx
& io_ctx
, bool image_apply_only_options
) {
59 m_io_ctx
.set_namespace("");
61 CephContext
*cct
= reinterpret_cast<CephContext
*>(m_io_ctx
.cct());
63 const std::string
rbd_key_prefix("rbd_");
64 const std::string
rbd_mirror_key_prefix("rbd_mirror_");
65 auto& schema
= cct
->_conf
.get_schema();
66 for (auto& pair
: schema
) {
67 if (!boost::starts_with(pair
.first
, rbd_key_prefix
)) {
69 } else if (EXCLUDE_OPTIONS
.count(pair
.first
) != 0) {
71 } else if (image_apply_only_options
&&
72 EXCLUDE_IMAGE_OPTIONS
.count(pair
.first
) != 0) {
74 } else if (image_apply_only_options
&&
75 boost::starts_with(pair
.first
, rbd_mirror_key_prefix
)) {
79 insert({pair
.first
, {}});
84 CephContext
*cct
= (CephContext
*)m_io_ctx
.cct();
86 for (auto& [k
,v
] : *this) {
87 int r
= cct
->_conf
.get_val(k
, &v
.first
);
89 v
.second
= RBD_CONFIG_SOURCE_CONFIG
;
92 std::string last_key
= ImageCtx::METADATA_CONF_PREFIX
;
93 bool more_results
= true;
95 while (more_results
) {
96 std::map
<std::string
, bufferlist
> pairs
;
98 int r
= librbd::api::PoolMetadata
<>::list(m_io_ctx
, last_key
, MAX_KEYS
,
108 more_results
= (pairs
.size() == MAX_KEYS
);
109 last_key
= pairs
.rbegin()->first
;
111 for (auto kv
: pairs
) {
113 if (!util::is_metadata_config_override(kv
.first
, &key
)) {
114 more_results
= false;
119 it
->second
= {{kv
.second
.c_str(), kv
.second
.length()},
120 RBD_CONFIG_SOURCE_POOL
};
128 } // anonymous namespace
130 template <typename I
>
131 bool Config
<I
>::is_option_name(librados::IoCtx
& io_ctx
,
132 const std::string
&name
) {
133 Options
opts(io_ctx
, false);
135 return (opts
.find(name
) != opts
.end());
138 template <typename I
>
139 int Config
<I
>::list(librados::IoCtx
& io_ctx
,
140 std::vector
<config_option_t
> *options
) {
141 Options
opts(io_ctx
, false);
148 for (auto& [k
,v
] : opts
) {
149 options
->push_back({std::string
{k
}, v
.first
, v
.second
});
155 template <typename I
>
156 bool Config
<I
>::is_option_name(I
*image_ctx
, const std::string
&name
) {
157 Options
opts(image_ctx
->md_ctx
, true);
159 return (opts
.find(name
) != opts
.end());
162 template <typename I
>
163 int Config
<I
>::list(I
*image_ctx
, std::vector
<config_option_t
> *options
) {
164 CephContext
*cct
= image_ctx
->cct
;
165 Options
opts(image_ctx
->md_ctx
, true);
172 std::map
<std::string
, bufferlist
> pairs
;
174 auto req
= image::GetMetadataRequest
<I
>::create(
175 image_ctx
->md_ctx
, image_ctx
->header_oid
, true,
176 ImageCtx::METADATA_CONF_PREFIX
, ImageCtx::METADATA_CONF_PREFIX
, 0U, &pairs
,
182 lderr(cct
) << "failed reading image metadata: " << cpp_strerror(r
)
187 for (auto kv
: pairs
) {
189 if (!util::is_metadata_config_override(kv
.first
, &key
)) {
192 auto it
= opts
.find(key
);
193 if (it
!= opts
.end()) {
194 it
->second
= {{kv
.second
.c_str(), kv
.second
.length()},
195 RBD_CONFIG_SOURCE_IMAGE
};
199 for (auto& [k
,v
] : opts
) {
200 options
->push_back({std::string
{k
}, v
.first
, v
.second
});
206 template <typename I
>
207 void Config
<I
>::apply_pool_overrides(librados::IoCtx
& io_ctx
,
208 ConfigProxy
* config
) {
209 CephContext
*cct
= reinterpret_cast<CephContext
*>(io_ctx
.cct());
211 Options
opts(io_ctx
, false);
214 lderr(cct
) << "failed to read pool config overrides: " << cpp_strerror(r
)
219 for (auto& [k
,v
] : opts
) {
220 if (v
.second
== RBD_CONFIG_SOURCE_POOL
) {
221 r
= config
->set_val(k
, v
.first
);
223 lderr(cct
) << "failed to override pool config " << k
<< "="
224 << v
.first
<< ": " << cpp_strerror(r
) << dendl
;
231 } // namespace librbd
233 template class librbd::api::Config
<librbd::ImageCtx
>;