Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

librbd: retrieve image name when opening by id #7736

Merged
merged 3 commits into from Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 23 additions & 11 deletions src/cls/rbd/cls_rbd_client.cc
Expand Up @@ -758,25 +758,37 @@ namespace librbd {
return 0;
}

int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
const std::string &id, std::string *name)
{
bufferlist in, out;
::encode(id, in);
int r = ioctx->exec(oid, "rbd", "dir_get_name", in, out);
if (r < 0)
return r;
void dir_get_name_start(librados::ObjectReadOperation *op,
const std::string &id) {
bufferlist in_bl;
::encode(id, in_bl);
op->exec("rbd", "dir_get_name", in_bl);
}

bufferlist::iterator iter = out.begin();
int dir_get_name_finish(bufferlist::iterator *it, std::string *name) {
try {
::decode(*name, iter);
::decode(*name, *it);
} catch (const buffer::error &err) {
return -EBADMSG;
}

return 0;
}

int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
const std::string &id, std::string *name) {
librados::ObjectReadOperation op;
dir_get_name_start(&op, id);

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

bufferlist::iterator it = out_bl.begin();
return dir_get_name_finish(&it, name);
}

int dir_list(librados::IoCtx *ioctx, const std::string &oid,
const std::string &start, uint64_t max_return,
map<string, string> *images)
Expand Down
3 changes: 3 additions & 0 deletions src/cls/rbd/cls_rbd_client.h
Expand Up @@ -152,6 +152,9 @@ namespace librbd {
// operations on rbd_directory objects
int dir_get_id(librados::IoCtx *ioctx, const std::string &oid,
const std::string &name, std::string *id);
void dir_get_name_start(librados::ObjectReadOperation *op,
const std::string &id);
int dir_get_name_finish(bufferlist::iterator *it, std::string *name);
int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
const std::string &id, std::string *name);
int dir_list(librados::IoCtx *ioctx, const std::string &oid,
Expand Down
15 changes: 12 additions & 3 deletions src/librbd/ImageCtx.cc
Expand Up @@ -175,8 +175,6 @@ struct C_InvalidateCache : public Context {
if (snap)
snap_name = snap;

asok_hook = new LibrbdAdminSocketHook(this);

memset(&header, 0, sizeof(header));
memset(&layout, 0, sizeof(layout));

Expand All @@ -196,6 +194,7 @@ struct C_InvalidateCache : public Context {
assert(exclusive_lock == NULL);
assert(object_map == NULL);
assert(journal == NULL);
assert(asok_hook == NULL);

if (perfcounter) {
perf_stop();
Expand All @@ -221,7 +220,6 @@ struct C_InvalidateCache : public Context {

delete op_work_queue;
delete aio_work_queue;
delete asok_hook;
delete operations;
delete state;
}
Expand All @@ -234,6 +232,8 @@ struct C_InvalidateCache : public Context {
}
apply_metadata_confs();

asok_hook = new LibrbdAdminSocketHook(this);

string pname = string("librbd-") + id + string("-") +
data_ctx.get_pool_name() + string("-") + name;
if (!snap_name.empty()) {
Expand Down Expand Up @@ -286,6 +286,15 @@ struct C_InvalidateCache : public Context {
readahead.set_max_readahead_size(readahead_max_bytes);
}

void ImageCtx::shutdown() {
if (image_watcher != nullptr) {
unregister_watch();
}

delete asok_hook;
asok_hook = nullptr;
}

void ImageCtx::init_layout()
{
if (stripe_unit == 0 || stripe_count == 0) {
Expand Down
1 change: 1 addition & 0 deletions src/librbd/ImageCtx.h
Expand Up @@ -197,6 +197,7 @@ namespace librbd {
const char *snap, IoCtx& p, bool read_only);
~ImageCtx();
void init();
void shutdown();
void init_layout();
void perf_start(std::string name);
void perf_stop();
Expand Down
5 changes: 1 addition & 4 deletions src/librbd/image/CloseRequest.cc
Expand Up @@ -248,10 +248,7 @@ void CloseRequest<I>::handle_flush_image_watcher(int r) {

template <typename I>
void CloseRequest<I>::finish() {
if (m_image_ctx->image_watcher != nullptr) {
m_image_ctx->unregister_watch();
}

m_image_ctx->shutdown();
m_on_finish->complete(m_error_result);
delete this;
}
Expand Down
40 changes: 38 additions & 2 deletions src/librbd/image/OpenRequest.cc
Expand Up @@ -102,7 +102,7 @@ void OpenRequest<I>::send_v2_detect_header() {
comp, &op, &m_out_bl);
comp->release();
} else {
send_v2_get_immutable_metadata();
send_v2_get_name();
}
}

Expand Down Expand Up @@ -141,7 +141,7 @@ void OpenRequest<I>::send_v2_get_id() {
comp, &op, &m_out_bl);
comp->release();
} else {
send_v2_get_immutable_metadata();
send_v2_get_name();
}
}

Expand All @@ -164,6 +164,42 @@ Context *OpenRequest<I>::handle_v2_get_id(int *result) {
return nullptr;
}

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

librados::ObjectReadOperation op;
cls_client::dir_get_name_start(&op, m_image_ctx->id);

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

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

if (*result == 0) {
bufferlist::iterator it = m_out_bl.begin();
*result = cls_client::dir_get_name_finish(&it, &m_image_ctx->name);
}
if (*result < 0) {
lderr(cct) << "failed to retreive name: "
<< cpp_strerror(*result) << dendl;
send_close_image(*result);
} else {
send_v2_get_immutable_metadata();
}

return nullptr;
}

template <typename I>
void OpenRequest<I>::send_v2_get_immutable_metadata() {
CephContext *cct = m_image_ctx->cct;
Expand Down
5 changes: 4 additions & 1 deletion src/librbd/image/OpenRequest.h
Expand Up @@ -38,7 +38,7 @@ class OpenRequest {
* \-----> V2_DETECT_HEADER | .
* | | .
* v | .
* V2_GET_ID | .
* V2_GET_ID|NAME | .
* | | .
* v | .
* V2_GET_IMMUTABLE_METADATA | .
Expand Down Expand Up @@ -78,6 +78,9 @@ class OpenRequest {
void send_v2_get_id();
Context *handle_v2_get_id(int *result);

void send_v2_get_name();
Context *handle_v2_get_name(int *result);

void send_v2_get_immutable_metadata();
Context *handle_v2_get_immutable_metadata(int *result);

Expand Down
15 changes: 15 additions & 0 deletions src/test/librbd/test_internal.cc
Expand Up @@ -6,6 +6,7 @@
#include "librbd/AioImageRequest.h"
#include "librbd/AioImageRequestWQ.h"
#include "librbd/ExclusiveLock.h"
#include "librbd/ImageState.h"
#include "librbd/ImageWatcher.h"
#include "librbd/internal.h"
#include "librbd/ObjectMap.h"
Expand Down Expand Up @@ -71,6 +72,20 @@ class DummyContext : public Context {
}
};

TEST_F(TestInternal, OpenByID) {
REQUIRE_FORMAT_V2();

librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
std::string id = ictx->id;
close_image(ictx);

ictx = new librbd::ImageCtx("", id, nullptr, m_ioctx, true);
ASSERT_EQ(0, ictx->state->open());
ASSERT_EQ(ictx->name, m_image_name);
close_image(ictx);
}

TEST_F(TestInternal, IsExclusiveLockOwner) {
REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);

Expand Down