librbd: switch to new metadata retrieval state machine

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2020-02-13 14:04:07 -05:00
parent b8e1c65db0
commit bcbdd6cf69
12 changed files with 340 additions and 343 deletions

View File

@ -2,12 +2,14 @@
// vim: ts=8 sw=2 smarttab
#include "librbd/api/Config.h"
#include "cls/rbd/cls_rbd_client.h"
#include "common/dout.h"
#include "common/errno.h"
#include "common/Cond.h"
#include "librbd/ImageCtx.h"
#include "librbd/Utils.h"
#include "librbd/api/PoolMetadata.h"
#include "librbd/image/GetMetadataRequest.h"
#include <algorithm>
#include <boost/algorithm/string/predicate.hpp>
#define dout_subsys ceph_subsys_rbd
@ -167,38 +169,29 @@ int Config<I>::list(I *image_ctx, std::vector<config_option_t> *options) {
return r;
}
std::string last_key = ImageCtx::METADATA_CONF_PREFIX;
bool more_results = true;
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);
req->send();
while (more_results) {
std::map<std::string, bufferlist> pairs;
r = ctx.wait();
if (r < 0) {
lderr(cct) << "failed reading image metadata: " << cpp_strerror(r)
<< dendl;
return r;
}
r = cls_client::metadata_list(&image_ctx->md_ctx, image_ctx->header_oid,
last_key, MAX_KEYS, &pairs);
if (r < 0) {
lderr(cct) << "failed reading image metadata: " << cpp_strerror(r)
<< dendl;
return r;
}
if (pairs.empty()) {
for (auto kv : pairs) {
std::string key;
if (!util::is_metadata_config_override(kv.first, &key)) {
break;
}
more_results = (pairs.size() == MAX_KEYS);
last_key = pairs.rbegin()->first;
for (auto kv : pairs) {
std::string key;
if (!util::is_metadata_config_override(kv.first, &key)) {
more_results = false;
break;
}
auto it = opts.find(key);
if (it != opts.end()) {
it->second = {{kv.second.c_str(), kv.second.length()},
RBD_CONFIG_SOURCE_IMAGE};
}
auto it = opts.find(key);
if (it != opts.end()) {
it->second = {{kv.second.c_str(), kv.second.length()},
RBD_CONFIG_SOURCE_IMAGE};
}
}

View File

@ -5,8 +5,10 @@
#include "cls/rbd/cls_rbd_client.h"
#include "common/dout.h"
#include "common/errno.h"
#include "common/Cond.h"
#include "librbd/Utils.h"
#include "librbd/api/Config.h"
#include "librbd/image/GetMetadataRequest.h"
#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
@ -94,15 +96,18 @@ int PoolMetadata<I>::list(librados::IoCtx& io_ctx, const std::string &start,
std::map<std::string, ceph::bufferlist> *pairs) {
CephContext *cct = (CephContext *)io_ctx.cct();
int r = cls_client::metadata_list(&io_ctx, RBD_INFO, start, max, pairs);
if (r == -ENOENT) {
r = 0;
} else if (r < 0) {
pairs->clear();
C_SaferCond ctx;
auto req = image::GetMetadataRequest<I>::create(
io_ctx, RBD_INFO, "", start, max, pairs, &ctx);
req->send();
int r = ctx.wait();
if (r < 0) {
lderr(cct) << "failed listing metadata: " << cpp_strerror(r)
<< dendl;
return r;
}
return 0;
}

View File

@ -6,6 +6,7 @@
#include "common/errno.h"
#include "cls/rbd/cls_rbd_client.h"
#include "librbd/Utils.h"
#include "librbd/image/GetMetadataRequest.h"
#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
@ -21,6 +22,7 @@ const uint64_t MAX_METADATA_ITEMS = 128;
} // anonymous namespace
using librbd::util::create_context_callback;
using librbd::util::create_rados_callback;
template <typename I>
@ -39,50 +41,42 @@ template <typename I>
void MetadataCopyRequest<I>::list_src_metadata() {
ldout(m_cct, 20) << "start_key=" << m_last_metadata_key << dendl;
librados::ObjectReadOperation op;
librbd::cls_client::metadata_list_start(&op, m_last_metadata_key, MAX_METADATA_ITEMS);
librados::AioCompletion *aio_comp = create_rados_callback<
m_metadata.clear();
auto ctx = create_context_callback<
MetadataCopyRequest<I>,
&MetadataCopyRequest<I>::handle_list_src_metadata>(this);
m_out_bl.clear();
m_src_image_ctx->md_ctx.aio_operate(m_src_image_ctx->header_oid,
aio_comp, &op, &m_out_bl);
aio_comp->release();
auto req = image::GetMetadataRequest<I>::create(
m_src_image_ctx->md_ctx, m_src_image_ctx->header_oid, "",
m_last_metadata_key, MAX_METADATA_ITEMS, &m_metadata, ctx);
req->send();
}
template <typename I>
void MetadataCopyRequest<I>::handle_list_src_metadata(int r) {
ldout(m_cct, 20) << "r=" << r << dendl;
Metadata metadata;
if (r == 0) {
auto it = m_out_bl.cbegin();
r = librbd::cls_client::metadata_list_finish(&it, &metadata);
}
if (r < 0) {
lderr(m_cct) << "failed to retrieve metadata: " << cpp_strerror(r) << dendl;
finish(r);
return;
}
if (metadata.empty()) {
if (m_metadata.empty()) {
finish(0);
return;
}
m_last_metadata_key = metadata.rbegin()->first;
m_more_metadata = (metadata.size() >= MAX_METADATA_ITEMS);
set_dst_metadata(metadata);
m_last_metadata_key = m_metadata.rbegin()->first;
m_more_metadata = (m_metadata.size() >= MAX_METADATA_ITEMS);
set_dst_metadata();
}
template <typename I>
void MetadataCopyRequest<I>::set_dst_metadata(const Metadata& metadata) {
ldout(m_cct, 20) << "count=" << metadata.size() << dendl;
void MetadataCopyRequest<I>::set_dst_metadata() {
ldout(m_cct, 20) << "count=" << m_metadata.size() << dendl;
librados::ObjectWriteOperation op;
librbd::cls_client::metadata_set(&op, metadata);
librbd::cls_client::metadata_set(&op, m_metadata);
librados::AioCompletion *aio_comp = create_rados_callback<
MetadataCopyRequest<I>,

View File

@ -56,13 +56,14 @@ private:
CephContext *m_cct;
bufferlist m_out_bl;
std::map<std::string, bufferlist> m_metadata;
std::string m_last_metadata_key;
bool m_more_metadata = false;
void list_src_metadata();
void handle_list_src_metadata(int r);
void set_dst_metadata(const Metadata& metadata);
void set_dst_metadata();
void handle_set_dst_metadata(int r);
void finish(int r);

View File

@ -8,6 +8,7 @@
#include "include/ceph_assert.h"
#include "librbd/ImageState.h"
#include "librbd/Utils.h"
#include "librbd/deep_copy/MetadataCopyRequest.h"
#include "librbd/image/AttachChildRequest.h"
#include "librbd/image/AttachParentRequest.h"
#include "librbd/image/CloneRequest.h"
@ -391,90 +392,32 @@ void CloneRequest<I>::handle_attach_child(int r) {
return;
}
metadata_list();
copy_metadata();
}
template <typename I>
void CloneRequest<I>::metadata_list() {
ldout(m_cct, 15) << "start_key=" << m_last_metadata_key << dendl;
librados::ObjectReadOperation op;
cls_client::metadata_list_start(&op, m_last_metadata_key, 0);
using klass = CloneRequest<I>;
librados::AioCompletion *comp =
create_rados_callback<klass, &klass::handle_metadata_list>(this);
m_out_bl.clear();
m_parent_image_ctx->md_ctx.aio_operate(m_parent_image_ctx->header_oid,
comp, &op, &m_out_bl);
comp->release();
}
template <typename I>
void CloneRequest<I>::handle_metadata_list(int r) {
ldout(m_cct, 15) << "r=" << r << dendl;
map<string, bufferlist> metadata;
if (r == 0) {
auto it = m_out_bl.cbegin();
r = cls_client::metadata_list_finish(&it, &metadata);
}
if (r < 0) {
if (r == -EOPNOTSUPP || r == -EIO) {
ldout(m_cct, 10) << "config metadata not supported by OSD" << dendl;
get_mirror_mode();
} else {
lderr(m_cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
m_r_saved = r;
close_child();
}
return;
}
if (!metadata.empty()) {
m_pairs.insert(metadata.begin(), metadata.end());
m_last_metadata_key = m_pairs.rbegin()->first;
}
if (metadata.size() == MAX_KEYS) {
metadata_list();
} else {
metadata_set();
}
}
template <typename I>
void CloneRequest<I>::metadata_set() {
if (m_pairs.empty()) {
get_mirror_mode();
return;
}
void CloneRequest<I>::copy_metadata() {
ldout(m_cct, 15) << dendl;
librados::ObjectWriteOperation op;
cls_client::metadata_set(&op, m_pairs);
using klass = CloneRequest<I>;
librados::AioCompletion *comp =
create_rados_callback<klass, &klass::handle_metadata_set>(this);
int r = m_ioctx.aio_operate(m_imctx->header_oid, comp, &op);
ceph_assert(r == 0);
comp->release();
auto ctx = create_context_callback<
CloneRequest<I>, &CloneRequest<I>::handle_copy_metadata>(this);
auto req = deep_copy::MetadataCopyRequest<I>::create(
m_parent_image_ctx, m_imctx, ctx);
req->send();
}
template <typename I>
void CloneRequest<I>::handle_metadata_set(int r) {
void CloneRequest<I>::handle_copy_metadata(int r) {
ldout(m_cct, 15) << "r=" << r << dendl;
if (r < 0) {
lderr(m_cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
lderr(m_cct) << "failed to copy metadata: " << cpp_strerror(r) << dendl;
m_r_saved = r;
close_child();
} else {
get_mirror_mode();
return;
}
get_mirror_mode();
}
template <typename I>

View File

@ -77,10 +77,7 @@ private:
* ATTACH CHILD * * * * * * * * * * * *
* | *
* v *
* GET PARENT META * * * * * * * * * ^
* | *
* v (skip if not needed) *
* SET CHILD META * * * * * * * * * * ^
* COPY META DATA * * * * * * * * * * ^
* | *
* v (skip if not needed) *
* GET MIRROR MODE * * * * * * * * * ^
@ -126,8 +123,6 @@ private:
uint64_t m_clone_format = 2;
bool m_use_p_features;
uint64_t m_features;
map<string, bufferlist> m_pairs;
std::string m_last_metadata_key;
bufferlist m_out_bl;
uint64_t m_size;
int m_r_saved = 0;
@ -154,11 +149,8 @@ private:
void attach_child();
void handle_attach_child(int r);
void metadata_list();
void handle_metadata_list(int r);
void metadata_set();
void handle_metadata_set(int r);
void copy_metadata();
void handle_copy_metadata(int r);
void get_mirror_mode();
void handle_get_mirror_mode(int r);

View File

@ -1,7 +1,6 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <boost/algorithm/string/predicate.hpp>
#include "include/ceph_assert.h"
#include "librbd/image/RefreshRequest.h"
@ -16,6 +15,7 @@
#include "librbd/ObjectMap.h"
#include "librbd/Utils.h"
#include "librbd/deep_copy/Utils.h"
#include "librbd/image/GetMetadataRequest.h"
#include "librbd/image/RefreshParentRequest.h"
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ImageDispatchSpec.h"
@ -495,19 +495,15 @@ Context *RefreshRequest<I>::handle_v2_get_parent(int *result) {
template <typename I>
void RefreshRequest<I>::send_v2_get_metadata() {
CephContext *cct = m_image_ctx.cct;
ldout(cct, 10) << this << " " << __func__ << ": "
<< "start_key=" << m_last_metadata_key << dendl;
ldout(cct, 10) << this << " " << __func__ << dendl;
librados::ObjectReadOperation op;
cls_client::metadata_list_start(&op, m_last_metadata_key, MAX_METADATA_ITEMS);
using klass = RefreshRequest<I>;
librados::AioCompletion *comp =
create_rados_callback<klass, &klass::handle_v2_get_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();
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,
ImageCtx::METADATA_CONF_PREFIX, ImageCtx::METADATA_CONF_PREFIX, 0U,
&m_metadata, ctx);
req->send();
}
template <typename I>
@ -515,29 +511,12 @@ Context *RefreshRequest<I>::handle_v2_get_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) {
auto it = m_out_bl.cbegin();
*result = cls_client::metadata_list_finish(&it, &metadata);
}
if (*result < 0) {
lderr(cct) << "failed to retrieve metadata: " << cpp_strerror(*result)
<< dendl;
return m_on_finish;
}
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_get_metadata();
return nullptr;
}
}
m_last_metadata_key.clear();
send_v2_get_pool_metadata();
return nullptr;
}
@ -545,18 +524,14 @@ Context *RefreshRequest<I>::handle_v2_get_metadata(int *result) {
template <typename I>
void RefreshRequest<I>::send_v2_get_pool_metadata() {
CephContext *cct = m_image_ctx.cct;
ldout(cct, 10) << this << " " << __func__ << ": "
<< "start_key=" << m_last_metadata_key << dendl;
ldout(cct, 10) << this << " " << __func__ << dendl;
librados::ObjectReadOperation op;
cls_client::metadata_list_start(&op, m_last_metadata_key, MAX_METADATA_ITEMS);
using klass = RefreshRequest<I>;
librados::AioCompletion *comp =
create_rados_callback<klass, &klass::handle_v2_get_pool_metadata>(this);
m_out_bl.clear();
m_pool_metadata_io_ctx.aio_operate(RBD_INFO, comp, &op, &m_out_bl);
comp->release();
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,
ImageCtx::METADATA_CONF_PREFIX, 0U, &m_metadata, ctx);
req->send();
}
template <typename I>
@ -564,30 +539,12 @@ Context *RefreshRequest<I>::handle_v2_get_pool_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) {
auto it = m_out_bl.cbegin();
*result = cls_client::metadata_list_finish(&it, &metadata);
}
if (*result == -EOPNOTSUPP || *result == -ENOENT) {
ldout(cct, 10) << "pool metadata not supported by OSD" << dendl;
} else if (*result < 0) {
if (*result < 0) {
lderr(cct) << "failed to retrieve pool metadata: " << cpp_strerror(*result)
<< dendl;
return m_on_finish;
}
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_get_pool_metadata();
return nullptr;
}
}
bool thread_safe = m_image_ctx.image_watcher->is_unregistered();
m_image_ctx.apply_metadata(m_metadata, thread_safe);

View File

@ -146,7 +146,6 @@ private:
uint64_t m_op_features = 0;
librados::IoCtx m_pool_metadata_io_ctx;
std::string m_last_metadata_key;
std::map<std::string, bufferlist> m_metadata;
std::string m_object_prefix;

View File

@ -36,8 +36,10 @@
#include "librbd/api/Image.h"
#include "librbd/exclusive_lock/AutomaticPolicy.h"
#include "librbd/exclusive_lock/StandardPolicy.h"
#include "librbd/deep_copy/MetadataCopyRequest.h"
#include "librbd/image/CloneRequest.h"
#include "librbd/image/CreateRequest.h"
#include "librbd/image/GetMetadataRequest.h"
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ImageRequest.h"
#include "librbd/io/ImageRequestWQ.h"
@ -1263,29 +1265,16 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
<< dest_size << dendl;
return -EINVAL;
}
int r;
const uint32_t MAX_KEYS = 64;
map<string, bufferlist> pairs;
std::string last_key = "";
bool more_results = true;
while (more_results) {
r = cls_client::metadata_list(&src->md_ctx, src->header_oid, last_key, 0, &pairs);
if (r < 0 && r != -EOPNOTSUPP && r != -EIO) {
lderr(cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
return r;
} else if (r == 0 && !pairs.empty()) {
r = cls_client::metadata_set(&dest->md_ctx, dest->header_oid, pairs);
if (r < 0) {
lderr(cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
return r;
}
C_SaferCond ctx;
auto req = deep_copy::MetadataCopyRequest<>::create(
src, dest, &ctx);
req->send();
last_key = pairs.rbegin()->first;
}
more_results = (pairs.size() == MAX_KEYS);
pairs.clear();
int r = ctx.wait();
if (r < 0) {
lderr(cct) << "failed to copy metadata: " << cpp_strerror(r) << dendl;
return r;
}
ZTracer::Trace trace;
@ -1648,7 +1637,12 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
return r;
}
return cls_client::metadata_list(&ictx->md_ctx, ictx->header_oid, start, max, pairs);
C_SaferCond ctx;
auto req = image::GetMetadataRequest<>::create(
ictx->md_ctx, ictx->header_oid, "", start, max, pairs, &ctx);
req->send();
return ctx.wait();
}
int list_watchers(ImageCtx *ictx,

View File

@ -6,6 +6,7 @@
#include "include/stringify.h"
#include "librbd/ImageCtx.h"
#include "librbd/deep_copy/MetadataCopyRequest.h"
#include "librbd/image/GetMetadataRequest.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librbd/mock/MockImageCtx.h"
#include "test/librbd/test_support.h"
@ -21,6 +22,38 @@ struct MockTestImageCtx : public librbd::MockImageCtx {
};
} // anonymous namespace
namespace image {
template <>
struct GetMetadataRequest<MockTestImageCtx> {
std::map<std::string, bufferlist>* pairs = nullptr;
Context* on_finish = nullptr;
static GetMetadataRequest* s_instance;
static GetMetadataRequest* create(librados::IoCtx&,
const std::string& oid,
const std::string& filter,
const std::string& last_key,
uint32_t max_results,
std::map<std::string, bufferlist>* pairs,
Context* on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->pairs = pairs;
s_instance->on_finish = on_finish;
return s_instance;
}
GetMetadataRequest() {
s_instance = this;
}
MOCK_METHOD0(send, void());
};
GetMetadataRequest<MockTestImageCtx>* GetMetadataRequest<MockTestImageCtx>::s_instance = nullptr;
} // namspace image
} // namespace librbd
// template definitions
@ -32,6 +65,7 @@ namespace deep_copy {
using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::WithArg;
@ -39,6 +73,7 @@ using ::testing::WithArg;
class TestMockDeepCopyMetadataCopyRequest : public TestMockFixture {
public:
typedef MetadataCopyRequest<librbd::MockTestImageCtx> MockMetadataCopyRequest;
typedef image::GetMetadataRequest<MockTestImageCtx> MockGetMetadataRequest;
typedef std::map<std::string, bufferlist> Metadata;
librbd::ImageCtx *m_src_image_ctx;
@ -60,16 +95,13 @@ public:
&m_thread_pool, &m_work_queue);
}
void expect_metadata_list(librbd::MockTestImageCtx &mock_image_ctx,
const Metadata& metadata, int r) {
bufferlist out_bl;
encode(metadata, out_bl);
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
StrEq("metadata_list"), _, _, _))
.WillOnce(DoAll(WithArg<5>(CopyInBufferlist(out_bl)),
Return(r)));
void expect_get_metadata(MockGetMetadataRequest& mock_request,
const Metadata& metadata, int r) {
EXPECT_CALL(mock_request, send())
.WillOnce(Invoke([this, &mock_request, metadata, r]() {
*mock_request.pairs = metadata;
m_work_queue->queue(mock_request.on_finish, r);
}));
}
void expect_metadata_set(librbd::MockTestImageCtx &mock_image_ctx,
@ -104,9 +136,10 @@ TEST_F(TestMockDeepCopyMetadataCopyRequest, Success) {
}
InSequence seq;
expect_metadata_list(mock_src_image_ctx, key_values_1, 0);
MockGetMetadataRequest mock_request;
expect_get_metadata(mock_request, key_values_1, 0);
expect_metadata_set(mock_dst_image_ctx, key_values_1, 0);
expect_metadata_list(mock_src_image_ctx, key_values_2, 0);
expect_get_metadata(mock_request, key_values_2, 0);
expect_metadata_set(mock_dst_image_ctx, key_values_2, 0);
C_SaferCond ctx;
@ -125,7 +158,8 @@ TEST_F(TestMockDeepCopyMetadataCopyRequest, Empty) {
Metadata key_values;
InSequence seq;
expect_metadata_list(mock_src_image_ctx, key_values, 0);
MockGetMetadataRequest mock_request;
expect_get_metadata(mock_request, key_values, 0);
C_SaferCond ctx;
auto request = MockMetadataCopyRequest::create(&mock_src_image_ctx,
@ -143,7 +177,8 @@ TEST_F(TestMockDeepCopyMetadataCopyRequest, MetadataListError) {
Metadata key_values;
InSequence seq;
expect_metadata_list(mock_src_image_ctx, key_values, -EINVAL);
MockGetMetadataRequest mock_request;
expect_get_metadata(mock_request, key_values, -EINVAL);
C_SaferCond ctx;
auto request = MockMetadataCopyRequest::create(&mock_src_image_ctx,
@ -164,7 +199,8 @@ TEST_F(TestMockDeepCopyMetadataCopyRequest, MetadataSetError) {
key_values.emplace("key", bl);
InSequence seq;
expect_metadata_list(mock_src_image_ctx, key_values, 0);
MockGetMetadataRequest mock_request;
expect_get_metadata(mock_request, key_values, 0);
expect_metadata_set(mock_dst_image_ctx, key_values, -EINVAL);
C_SaferCond ctx;

View File

@ -9,6 +9,7 @@
#include "test/librados_test_stub/MockTestMemRadosClient.h"
#include "librbd/ImageState.h"
#include "librbd/Operations.h"
#include "librbd/deep_copy/MetadataCopyRequest.h"
#include "librbd/image/TypeTraits.h"
#include "librbd/image/AttachChildRequest.h"
#include "librbd/image/AttachParentRequest.h"
@ -47,6 +48,32 @@ MockTestImageCtx* MockTestImageCtx::s_instance = nullptr;
} // anonymous namespace
namespace deep_copy {
template <>
struct MetadataCopyRequest<MockTestImageCtx> {
Context* on_finish = nullptr;
static MetadataCopyRequest* s_instance;
static MetadataCopyRequest* create(MockTestImageCtx* src_image_ctx,
MockTestImageCtx* dst_image_ctx,
Context* on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
return s_instance;
}
MetadataCopyRequest() {
s_instance = this;
}
MOCK_METHOD0(send, void());
};
MetadataCopyRequest<MockTestImageCtx>* MetadataCopyRequest<MockTestImageCtx>::s_instance = nullptr;
} // namespace deep_copy
namespace image {
template <>
@ -202,6 +229,7 @@ public:
typedef AttachParentRequest<MockTestImageCtx> MockAttachParentRequest;
typedef CreateRequest<MockTestImageCtx> MockCreateRequest;
typedef RemoveRequest<MockTestImageCtx> MockRemoveRequest;
typedef deep_copy::MetadataCopyRequest<MockTestImageCtx> MockMetadataCopyRequest;
typedef mirror::EnableRequest<MockTestImageCtx> MockMirrorEnableRequest;
void SetUp() override {
@ -284,31 +312,11 @@ public:
}));
}
void expect_metadata_list(MockTestImageCtx &mock_image_ctx,
const std::map<std::string, bufferlist>& metadata,
int r) {
bufferlist out_bl;
encode(metadata, out_bl);
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("metadata_list"), _, _, _))
.WillOnce(WithArg<5>(Invoke([out_bl, r](bufferlist *out) {
*out = out_bl;
return r;
})));
}
void expect_metadata_set(librados::IoCtx& io_ctx,
MockTestImageCtx& mock_image_ctx,
const std::map<std::string, bufferlist>& metadata,
int r) {
bufferlist in_bl;
encode(metadata, in_bl);
EXPECT_CALL(get_mock_io_ctx(io_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("metadata_set"),
ContentsEqual(in_bl), _, _))
.WillOnce(Return(r));
void expect_metadata_copy(MockMetadataCopyRequest& mock_request, int r) {
EXPECT_CALL(mock_request, send())
.WillOnce(Invoke([this, &mock_request, r]() {
image_ctx->op_work_queue->queue(mock_request.on_finish, r);
}));
}
void expect_test_features(MockTestImageCtx &mock_image_ctx,
@ -381,8 +389,8 @@ TEST_F(TestMockImageCloneRequest, SuccessV1) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 1, 0);
expect_metadata_list(mock_image_ctx, {{"key", {}}}, 0);
expect_metadata_set(m_ioctx, mock_image_ctx, {{"key", {}}}, 0);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, 0);
MockMirrorEnableRequest mock_mirror_enable_request;
if (is_feature_enabled(RBD_FEATURE_JOURNALING)) {
@ -431,8 +439,8 @@ TEST_F(TestMockImageCloneRequest, SuccessV2) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {{"key", {}}}, 0);
expect_metadata_set(m_ioctx, mock_image_ctx, {{"key", {}}}, 0);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, 0);
MockMirrorEnableRequest mock_mirror_enable_request;
if (is_feature_enabled(RBD_FEATURE_JOURNALING)) {
@ -481,8 +489,8 @@ TEST_F(TestMockImageCloneRequest, SuccessAuto) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {{"key", {}}}, 0);
expect_metadata_set(m_ioctx, mock_image_ctx, {{"key", {}}}, 0);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, 0);
MockMirrorEnableRequest mock_mirror_enable_request;
if (is_feature_enabled(RBD_FEATURE_JOURNALING)) {
@ -662,7 +670,7 @@ TEST_F(TestMockImageCloneRequest, AttachChildError) {
ASSERT_EQ(-EINVAL, ctx.wait());
}
TEST_F(TestMockImageCloneRequest, MetadataListError) {
TEST_F(TestMockImageCloneRequest, MetadataCopyError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
@ -685,50 +693,8 @@ TEST_F(TestMockImageCloneRequest, MetadataListError) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {{"key", {}}}, -EINVAL);
expect_close(mock_image_ctx, 0);
MockRemoveRequest mock_remove_request;
expect_remove(mock_remove_request, 0);
expect_close(mock_image_ctx, 0);
C_SaferCond ctx;
ImageOptions clone_opts;
auto req = new MockCloneRequest(m_cct->_conf, m_ioctx, "parent id", "", {}, 123,
m_ioctx, "clone name", "clone id", clone_opts,
cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, "", "",
image_ctx->op_work_queue, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
}
TEST_F(TestMockImageCloneRequest, MetadataSetError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
expect_op_work_queue(mock_image_ctx);
InSequence seq;
expect_open(mock_image_ctx, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
MockCreateRequest mock_create_request;
expect_create(mock_create_request, 0);
expect_open(mock_image_ctx, 0);
MockAttachParentRequest mock_attach_parent_request;
expect_attach_parent(mock_attach_parent_request, 0);
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {{"key", {}}}, 0);
expect_metadata_set(m_ioctx, mock_image_ctx, {{"key", {}}}, -EINVAL);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, -EINVAL);
expect_close(mock_image_ctx, 0);
@ -770,7 +736,8 @@ TEST_F(TestMockImageCloneRequest, GetMirrorModeError) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {}, 0);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, 0);
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
expect_mirror_mode_get(mock_image_ctx, cls::rbd::MIRROR_MODE_POOL, -EINVAL);
@ -815,7 +782,8 @@ TEST_F(TestMockImageCloneRequest, MirrorEnableError) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {}, 0);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, 0);
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
expect_mirror_mode_get(mock_image_ctx, cls::rbd::MIRROR_MODE_POOL, 0);
@ -863,7 +831,9 @@ TEST_F(TestMockImageCloneRequest, CloseError) {
MockAttachChildRequest mock_attach_child_request;
expect_attach_child(mock_attach_child_request, 2, 0);
expect_metadata_list(mock_image_ctx, {}, 0);
MockMetadataCopyRequest mock_request;
expect_metadata_copy(mock_request, 0);
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, false);
expect_close(mock_image_ctx, -EINVAL);

View File

@ -14,6 +14,7 @@
#include "librbd/internal.h"
#include "librbd/Operations.h"
#include "librbd/api/Image.h"
#include "librbd/image/GetMetadataRequest.h"
#include "librbd/image/RefreshRequest.h"
#include "librbd/image/RefreshParentRequest.h"
#include "librbd/io/ImageDispatchSpec.h"
@ -36,6 +37,36 @@ struct MockRefreshImageCtx : public MockImageCtx {
namespace image {
template <>
struct GetMetadataRequest<MockRefreshImageCtx> {
std::string oid;
std::map<std::string, bufferlist>* pairs = nullptr;
Context* on_finish = nullptr;
static GetMetadataRequest* s_instance;
static GetMetadataRequest* create(librados::IoCtx&,
const std::string& oid,
const std::string& filter,
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_", last_key);
s_instance->oid = oid;
s_instance->pairs = pairs;
s_instance->on_finish = on_finish;
return s_instance;
}
GetMetadataRequest() {
s_instance = this;
}
MOCK_METHOD0(send, void());
};
template <>
struct RefreshParentRequest<MockRefreshImageCtx> {
static RefreshParentRequest* s_instance;
@ -66,6 +97,7 @@ struct RefreshParentRequest<MockRefreshImageCtx> {
MOCK_METHOD1(finalize, void(Context *));
};
GetMetadataRequest<MockRefreshImageCtx>* GetMetadataRequest<MockRefreshImageCtx>::s_instance = nullptr;
RefreshParentRequest<MockRefreshImageCtx>* RefreshParentRequest<MockRefreshImageCtx>::s_instance = nullptr;
} // namespace image
@ -132,9 +164,11 @@ using ::testing::StrEq;
class TestMockImageRefreshRequest : public TestMockFixture {
public:
typedef GetMetadataRequest<MockRefreshImageCtx> MockGetMetadataRequest;
typedef RefreshRequest<MockRefreshImageCtx> MockRefreshRequest;
typedef RefreshParentRequest<MockRefreshImageCtx> MockRefreshParentRequest;
typedef io::ImageDispatchSpec<librbd::MockRefreshImageCtx> MockIoImageDispatchSpec;
typedef std::map<std::string, bufferlist> Metadata;
void set_v1_migration_header(ImageCtx *ictx) {
bufferlist hdr;
@ -257,16 +291,17 @@ public:
}
}
void expect_get_metadata(MockRefreshImageCtx &mock_image_ctx, int r) {
auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("metadata_list"), _, _, _));
if (r < 0) {
expect.WillOnce(Return(r));
} else {
expect.WillOnce(DoDefault());
EXPECT_CALL(*mock_image_ctx.image_watcher, is_unregistered())
.WillOnce(Return(false));
}
void expect_get_metadata(MockRefreshImageCtx& mock_image_ctx,
MockGetMetadataRequest& mock_request,
const std::string& oid,
const Metadata& metadata, int r) {
EXPECT_CALL(mock_request, send())
.WillOnce(Invoke([&mock_image_ctx, &mock_request, oid, metadata, r]() {
ASSERT_EQ(oid, mock_request.oid);
*mock_request.pairs = metadata;
mock_image_ctx.image_ctx->op_work_queue->queue(
mock_request.on_finish, r);
}));
}
void expect_get_flags(MockRefreshImageCtx &mock_image_ctx, int r) {
@ -348,6 +383,8 @@ public:
void expect_apply_metadata(MockRefreshImageCtx &mock_image_ctx,
int r) {
EXPECT_CALL(*mock_image_ctx.image_watcher, is_unregistered())
.WillOnce(Return(false));
EXPECT_CALL(mock_image_ctx, apply_metadata(_, false))
.WillOnce(Return(r));
}
@ -544,7 +581,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessV2) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -575,7 +616,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_get_snapshots(mock_image_ctx, false, 0);
@ -609,7 +654,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessLegacySnapshotV2) {
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, -EOPNOTSUPP);
expect_get_parent_legacy(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_get_snapshots(mock_image_ctx, true, -EOPNOTSUPP);
@ -646,7 +695,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_get_snapshots(mock_image_ctx, false, 0);
@ -699,7 +752,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessChild) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx2->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_op_features(mock_image_ctx, RBD_OPERATION_FEATURE_CLONE_CHILD, 0);
expect_get_group(mock_image_ctx, 0);
@ -752,7 +809,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessChildDontOpenParent) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx2->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_op_features(mock_image_ctx, RBD_OPERATION_FEATURE_CLONE_CHILD, 0);
expect_get_group(mock_image_ctx, 0);
@ -784,7 +845,11 @@ TEST_F(TestMockImageRefreshRequest, SuccessOpFeatures) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, mock_image_ctx.features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_op_features(mock_image_ctx, 4096, 0);
expect_get_group(mock_image_ctx, 0);
@ -849,7 +914,11 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLock) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -899,7 +968,11 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLockWhileAcquiringLock) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -939,7 +1012,11 @@ TEST_F(TestMockImageRefreshRequest, JournalDisabledByPolicy) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -984,7 +1061,11 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithExclusiveLock) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1028,7 +1109,11 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1075,7 +1160,11 @@ TEST_F(TestMockImageRefreshRequest, DisableJournal) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1122,7 +1211,11 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithExclusiveLock) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1162,7 +1255,11 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithoutExclusiveLock) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1208,7 +1305,11 @@ TEST_F(TestMockImageRefreshRequest, DisableObjectMap) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1250,7 +1351,11 @@ TEST_F(TestMockImageRefreshRequest, OpenObjectMapError) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1294,7 +1399,11 @@ TEST_F(TestMockImageRefreshRequest, OpenObjectMapTooLarge) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@ -1324,7 +1433,11 @@ TEST_F(TestMockImageRefreshRequest, ApplyMetadataError) {
InSequence seq;
expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
expect_get_parent(mock_image_ctx, 0);
expect_get_metadata(mock_image_ctx, 0);
MockGetMetadataRequest mock_get_metadata_request;
expect_get_metadata(mock_image_ctx, mock_get_metadata_request,
mock_image_ctx.header_oid, {}, 0);
expect_get_metadata(mock_image_ctx, mock_get_metadata_request, RBD_INFO, {},
0);
expect_apply_metadata(mock_image_ctx, -EINVAL);
expect_get_group(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);