]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/api/Config.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / 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
3
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>
12
13 #define dout_subsys ceph_subsys_rbd
14 #undef dout_prefix
15 #define dout_prefix *_dout << "librbd::Config: " << __func__ << ": "
16
17 namespace librbd {
18 namespace api {
19
20 namespace {
21
22 const uint32_t MAX_KEYS = 64;
23
24 typedef std::map<std::string, std::pair<std::string, config_source_t>> Parent;
25
26 static std::set<std::string> EXCLUDE_OPTIONS {
27 "rbd_auto_exclusive_lock_until_manual_request",
28 "rbd_default_format",
29 "rbd_default_map_options",
30 "rbd_default_pool",
31 "rbd_discard_on_zeroed_write_same",
32 "rbd_op_thread_timeout",
33 "rbd_op_threads",
34 "rbd_tracing",
35 "rbd_validate_names",
36 "rbd_validate_pool",
37 "rbd_mirror_pool_replayers_refresh_interval"
38 };
39 static std::set<std::string> EXCLUDE_IMAGE_OPTIONS {
40 "rbd_default_clone_format",
41 "rbd_default_data_pool",
42 "rbd_default_features",
43 "rbd_default_format",
44 "rbd_default_order",
45 "rbd_default_stripe_count",
46 "rbd_default_stripe_unit",
47 "rbd_journal_order",
48 "rbd_journal_pool",
49 "rbd_journal_splay_width"
50 };
51
52 struct Options : Parent {
53 librados::IoCtx m_io_ctx;
54
55 Options(librados::IoCtx& io_ctx, bool image_apply_only_options) {
56 m_io_ctx.dup(io_ctx);
57 m_io_ctx.set_namespace("");
58
59 CephContext *cct = reinterpret_cast<CephContext *>(m_io_ctx.cct());
60
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)) {
66 continue;
67 } else if (EXCLUDE_OPTIONS.count(pair.first) != 0) {
68 continue;
69 } else if (image_apply_only_options &&
70 EXCLUDE_IMAGE_OPTIONS.count(pair.first) != 0) {
71 continue;
72 } else if (image_apply_only_options &&
73 boost::starts_with(pair.first, rbd_mirror_key_prefix)) {
74 continue;
75 }
76
77 insert({pair.first, {}});
78 }
79 }
80
81 int init() {
82 CephContext *cct = (CephContext *)m_io_ctx.cct();
83
84 for (auto &it : *this) {
85 int r = cct->_conf.get_val(it.first.c_str(), &it.second.first);
86 ceph_assert(r == 0);
87 it.second.second = RBD_CONFIG_SOURCE_CONFIG;
88 }
89
90 std::string last_key = ImageCtx::METADATA_CONF_PREFIX;
91 bool more_results = true;
92
93 while (more_results) {
94 std::map<std::string, bufferlist> pairs;
95
96 int r = librbd::api::PoolMetadata<>::list(m_io_ctx, last_key, MAX_KEYS,
97 &pairs);
98 if (r < 0) {
99 return r;
100 }
101
102 if (pairs.empty()) {
103 break;
104 }
105
106 more_results = (pairs.size() == MAX_KEYS);
107 last_key = pairs.rbegin()->first;
108
109 for (auto kv : pairs) {
110 std::string key;
111 if (!util::is_metadata_config_override(kv.first, &key)) {
112 more_results = false;
113 break;
114 }
115 auto it = find(key);
116 if (it != end()) {
117 it->second = {{kv.second.c_str(), kv.second.length()},
118 RBD_CONFIG_SOURCE_POOL};
119 }
120 }
121 }
122 return 0;
123 }
124 };
125
126 } // anonymous namespace
127
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);
132
133 return (opts.find(name) != opts.end());
134 }
135
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);
140
141 int r = opts.init();
142 if (r < 0) {
143 return r;
144 }
145
146 for (auto &it : opts) {
147 options->push_back({it.first, it.second.first, it.second.second});
148 }
149
150 return 0;
151 }
152
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);
156
157 return (opts.find(name) != opts.end());
158 }
159
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);
164
165 int r = opts.init();
166 if (r < 0) {
167 return r;
168 }
169
170 std::string last_key = ImageCtx::METADATA_CONF_PREFIX;
171 bool more_results = true;
172
173 while (more_results) {
174 std::map<std::string, bufferlist> pairs;
175
176 r = cls_client::metadata_list(&image_ctx->md_ctx, image_ctx->header_oid,
177 last_key, MAX_KEYS, &pairs);
178 if (r < 0) {
179 lderr(cct) << "failed reading image metadata: " << cpp_strerror(r)
180 << dendl;
181 return r;
182 }
183
184 if (pairs.empty()) {
185 break;
186 }
187
188 more_results = (pairs.size() == MAX_KEYS);
189 last_key = pairs.rbegin()->first;
190
191 for (auto kv : pairs) {
192 std::string key;
193 if (!util::is_metadata_config_override(kv.first, &key)) {
194 more_results = false;
195 break;
196 }
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};
201 }
202 }
203 }
204
205 for (auto &it : opts) {
206 options->push_back({it.first, it.second.first, it.second.second});
207 }
208
209 return 0;
210 }
211
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());
216
217 Options opts(io_ctx, false);
218 int r = opts.init();
219 if (r < 0) {
220 lderr(cct) << "failed to read pool config overrides: " << cpp_strerror(r)
221 << dendl;
222 return;
223 }
224
225 for (auto& pair : opts) {
226 if (pair.second.second == RBD_CONFIG_SOURCE_POOL) {
227 r = config->set_val(pair.first, pair.second.first);
228 if (r < 0) {
229 lderr(cct) << "failed to override pool config " << pair.first << "="
230 << pair.second.first << ": " << cpp_strerror(r) << dendl;
231 }
232 }
233 }
234 }
235
236 } // namespace api
237 } // namespace librbd
238
239 template class librbd::api::Config<librbd::ImageCtx>;