Skip to content

Commit

Permalink
Merge pull request #9318 from Abhishekvrshny/wip-15957-jewel
Browse files Browse the repository at this point in the history
jewel: Metadata config overrides are applied synchronously

Reviewed-by: Jason Dillaman <dillaman@redhat.com>
  • Loading branch information
Jason Dillaman committed May 31, 2016
2 parents 409fc64 + 305ebbc commit dafe375
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 95 deletions.
34 changes: 25 additions & 9 deletions src/cls/rbd/cls_rbd_client.cc
Expand Up @@ -942,21 +942,37 @@ namespace librbd {
const std::string &start, uint64_t max_return,
map<string, bufferlist> *pairs)
{
assert(pairs);
bufferlist in, out;
::encode(start, in);
::encode(max_return, in);
int r = ioctx->exec(oid, "rbd", "metadata_list", in, out);
if (r < 0)
librados::ObjectReadOperation op;
metadata_list_start(&op, start, max_return);

bufferlist out_bl;
int r = ioctx->operate(oid, &op, &out_bl);
if (r < 0) {
return r;
}

bufferlist::iterator iter = out.begin();
bufferlist::iterator it = out_bl.begin();
return metadata_list_finish(&it, pairs);
}

void metadata_list_start(librados::ObjectReadOperation *op,
const std::string &start, uint64_t max_return)
{
bufferlist in_bl;
::encode(start, in_bl);
::encode(max_return, in_bl);
op->exec("rbd", "metadata_list", in_bl);
}

int metadata_list_finish(bufferlist::iterator *it,
std::map<std::string, bufferlist> *pairs)
{
assert(pairs);
try {
::decode(*pairs, iter);
::decode(*pairs, *it);
} catch (const buffer::error &err) {
return -EBADMSG;
}

return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions src/cls/rbd/cls_rbd_client.h
Expand Up @@ -135,6 +135,10 @@ namespace librbd {
int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
const std::string &start, uint64_t max_return,
map<string, bufferlist> *pairs);
void metadata_list_start(librados::ObjectReadOperation *op,
const std::string &start, uint64_t max_return);
int metadata_list_finish(bufferlist::iterator *it,
std::map<std::string, bufferlist> *pairs);
int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
const map<std::string, bufferlist> &data);
int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
Expand Down
66 changes: 21 additions & 45 deletions src/librbd/ImageCtx.cc
Expand Up @@ -234,10 +234,6 @@ struct C_InvalidateCache : public Context {
void ImageCtx::init() {
assert(!header_oid.empty());
assert(old_format || !id.empty());
if (!old_format) {
init_layout();
}
apply_metadata_confs();

asok_hook = new LibrbdAdminSocketHook(this);

Expand Down Expand Up @@ -888,31 +884,32 @@ struct C_InvalidateCache : public Context {
completed_reqs.clear();
}

bool ImageCtx::_filter_metadata_confs(const string &prefix, map<string, bool> &configs,
map<string, bufferlist> &pairs, map<string, bufferlist> *res) {
bool ImageCtx::_filter_metadata_confs(const string &prefix,
map<string, bool> &configs,
const map<string, bufferlist> &pairs,
map<string, bufferlist> *res) {
size_t conf_prefix_len = prefix.size();

string start = prefix;
for (map<string, bufferlist>::iterator it = pairs.begin(); it != pairs.end(); ++it) {
if (it->first.compare(0, MIN(conf_prefix_len, it->first.size()), prefix) > 0)
for (auto it : pairs) {
if (it.first.compare(0, MIN(conf_prefix_len, it.first.size()), prefix) > 0)
return false;

if (it->first.size() <= conf_prefix_len)
if (it.first.size() <= conf_prefix_len)
continue;

string key = it->first.substr(conf_prefix_len, it->first.size() - conf_prefix_len);
map<string, bool>::iterator cit = configs.find(key);
if ( cit != configs.end()) {
string key = it.first.substr(conf_prefix_len, it.first.size() - conf_prefix_len);
auto cit = configs.find(key);
if (cit != configs.end()) {
cit->second = true;
res->insert(make_pair(key, it->second));
res->insert(make_pair(key, it.second));
}
}
return true;
}

void ImageCtx::apply_metadata_confs() {
void ImageCtx::apply_metadata(const std::map<std::string, bufferlist> &meta) {
ldout(cct, 20) << __func__ << dendl;
static uint64_t max_conf_items = 128;
std::map<string, bool> configs = boost::assign::map_list_of(
"rbd_non_blocking_aio", false)(
"rbd_cache", false)(
Expand Down Expand Up @@ -943,39 +940,18 @@ struct C_InvalidateCache : public Context {
"rbd_journal_object_flush_age", false)(
"rbd_journal_pool", false);

string start = METADATA_CONF_PREFIX;
md_config_t local_config_t;

bool retrieve_metadata = !old_format;
while (retrieve_metadata) {
map<string, bufferlist> pairs, res;
int r = cls_client::metadata_list(&md_ctx, header_oid, start, max_conf_items,
&pairs);
if (r == -EOPNOTSUPP || r == -EIO) {
ldout(cct, 10) << "config metadata not supported by OSD" << dendl;
break;
} else if (r < 0) {
lderr(cct) << __func__ << " couldn't list config metadata: " << r
std::map<std::string, bufferlist> res;

_filter_metadata_confs(METADATA_CONF_PREFIX, configs, meta, &res);
for (auto it : res) {
std::string val(it.second.c_str(), it.second.length());
int j = local_config_t.set_val(it.first.c_str(), val);
if (j < 0) {
lderr(cct) << __func__ << " failed to set config " << it.first
<< " with value " << it.second.c_str() << ": " << j
<< dendl;
break;
}
if (pairs.empty()) {
break;
}

retrieve_metadata = _filter_metadata_confs(METADATA_CONF_PREFIX, configs,
pairs, &res);
for (map<string, bufferlist>::iterator it = res.begin();
it != res.end(); ++it) {
string val(it->second.c_str(), it->second.length());
int j = local_config_t.set_val(it->first.c_str(), val);
if (j < 0) {
lderr(cct) << __func__ << " failed to set config " << it->first
<< " with value " << it->second.c_str() << ": " << j
<< dendl;
}
}
start = pairs.rbegin()->first;
}

#define ASSIGN_OPTION(config) \
Expand Down
4 changes: 2 additions & 2 deletions src/librbd/ImageCtx.h
Expand Up @@ -192,7 +192,7 @@ namespace librbd {
journal::Policy *journal_policy = nullptr;

static bool _filter_metadata_confs(const string &prefix, std::map<string, bool> &configs,
map<string, bufferlist> &pairs, map<string, bufferlist> *res);
const map<string, bufferlist> &pairs, map<string, bufferlist> *res);

// unit test mock helpers
static ImageCtx* create(const std::string &image_name,
Expand Down Expand Up @@ -285,7 +285,7 @@ namespace librbd {
void cancel_async_requests();
void cancel_async_requests(Context *on_finish);

void apply_metadata_confs();
void apply_metadata(const std::map<std::string, bufferlist> &meta);

ExclusiveLock<ImageCtx> *create_exclusive_lock();
ObjectMap *create_object_map(uint64_t snap_id);
Expand Down
93 changes: 81 additions & 12 deletions src/librbd/image/OpenRequest.cc
Expand Up @@ -11,6 +11,8 @@
#include "librbd/image/CloseRequest.h"
#include "librbd/image/RefreshRequest.h"
#include "librbd/image/SetSnapRequest.h"
#include <boost/algorithm/string/predicate.hpp>
#include "include/assert.h"

#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
Expand All @@ -19,12 +21,19 @@
namespace librbd {
namespace image {

namespace {

static uint64_t MAX_METADATA_ITEMS = 128;

}

using util::create_context_callback;
using util::create_rados_ack_callback;

template <typename I>
OpenRequest<I>::OpenRequest(I *image_ctx, Context *on_finish)
: m_image_ctx(image_ctx), m_on_finish(on_finish), m_error_result(0) {
: m_image_ctx(image_ctx), m_on_finish(on_finish), m_error_result(0),
m_last_metadata_key(ImageCtx::METADATA_CONF_PREFIX) {
}

template <typename I>
Expand Down Expand Up @@ -63,6 +72,8 @@ Context *OpenRequest<I>::handle_v1_detect_header(int *result) {

m_image_ctx->old_format = true;
m_image_ctx->header_oid = util::old_header_name(m_image_ctx->name);
m_image_ctx->apply_metadata({});

send_register_watch();
}
return nullptr;
Expand Down Expand Up @@ -260,27 +271,85 @@ Context *OpenRequest<I>::handle_v2_get_stripe_unit_count(int *result) {
lderr(cct) << "failed to read striping metadata: " << cpp_strerror(*result)
<< dendl;
send_close_image(*result);
} else {
send_register_watch();
return nullptr;
}

m_image_ctx->init_layout();

send_v2_apply_metadata();
return nullptr;
}

template <typename I>
void OpenRequest<I>::send_v2_apply_metadata() {
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << ": "
<< "start_key=" << m_last_metadata_key << dendl;

librados::ObjectReadOperation op;
cls_client::metadata_list_start(&op, m_last_metadata_key, MAX_METADATA_ITEMS);

using klass = OpenRequest<I>;
librados::AioCompletion *comp =
create_rados_ack_callback<klass, &klass::handle_v2_apply_metadata>(this);
m_out_bl.clear();
m_image_ctx->md_ctx.aio_operate(m_image_ctx->header_oid, comp, &op,
&m_out_bl);
comp->release();
}

template <typename I>
Context *OpenRequest<I>::handle_v2_apply_metadata(int *result) {
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl;

std::map<std::string, bufferlist> metadata;
if (*result == 0) {
bufferlist::iterator it = m_out_bl.begin();
*result = cls_client::metadata_list_finish(&it, &metadata);
}

if (*result == -EOPNOTSUPP || *result == -EIO) {
ldout(cct, 10) << "config metadata not supported by OSD" << dendl;
} else if (*result < 0) {
lderr(cct) << "failed to retrieve metadata: " << cpp_strerror(*result)
<< dendl;
send_close_image(*result);
return nullptr;
}

if (!metadata.empty()) {
m_metadata.insert(metadata.begin(), metadata.end());
m_last_metadata_key = metadata.rbegin()->first;
if (boost::starts_with(m_last_metadata_key,
ImageCtx::METADATA_CONF_PREFIX)) {
send_v2_apply_metadata();
return nullptr;
}
}

m_image_ctx->apply_metadata(m_metadata);

send_register_watch();
return nullptr;
}

template <typename I>
void OpenRequest<I>::send_register_watch() {
m_image_ctx->init();

if (!m_image_ctx->read_only) {
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << dendl;

using klass = OpenRequest<I>;
Context *ctx = create_context_callback<
klass, &klass::handle_register_watch>(this);
m_image_ctx->register_watch(ctx);
} else {
if (m_image_ctx->read_only) {
send_refresh();
return;
}

CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << dendl;

using klass = OpenRequest<I>;
Context *ctx = create_context_callback<
klass, &klass::handle_register_watch>(this);
m_image_ctx->register_watch(ctx);
}

template <typename I>
Expand Down

0 comments on commit dafe375

Please sign in to comment.