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;
C_SaferCond ctx;
auto req = image::GetMetadataRequest<I>::create(
image_ctx->md_ctx, image_ctx->header_oid, ImageCtx::METADATA_CONF_PREFIX,
ImageCtx::METADATA_CONF_PREFIX, 0U, &pairs, &ctx);
image_ctx->md_ctx, image_ctx->header_oid, true,
ImageCtx::METADATA_CONF_PREFIX, ImageCtx::METADATA_CONF_PREFIX, 0U, &pairs,
&ctx);
req->send();
r = ctx.wait();

View File

@ -99,7 +99,7 @@ int PoolMetadata<I>::list(librados::IoCtx& io_ctx, const std::string &start,
pairs->clear();
C_SaferCond ctx;
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();
int r = ctx.wait();

View File

@ -46,7 +46,7 @@ void MetadataCopyRequest<I>::list_src_metadata() {
MetadataCopyRequest<I>,
&MetadataCopyRequest<I>::handle_list_src_metadata>(this);
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);
req->send();
}

View File

@ -19,15 +19,21 @@
namespace librbd {
namespace image {
namespace {
static const std::string INTERNAL_KEY_PREFIX{".rbd"};
} // anonymous namespace
using util::create_rados_callback;
template <typename I>
GetMetadataRequest<I>::GetMetadataRequest(
IoCtx &io_ctx, const std::string &oid, const std::string& filter,
const std::string& last_key, 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),
IoCtx &io_ctx, const std::string &oid, bool filter_internal,
const std::string& filter_key_prefix, const std::string& last_key,
uint32_t max_results, KeyValues* key_values, Context *on_finish)
: 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_on_finish(on_finish),
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) {
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;
}
m_key_values->insert({it->first, std::move(it->second)});

View File

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

View File

@ -500,7 +500,7 @@ void RefreshRequest<I>::send_v2_get_metadata() {
auto ctx = create_context_callback<
RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_metadata>(this);
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,
&m_metadata, ctx);
req->send();
@ -529,7 +529,7 @@ void RefreshRequest<I>::send_v2_get_pool_metadata() {
auto ctx = create_context_callback<
RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_pool_metadata>(this);
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);
req->send();
}

View File

@ -1639,7 +1639,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
C_SaferCond ctx;
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();
return ctx.wait();

View File

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

View File

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

View File

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

View File

@ -148,7 +148,7 @@ void ApplyImageStateRequest<I>::get_image_meta() {
ApplyImageStateRequest<I>,
&ApplyImageStateRequest<I>::handle_get_image_meta>(this);
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);
req->send();
}