Skip to content

Commit

Permalink
librbd: get image name on open if it is opened by id
Browse files Browse the repository at this point in the history
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
  • Loading branch information
Mykola Golub committed Feb 23, 2016
1 parent ef30dde commit cb9cc45
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/librbd/image/RefreshRequest.cc
Expand Up @@ -244,6 +244,51 @@ Context *RefreshRequest<I>::handle_v2_get_mutable_metadata(int *result) {
return m_on_finish;
}

if (m_image_ctx.name.empty()) {
send_v2_get_name();
} else {
send_v2_get_flags();
}
return nullptr;
}

template <typename I>
void RefreshRequest<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 = RefreshRequest<I>;
librados::AioCompletion *comp = create_rados_ack_callback<
klass, &klass::handle_v2_get_name>(this);
m_out_bl.clear();
int r = m_image_ctx.md_ctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_out_bl);
assert(r == 0);
comp->release();
}

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

if (*result == 0) {
bufferlist::iterator it = m_out_bl.begin();
cls_client::dir_get_name_finish(&it, &m_name);
}
if (*result == -ENOENT) {
ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
send_v2_get_mutable_metadata();
return nullptr;
} else if (*result < 0) {
lderr(cct) << "failed to retrieve name: " << cpp_strerror(*result)
<< dendl;
return m_on_finish;
}

send_v2_get_flags();
return nullptr;
}
Expand Down Expand Up @@ -730,6 +775,9 @@ void RefreshRequest<I>::apply() {
m_image_ctx.init_layout();
} else {
m_image_ctx.features = m_features;
if (m_image_ctx.name.empty()) {
m_image_ctx.name = m_name;
}
m_image_ctx.flags = m_flags;
m_image_ctx.parent_md = m_parent_md;
}
Expand Down
7 changes: 7 additions & 0 deletions src/librbd/image/RefreshRequest.h
Expand Up @@ -49,6 +49,9 @@ class RefreshRequest {
* \-----> V2_GET_MUTABLE_METADATA <apply>
* | |
* v |
* V2_GET_NAME (skip if known) |
* | |
* v |
* V2_GET_FLAGS |
* | |
* v |
Expand Down Expand Up @@ -109,6 +112,7 @@ class RefreshRequest {
uint64_t m_size;
uint64_t m_features;
uint64_t m_incompatible_features;
std::string m_name;
uint64_t m_flags;
std::string m_object_prefix;
parent_info m_parent_md;
Expand Down Expand Up @@ -137,6 +141,9 @@ class RefreshRequest {
void send_v2_get_mutable_metadata();
Context *handle_v2_get_mutable_metadata(int *result);

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

void send_v2_get_flags();
Context *handle_v2_get_flags(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

0 comments on commit cb9cc45

Please sign in to comment.