]>
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",
31 "rbd_default_map_options",
33 "rbd_discard_on_zeroed_write_same",
34 "rbd_op_thread_timeout",
39 "rbd_mirror_pool_replayers_refresh_interval",
40 "rbd_config_pool_override_update_timestamp"
42 static std::set
<std::string_view
> EXCLUDE_IMAGE_OPTIONS
{
43 "rbd_default_clone_format",
44 "rbd_default_data_pool",
45 "rbd_default_features",
48 "rbd_default_stripe_count",
49 "rbd_default_stripe_unit",
52 "rbd_journal_splay_width"
55 struct Options
: Parent
{
56 librados::IoCtx m_io_ctx
;
58 Options(librados::IoCtx
& io_ctx
, bool image_apply_only_options
) {
60 m_io_ctx
.set_namespace("");
62 CephContext
*cct
= reinterpret_cast<CephContext
*>(m_io_ctx
.cct());
64 const std::string
rbd_key_prefix("rbd_");
65 const std::string
rbd_mirror_key_prefix("rbd_mirror_");
66 auto& schema
= cct
->_conf
.get_schema();
67 for (auto& pair
: schema
) {
68 if (!boost::starts_with(pair
.first
, rbd_key_prefix
)) {
70 } else if (EXCLUDE_OPTIONS
.count(pair
.first
) != 0) {
72 } else if (image_apply_only_options
&&
73 EXCLUDE_IMAGE_OPTIONS
.count(pair
.first
) != 0) {
75 } else if (image_apply_only_options
&&
76 boost::starts_with(pair
.first
, rbd_mirror_key_prefix
)) {
80 insert({pair
.first
, {}});
85 CephContext
*cct
= (CephContext
*)m_io_ctx
.cct();
87 for (auto& [k
,v
] : *this) {
88 int r
= cct
->_conf
.get_val(k
, &v
.first
);
90 v
.second
= RBD_CONFIG_SOURCE_CONFIG
;
93 std::string last_key
= ImageCtx::METADATA_CONF_PREFIX
;
94 bool more_results
= true;
96 while (more_results
) {
97 std::map
<std::string
, bufferlist
> pairs
;
99 int r
= librbd::api::PoolMetadata
<>::list(m_io_ctx
, last_key
, MAX_KEYS
,
109 more_results
= (pairs
.size() == MAX_KEYS
);
110 last_key
= pairs
.rbegin()->first
;
112 for (auto kv
: pairs
) {
114 if (!util::is_metadata_config_override(kv
.first
, &key
)) {
115 more_results
= false;
120 it
->second
= {{kv
.second
.c_str(), kv
.second
.length()},
121 RBD_CONFIG_SOURCE_POOL
};
129 } // anonymous namespace
131 template <typename I
>
132 bool Config
<I
>::is_option_name(librados::IoCtx
& io_ctx
,
133 const std::string
&name
) {
134 Options
opts(io_ctx
, false);
136 return (opts
.find(name
) != opts
.end());
139 template <typename I
>
140 int Config
<I
>::list(librados::IoCtx
& io_ctx
,
141 std::vector
<config_option_t
> *options
) {
142 Options
opts(io_ctx
, false);
149 for (auto& [k
,v
] : opts
) {
150 options
->push_back({std::string
{k
}, v
.first
, v
.second
});
156 template <typename I
>
157 bool Config
<I
>::is_option_name(I
*image_ctx
, const std::string
&name
) {
158 Options
opts(image_ctx
->md_ctx
, true);
160 return (opts
.find(name
) != opts
.end());
163 template <typename I
>
164 int Config
<I
>::list(I
*image_ctx
, std::vector
<config_option_t
> *options
) {
165 CephContext
*cct
= image_ctx
->cct
;
166 Options
opts(image_ctx
->md_ctx
, true);
173 std::map
<std::string
, bufferlist
> pairs
;
175 auto req
= image::GetMetadataRequest
<I
>::create(
176 image_ctx
->md_ctx
, image_ctx
->header_oid
, true,
177 ImageCtx::METADATA_CONF_PREFIX
, ImageCtx::METADATA_CONF_PREFIX
, 0U, &pairs
,
183 lderr(cct
) << "failed reading image metadata: " << cpp_strerror(r
)
188 for (auto kv
: pairs
) {
190 if (!util::is_metadata_config_override(kv
.first
, &key
)) {
193 auto it
= opts
.find(key
);
194 if (it
!= opts
.end()) {
195 it
->second
= {{kv
.second
.c_str(), kv
.second
.length()},
196 RBD_CONFIG_SOURCE_IMAGE
};
200 for (auto& [k
,v
] : opts
) {
201 options
->push_back({std::string
{k
}, v
.first
, v
.second
});
207 template <typename I
>
208 void Config
<I
>::apply_pool_overrides(librados::IoCtx
& io_ctx
,
209 ConfigProxy
* config
) {
210 CephContext
*cct
= reinterpret_cast<CephContext
*>(io_ctx
.cct());
212 Options
opts(io_ctx
, false);
215 lderr(cct
) << "failed to read pool config overrides: " << cpp_strerror(r
)
220 for (auto& [k
,v
] : opts
) {
221 if (v
.second
== RBD_CONFIG_SOURCE_POOL
) {
222 r
= config
->set_val(k
, v
.first
);
224 lderr(cct
) << "failed to override pool config " << k
<< "="
225 << v
.first
<< ": " << cpp_strerror(r
) << dendl
;
232 } // namespace librbd
234 template class librbd::api::Config
<librbd::ImageCtx
>;