librbd: optionally filter internal image-meta when copying/cloning

Any ".rbd"-prefixed image-meta keys will be considered RBD-internal and
will not be added to the new image when copied/cloned.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2020-02-25 08:54:37 -05:00
parent 281a64acf9
commit f523d7059c
11 changed files with 41 additions and 25 deletions

View File

@ -172,8 +172,9 @@ int Config<I>::list(I *image_ctx, std::vector<config_option_t> *options) {
std::map<std::string, bufferlist> pairs; std::map<std::string, bufferlist> pairs;
C_SaferCond ctx; C_SaferCond ctx;
auto req = image::GetMetadataRequest<I>::create( auto req = image::GetMetadataRequest<I>::create(
image_ctx->md_ctx, image_ctx->header_oid, ImageCtx::METADATA_CONF_PREFIX, image_ctx->md_ctx, image_ctx->header_oid, true,
ImageCtx::METADATA_CONF_PREFIX, 0U, &pairs, &ctx); ImageCtx::METADATA_CONF_PREFIX, ImageCtx::METADATA_CONF_PREFIX, 0U, &pairs,
&ctx);
req->send(); req->send();
r = ctx.wait(); r = ctx.wait();

View File

@ -99,7 +99,7 @@ int PoolMetadata<I>::list(librados::IoCtx& io_ctx, const std::string &start,
pairs->clear(); pairs->clear();
C_SaferCond ctx; C_SaferCond ctx;
auto req = image::GetMetadataRequest<I>::create( auto req = image::GetMetadataRequest<I>::create(
io_ctx, RBD_INFO, "", start, max, pairs, &ctx); io_ctx, RBD_INFO, false, "", start, max, pairs, &ctx);
req->send(); req->send();
int r = ctx.wait(); int r = ctx.wait();

View File

@ -46,7 +46,7 @@ void MetadataCopyRequest<I>::list_src_metadata() {
MetadataCopyRequest<I>, MetadataCopyRequest<I>,
&MetadataCopyRequest<I>::handle_list_src_metadata>(this); &MetadataCopyRequest<I>::handle_list_src_metadata>(this);
auto req = image::GetMetadataRequest<I>::create( auto req = image::GetMetadataRequest<I>::create(
m_src_image_ctx->md_ctx, m_src_image_ctx->header_oid, "", m_src_image_ctx->md_ctx, m_src_image_ctx->header_oid, true, "",
m_last_metadata_key, MAX_METADATA_ITEMS, &m_metadata, ctx); m_last_metadata_key, MAX_METADATA_ITEMS, &m_metadata, ctx);
req->send(); req->send();
} }

View File

@ -19,15 +19,21 @@
namespace librbd { namespace librbd {
namespace image { namespace image {
namespace {
static const std::string INTERNAL_KEY_PREFIX{".rbd"};
} // anonymous namespace
using util::create_rados_callback; using util::create_rados_callback;
template <typename I> template <typename I>
GetMetadataRequest<I>::GetMetadataRequest( GetMetadataRequest<I>::GetMetadataRequest(
IoCtx &io_ctx, const std::string &oid, const std::string& filter, IoCtx &io_ctx, const std::string &oid, bool filter_internal,
const std::string& last_key, uint32_t max_results, const std::string& filter_key_prefix, const std::string& last_key,
KeyValues* key_values, Context *on_finish) uint32_t max_results, KeyValues* key_values, Context *on_finish)
: m_io_ctx(io_ctx), m_oid(oid), m_filter(filter), m_last_key(last_key), : m_io_ctx(io_ctx), m_oid(oid), m_filter_internal(filter_internal),
m_filter_key_prefix(filter_key_prefix), m_last_key(last_key),
m_max_results(max_results), m_key_values(key_values), m_max_results(max_results), m_key_values(key_values),
m_on_finish(on_finish), m_on_finish(on_finish),
m_cct(reinterpret_cast<CephContext*>(m_io_ctx.cct())) { m_cct(reinterpret_cast<CephContext*>(m_io_ctx.cct())) {
@ -79,7 +85,11 @@ void GetMetadataRequest<I>::handle_metadata_list(int r) {
} }
for (auto it = metadata.begin(); it != metadata.end(); ++it) { for (auto it = metadata.begin(); it != metadata.end(); ++it) {
if (!m_filter.empty() && !boost::starts_with(it->first, m_filter)) { if (m_filter_internal &&
boost::starts_with(it->first, INTERNAL_KEY_PREFIX)) {
continue;
} else if (!m_filter_key_prefix.empty() &&
!boost::starts_with(it->first, m_filter_key_prefix)) {
continue; continue;
} }
m_key_values->insert({it->first, std::move(it->second)}); m_key_values->insert({it->first, std::move(it->second)});

View File

@ -24,17 +24,18 @@ public:
typedef std::map<std::string, bufferlist> KeyValues; typedef std::map<std::string, bufferlist> KeyValues;
static GetMetadataRequest* create( static GetMetadataRequest* create(
IoCtx &io_ctx, const std::string &oid, const std::string& filter, IoCtx &io_ctx, const std::string &oid, bool filter_internal,
const std::string& last_key, uint32_t max_results, KeyValues* key_values, const std::string& filter_key_prefix, const std::string& last_key,
Context *on_finish) { uint32_t max_results, KeyValues* key_values, Context *on_finish) {
return new GetMetadataRequest(io_ctx, oid, filter, last_key, max_results, return new GetMetadataRequest(io_ctx, oid, filter_internal,
filter_key_prefix, last_key, max_results,
key_values, on_finish); key_values, on_finish);
} }
GetMetadataRequest( GetMetadataRequest(
IoCtx &io_ctx, const std::string &oid, const std::string& filter, IoCtx &io_ctx, const std::string &oid, bool filter_internal,
const std::string& last_key, uint32_t max_results, KeyValues* key_values, const std::string& filter_key_prefix, const std::string& last_key,
Context *on_finish); uint32_t max_results, KeyValues* key_values, Context *on_finish);
void send(); void send();
@ -56,7 +57,8 @@ private:
*/ */
librados::IoCtx m_io_ctx; librados::IoCtx m_io_ctx;
std::string m_oid; std::string m_oid;
std::string m_filter; bool m_filter_internal;
std::string m_filter_key_prefix;
std::string m_last_key; std::string m_last_key;
uint32_t m_max_results; uint32_t m_max_results;
KeyValues* m_key_values; KeyValues* m_key_values;

View File

@ -500,7 +500,7 @@ void RefreshRequest<I>::send_v2_get_metadata() {
auto ctx = create_context_callback< auto ctx = create_context_callback<
RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_metadata>(this); RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_metadata>(this);
auto req = GetMetadataRequest<I>::create( auto req = GetMetadataRequest<I>::create(
m_image_ctx.md_ctx, m_image_ctx.header_oid, m_image_ctx.md_ctx, m_image_ctx.header_oid, true,
ImageCtx::METADATA_CONF_PREFIX, ImageCtx::METADATA_CONF_PREFIX, 0U, ImageCtx::METADATA_CONF_PREFIX, ImageCtx::METADATA_CONF_PREFIX, 0U,
&m_metadata, ctx); &m_metadata, ctx);
req->send(); req->send();
@ -529,7 +529,7 @@ void RefreshRequest<I>::send_v2_get_pool_metadata() {
auto ctx = create_context_callback< auto ctx = create_context_callback<
RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_pool_metadata>(this); RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_pool_metadata>(this);
auto req = GetMetadataRequest<I>::create( auto req = GetMetadataRequest<I>::create(
m_pool_metadata_io_ctx, RBD_INFO, ImageCtx::METADATA_CONF_PREFIX, m_pool_metadata_io_ctx, RBD_INFO, true, ImageCtx::METADATA_CONF_PREFIX,
ImageCtx::METADATA_CONF_PREFIX, 0U, &m_metadata, ctx); ImageCtx::METADATA_CONF_PREFIX, 0U, &m_metadata, ctx);
req->send(); req->send();
} }

View File

@ -1639,7 +1639,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
C_SaferCond ctx; C_SaferCond ctx;
auto req = image::GetMetadataRequest<>::create( auto req = image::GetMetadataRequest<>::create(
ictx->md_ctx, ictx->header_oid, "", start, max, pairs, &ctx); ictx->md_ctx, ictx->header_oid, false, "", start, max, pairs, &ctx);
req->send(); req->send();
return ctx.wait(); return ctx.wait();

View File

@ -33,7 +33,8 @@ struct GetMetadataRequest<MockTestImageCtx> {
static GetMetadataRequest* s_instance; static GetMetadataRequest* s_instance;
static GetMetadataRequest* create(librados::IoCtx&, static GetMetadataRequest* create(librados::IoCtx&,
const std::string& oid, const std::string& oid,
const std::string& filter, bool filter_internal,
const std::string& filter_key_prefix,
const std::string& last_key, const std::string& last_key,
uint32_t max_results, uint32_t max_results,
std::map<std::string, bufferlist>* pairs, std::map<std::string, bufferlist>* pairs,

View File

@ -46,13 +46,14 @@ struct GetMetadataRequest<MockRefreshImageCtx> {
static GetMetadataRequest* s_instance; static GetMetadataRequest* s_instance;
static GetMetadataRequest* create(librados::IoCtx&, static GetMetadataRequest* create(librados::IoCtx&,
const std::string& oid, const std::string& oid,
const std::string& filter, bool filter_internal,
const std::string& filter_key_prefix,
const std::string& last_key, const std::string& last_key,
uint32_t max_results, uint32_t max_results,
std::map<std::string, bufferlist>* pairs, std::map<std::string, bufferlist>* pairs,
Context* on_finish) { Context* on_finish) {
ceph_assert(s_instance != nullptr); ceph_assert(s_instance != nullptr);
EXPECT_EQ("conf_", filter); EXPECT_EQ("conf_", filter_key_prefix);
EXPECT_EQ("conf_", last_key); EXPECT_EQ("conf_", last_key);
s_instance->oid = oid; s_instance->oid = oid;
s_instance->pairs = pairs; s_instance->pairs = pairs;

View File

@ -32,7 +32,8 @@ struct GetMetadataRequest<MockTestImageCtx> {
static GetMetadataRequest* s_instance; static GetMetadataRequest* s_instance;
static GetMetadataRequest* create(librados::IoCtx& io_ctx, static GetMetadataRequest* create(librados::IoCtx& io_ctx,
const std::string& oid, const std::string& oid,
const std::string& filter, bool filter_internal,
const std::string& filter_key_prefix,
const std::string& last_key, const std::string& last_key,
size_t max_results, size_t max_results,
std::map<std::string, bufferlist>* pairs, std::map<std::string, bufferlist>* pairs,

View File

@ -148,7 +148,7 @@ void ApplyImageStateRequest<I>::get_image_meta() {
ApplyImageStateRequest<I>, ApplyImageStateRequest<I>,
&ApplyImageStateRequest<I>::handle_get_image_meta>(this); &ApplyImageStateRequest<I>::handle_get_image_meta>(this);
auto req = librbd::image::GetMetadataRequest<I>::create( auto req = librbd::image::GetMetadataRequest<I>::create(
m_local_image_ctx->md_ctx, m_local_image_ctx->header_oid, "", "", 0U, m_local_image_ctx->md_ctx, m_local_image_ctx->header_oid, true, "", "", 0U,
&m_metadata, ctx); &m_metadata, ctx);
req->send(); req->send();
} }