compare_images ${POOL} ${i}
done
-testlog "TEST: remove mirroring pool"
-pool=pool_to_remove
-for cluster in ${CLUSTER1} ${CLUSTER2}; do
- CEPH_ARGS='' ceph --cluster ${cluster} osd pool create ${pool} 16 16
- CEPH_ARGS='' rbd --cluster ${cluster} pool init ${pool}
- rbd --cluster ${cluster} mirror pool enable ${pool} pool
-done
-rbd --cluster ${CLUSTER1} mirror pool peer add ${pool} ${CLUSTER2}
-rbd --cluster ${CLUSTER2} mirror pool peer add ${pool} ${CLUSTER1}
-rdp_image=test_remove_data_pool
-create_image ${CLUSTER2} ${pool} ${image} 128
-create_image ${CLUSTER2} ${POOL} ${rdp_image} 128 --data-pool ${pool}
-write_image ${CLUSTER2} ${pool} ${image} 100
-write_image ${CLUSTER2} ${POOL} ${rdp_image} 100
-wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${pool} ${image}
-wait_for_status_in_pool_dir ${CLUSTER1} ${pool} ${image} 'up+replaying' 'master_position'
-wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${rdp_image}
-wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${rdp_image} 'up+replaying' 'master_position'
-for cluster in ${CLUSTER1} ${CLUSTER2}; do
- CEPH_ARGS='' ceph --cluster ${cluster} osd pool rm ${pool} ${pool} --yes-i-really-really-mean-it
-done
-remove_image_retry ${CLUSTER2} ${POOL} ${rdp_image}
-wait_for_image_present ${CLUSTER1} ${POOL} ${rdp_image} 'deleted'
-for i in 0 1 2 4 8 8 8 8 16 16; do
- sleep $i
- admin_daemons "${CLUSTER2}" rbd mirror status ${pool}/${image} || break
-done
-admin_daemons "${CLUSTER2}" rbd mirror status ${pool}/${image} && false
-
testlog "TEST: snapshot rename"
snap_name='snap_rename'
create_snapshot ${CLUSTER2} ${POOL} ${image2} "${snap_name}_0"
~IoCtx();
- bool is_valid() const;
-
// Close our pool handle
void close();
close();
}
-bool librados::IoCtx::is_valid() const {
- return io_ctx_impl != nullptr;
-}
-
void librados::IoCtx::close()
{
if (io_ctx_impl)
template <typename I>
void DeepCopyRequest<I>::send() {
- if (!m_src_image_ctx->data_ctx.is_valid()) {
- lderr(m_cct) << "missing data pool for source image" << dendl;
- finish(-ENODEV);
- return;
- }
-
- if (!m_dst_image_ctx->data_ctx.is_valid()) {
- lderr(m_cct) << "missing data pool for destination image" << dendl;
- finish(-ENODEV);
- return;
- }
-
int r = validate_copy_points();
if (r < 0) {
finish(r);
delete[] format_string;
md_ctx.aio_flush();
- if (data_ctx.is_valid()) {
- data_ctx.aio_flush();
- }
+ data_ctx.aio_flush();
io_work_queue->drain();
delete io_object_dispatcher;
asok_hook = new LibrbdAdminSocketHook(this);
string pname = string("librbd-") + id + string("-") +
- md_ctx.get_pool_name() + string("-") + name;
+ data_ctx.get_pool_name() + string("-") + name;
if (!snap_name.empty()) {
pname += "-";
pname += snap_name;
asok_hook = nullptr;
}
- void ImageCtx::init_layout(int64_t pool_id)
+ void ImageCtx::init_layout()
{
if (stripe_unit == 0 || stripe_count == 0) {
stripe_unit = 1ull << order;
layout.stripe_unit = stripe_unit;
layout.stripe_count = stripe_count;
layout.object_size = 1ull << order;
- layout.pool_id = pool_id; // FIXME: pool id overflow?
+ layout.pool_id = data_ctx.get_id(); // FIXME: pool id overflow?
delete[] format_string;
size_t len = object_prefix.length() + 16;
snap_namespace = it->second.snap_namespace;
snap_name = it->second.name;
snap_exists = true;
- if (data_ctx.is_valid()) {
- data_ctx.snap_set_read(snap_id);
- }
+ data_ctx.snap_set_read(snap_id);
return 0;
}
return -ENOENT;
snap_namespace = {};
snap_name = "";
snap_exists = true;
- if (data_ctx.is_valid()) {
- data_ctx.snap_set_read(snap_id);
- }
+ data_ctx.snap_set_read(snap_id);
}
snap_t ImageCtx::get_snap_id(const cls::rbd::SnapshotNamespace& in_snap_namespace,
~ImageCtx();
void init();
void shutdown();
- void init_layout(int64_t pool_id);
+ void init_layout();
void perf_start(std::string name);
void perf_stop();
void set_read_flag(unsigned flag);
ldout(ictx->cct, 20) << "diff_iterate " << ictx << " off = " << off
<< " len = " << len << dendl;
- if (!ictx->data_ctx.is_valid()) {
- return -ENODEV;
- }
-
// ensure previous writes are visible to listsnaps
C_SaferCond flush_ctx;
{
int DiffIterate<I>::execute() {
CephContext* cct = m_image_ctx.cct;
- ceph_assert(m_image_ctx.data_ctx.is_valid());
-
librados::IoCtx head_ctx;
librados::snap_t from_snap_id = 0;
librados::snap_t end_snap_id;
} // anonymous namespace
-template <typename I>
-int64_t Image<I>::get_data_pool_id(I *ictx) {
- if (ictx->data_ctx.is_valid()) {
- return ictx->data_ctx.get_id();
- }
-
- int64_t pool_id;
- int r = cls_client::get_data_pool(&ictx->md_ctx, ictx->header_oid, &pool_id);
- if (r < 0) {
- CephContext *cct = ictx->cct;
- lderr(cct) << "error getting data pool ID: " << cpp_strerror(r) << dendl;
- return r;
- }
-
- return pool_id;
-}
-
template <typename I>
int Image<I>::get_op_features(I *ictx, uint64_t *op_features) {
CephContext *cct = ictx->cct;
struct Image {
typedef std::map<std::string, std::string> ImageNameToIds;
- static int64_t get_data_pool_id(ImageCtxT *ictx);
-
static int get_op_features(ImageCtxT *ictx, uint64_t *op_features);
static int list_images(librados::IoCtx& io_ctx,
return -ENOENT;
}
- GetGroupVisitor ggv = GetGroupVisitor(ictx->cct, &ictx->md_ctx, group_snap);
+ GetGroupVisitor ggv = GetGroupVisitor(ictx->cct, &ictx->data_ctx, group_snap);
r = boost::apply_visitor(ggv, snap_info->snap_namespace);
if (r < 0) {
return r;
: m_image_ctx(image_ctx),
m_cache_lock(util::unique_lock_name(
"librbd::cache::ObjectCacherObjectDispatch::cache_lock", this)) {
- ceph_assert(m_image_ctx->data_ctx.is_valid());
}
template <typename I>
m_dst_image_ctx(dst_image_ctx), m_cct(dst_image_ctx->cct),
m_snap_map(snap_map), m_dst_object_number(dst_object_number),
m_flatten(flatten), m_on_finish(on_finish) {
- ceph_assert(src_image_ctx->data_ctx.is_valid());
- ceph_assert(dst_image_ctx->data_ctx.is_valid());
ceph_assert(!m_snap_map.empty());
m_src_async_op = new io::AsyncOperation();
*result = util::create_ioctx(m_image_ctx->md_ctx, "data pool", data_pool_id,
{}, &m_image_ctx->data_ctx);
if (*result < 0) {
- if (*result != -ENOENT) {
- send_close_image(*result);
- return nullptr;
- }
- m_image_ctx->data_ctx.close();
- } else {
- m_image_ctx->data_ctx.set_namespace(m_image_ctx->md_ctx.get_namespace());
+ send_close_image(*result);
+ return nullptr;
}
- } else {
- data_pool_id = m_image_ctx->md_ctx.get_id();
+ m_image_ctx->data_ctx.set_namespace(m_image_ctx->md_ctx.get_namespace());
}
- m_image_ctx->init_layout(data_pool_id);
+ m_image_ctx->init_layout();
send_refresh();
return nullptr;
}
template <typename I>
Context *OpenRequest<I>::send_init_cache(int *result) {
// cache is disabled or parent image context
- if (!m_image_ctx->cache || m_image_ctx->child != nullptr ||
- !m_image_ctx->data_ctx.is_valid()) {
+ if (!m_image_ctx->cache || m_image_ctx->child != nullptr) {
return send_register_watch(result);
}
m_image_ctx.op_features = 0;
m_image_ctx.operations_disabled = false;
m_image_ctx.object_prefix = std::move(m_object_prefix);
- m_image_ctx.init_layout(m_image_ctx.md_ctx.get_id());
+ m_image_ctx.init_layout();
} else {
// HEAD revision doesn't have a defined overlap so it's only
// applicable to snapshots
if (m_refresh_parent != nullptr) {
m_refresh_parent->apply();
}
- if (m_image_ctx.data_ctx.is_valid()) {
- m_image_ctx.data_ctx.selfmanaged_snap_set_write_ctx(m_image_ctx.snapc.seq,
- m_image_ctx.snaps);
- }
+ m_image_ctx.data_ctx.selfmanaged_snap_set_write_ctx(m_image_ctx.snapc.seq,
+ m_image_ctx.snaps);
// handle dynamically enabled / disabled features
if (m_image_ctx.exclusive_lock != nullptr &&
return;
}
- if (!m_image_ctx->data_ctx.is_valid()) {
- detach_child();
- return;
- }
-
trim_image();
}
* PRE REMOVE IMAGE * * * |
* | * |
* v * |
- * (skip if invalid data pool) TRIM IMAGE * * * * * |
+ * TRIM IMAGE * * * * * |
* | * |
* v * |
* DETACH CHILD * |
m_trace(util::create_trace(*m_image_ctx, "copy-up", parent_trace)),
m_lock("CopyupRequest", false, false)
{
- ceph_assert(m_image_ctx->data_ctx.is_valid());
m_async_op.start_op(*util::get_image_ctx(m_image_ctx));
}
return false;
}
- if (!m_image_ctx.data_ctx.is_valid()) {
- CephContext *cct = m_image_ctx.cct;
- lderr(cct) << "missing data pool" << dendl;
-
- c->get();
- c->fail(-ENODEV);
- return false;
- }
-
m_in_flight_ios++;
return true;
}
: m_ictx(ictx), m_oid(oid), m_object_no(objectno), m_object_off(off),
m_object_len(len), m_snap_id(snap_id), m_completion(completion),
m_trace(util::create_trace(*ictx, "", trace)) {
- ceph_assert(m_ictx->data_ctx.is_valid());
if (m_trace.valid()) {
m_trace.copy_name(trace_name + std::string(" ") + oid);
m_trace.event("start");
int64_t Image::get_data_pool_id()
{
ImageCtx *ictx = reinterpret_cast<ImageCtx *>(ctx);
- return librbd::api::Image<>::get_data_pool_id(ictx);
+ return ictx->data_ctx.get_id();
}
int Image::parent_info(string *parent_pool_name, string *parent_name,
extern "C" int64_t rbd_get_data_pool_id(rbd_image_t image)
{
librbd::ImageCtx *ictx = reinterpret_cast<librbd::ImageCtx *>(image);
- return librbd::api::Image<>::get_data_pool_id(ictx);
+ return ictx->data_ctx.get_id();
}
extern "C" int rbd_get_parent_info(rbd_image_t image,
template <typename I>
void ObjectMapIterateRequest<I>::send() {
- if (!m_image_ctx.data_ctx.is_valid()) {
- this->async_complete(-ENODEV);
- return;
- }
-
send_verify_objects();
}
bool ObjectMapIterateRequest<I>::should_complete(int r) {
CephContext *cct = m_image_ctx.cct;
ldout(cct, 5) << this << " should_complete: " << " r=" << r << dendl;
-
- if (r == -ENODEV) {
- lderr(cct) << "missing data pool" << dendl;
- return true;
- }
-
if (r < 0) {
lderr(cct) << "object map operation encountered an error: "
<< cpp_strerror(r) << dendl;
template <typename I>
void SnapshotCreateRequest<I>::send_op() {
- I &image_ctx = this->m_image_ctx;
- CephContext *cct = image_ctx.cct;
-
- if (!image_ctx.data_ctx.is_valid()) {
- lderr(cct) << "missing data pool" << dendl;
- this->async_complete(-ENODEV);
- return;
- }
-
send_suspend_requests();
}
void SnapshotRemoveRequest<I>::release_snap_id() {
I &image_ctx = this->m_image_ctx;
- if (!image_ctx.data_ctx.is_valid()) {
- remove_snap();
- return;
- }
-
CephContext *cct = image_ctx.cct;
ldout(cct, 5) << "snap_name=" << m_snap_name << ", "
<< "snap_id=" << m_snap_id << dendl;
ldout(m_cct, 20) << dendl;
- if (!image_ctx.data_ctx.is_valid()) {
- lderr(m_cct) << "missing data pool" << dendl;
- return -ENODEV;
- }
-
if (image_ctx.exclusive_lock != nullptr &&
!image_ctx.exclusive_lock->is_lock_owner()) {
ldout(m_cct, 1) << "lost exclusive lock during sparsify" << dendl;
template <typename I>
void TrimRequest<I>::send() {
- I &image_ctx = this->m_image_ctx;
- CephContext *cct = image_ctx.cct;
-
- if (!image_ctx.data_ctx.is_valid()) {
- lderr(cct) << "missing data pool" << dendl;
- send_finish(-ENODEV);
- return;
- }
-
send_pre_trim();
}
}
void expect_init_layout(MockRefreshImageCtx &mock_image_ctx) {
- EXPECT_CALL(mock_image_ctx, init_layout(_));
+ EXPECT_CALL(mock_image_ctx, init_layout());
}
void expect_test_features(MockRefreshImageCtx &mock_image_ctx) {
ctx.wait();
}
- MOCK_METHOD1(init_layout, void(int64_t));
+ MOCK_METHOD0(init_layout, void());
MOCK_CONST_METHOD1(get_object_name, std::string(uint64_t));
MOCK_CONST_METHOD0(get_object_size, uint64_t());
ASSERT_EQ(0, ictx->data_ctx.stat(oid, &size, NULL));
ASSERT_EQ(0, ictx->data_ctx.read(oid, read_bl, 4096, 0));
}
-
-TEST_F(TestInternal, MissingDataPool) {
- REQUIRE_FORMAT_V2();
-
- librbd::ImageCtx *ictx;
- ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_EQ(0, snap_create(*ictx, "snap1"));
- std::string header_oid = ictx->header_oid;
- close_image(ictx);
-
- // emulate non-existent data pool
- int64_t pool_id = 1234;
- std::string pool_name;
- int r;
- while ((r = _rados.pool_reverse_lookup(pool_id, &pool_name)) == 0) {
- pool_id++;
- }
- ASSERT_EQ(r, -ENOENT);
- bufferlist bl;
- using ceph::encode;
- encode(pool_id, bl);
- ASSERT_EQ(0, m_ioctx.omap_set(header_oid, {{"data_pool_id", bl}}));
-
- ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
- ASSERT_FALSE(ictx->data_ctx.is_valid());
- ASSERT_EQ(pool_id, librbd::api::Image<>::get_data_pool_id(ictx));
-
- librbd::image_info_t info;
- ASSERT_EQ(0, librbd::info(ictx, info, sizeof(info)));
-
- vector<librbd::snap_info_t> snaps;
- EXPECT_EQ(0, librbd::snap_list(ictx, snaps));
- EXPECT_EQ(1U, snaps.size());
- EXPECT_EQ("snap1", snaps[0].name);
-
- bufferptr read_ptr(256);
- bufferlist read_bl;
- read_bl.push_back(read_ptr);
- librbd::io::ReadResult read_result{&read_bl};
- ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->read(0, 256,
- librbd::io::ReadResult{read_result}, 0));
- ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->write(0, bl.length(), bufferlist{bl}, 0));
- ASSERT_EQ(-ENODEV, ictx->io_work_queue->discard(0, 1, 256));
- ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->writesame(0, bl.length(), bufferlist{bl}, 0));
- uint64_t mismatch_off;
- ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->compare_and_write(0, bl.length(),
- bufferlist{bl},
- bufferlist{bl},
- &mismatch_off, 0));
- ASSERT_EQ(-ENODEV, ictx->io_work_queue->flush());
-
- ASSERT_EQ(-ENODEV, snap_create(*ictx, "snap2"));
- ASSERT_EQ(0, ictx->operations->snap_remove(cls::rbd::UserSnapshotNamespace(),
- "snap1"));
-
- librbd::NoOpProgressContext no_op;
- ASSERT_EQ(-ENODEV, ictx->operations->resize(0, true, no_op));
-
- close_image(ictx);
-
- ASSERT_EQ(0, librbd::api::Image<>::remove(m_ioctx, m_image_name, no_op));
-
- ASSERT_EQ(0, create_image_pp(m_rbd, m_ioctx, m_image_name, m_image_size));
-}