librados::ObjectReadOperation op;
for (auto snap_id : m_snapc.snaps) {
- if (m_legacy_snapshot) {
+ if (m_legacy_snapshot != LEGACY_SNAPSHOT_DISABLED) {
/// NOTE: remove after Luminous is retired
cls_client::get_snapshot_name_start(&op, snap_id);
cls_client::get_size_start(&op, snap_id);
- cls_client::get_snapshot_timestamp_start(&op, snap_id);
+ if (m_legacy_snapshot != LEGACY_SNAPSHOT_ENABLED_NO_TIMESTAMP) {
+ cls_client::get_snapshot_timestamp_start(&op, snap_id);
+ }
} else {
cls_client::snapshot_get_start(&op, snap_id);
}
auto it = m_out_bl.cbegin();
for (size_t i = 0; i < m_snapc.snaps.size(); ++i) {
- if (m_legacy_snapshot) {
+ if (m_legacy_snapshot != LEGACY_SNAPSHOT_DISABLED) {
/// NOTE: remove after Luminous is retired
std::string snap_name;
if (*result >= 0) {
}
utime_t snap_timestamp;
- if (*result >= 0) {
+ if (*result >= 0 &&
+ m_legacy_snapshot != LEGACY_SNAPSHOT_ENABLED_NO_TIMESTAMP) {
+ /// NOTE: remove after Jewel is retired
*result = cls_client::get_snapshot_timestamp_finish(&it,
&snap_timestamp);
}
ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
send_v2_get_mutable_metadata();
return nullptr;
- } else if (!m_legacy_snapshot && *result == -EOPNOTSUPP) {
+ } else if (m_legacy_snapshot == LEGACY_SNAPSHOT_DISABLED &&
+ *result == -EOPNOTSUPP) {
ldout(cct, 10) << "retrying using legacy snapshot methods" << dendl;
- m_legacy_snapshot = true;
+ m_legacy_snapshot = LEGACY_SNAPSHOT_ENABLED;
+ send_v2_get_snapshots();
+ return nullptr;
+ } else if (m_legacy_snapshot == LEGACY_SNAPSHOT_ENABLED &&
+ *result == -EOPNOTSUPP) {
+ ldout(cct, 10) << "retrying using legacy snapshot methods (jewel)" << dendl;
+ m_legacy_snapshot = LEGACY_SNAPSHOT_ENABLED_NO_TIMESTAMP;
send_v2_get_snapshots();
return nullptr;
} else if (*result < 0) {
}
}
- void expect_get_snapshots_legacy(MockRefreshImageCtx &mock_image_ctx, int r) {
+ void expect_get_snapshots_legacy(MockRefreshImageCtx &mock_image_ctx,
+ bool include_timestamp, int r) {
auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_name"), _, _, _));
if (r < 0) {
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _))
.WillOnce(DoDefault());
- EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
- exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_timestamp"), _, _, _))
- .WillOnce(DoDefault());
+ if (include_timestamp) {
+ EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
+ exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_timestamp"), _, _, _))
+ .WillOnce(DoDefault());
+ }
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
.WillOnce(DoDefault());
expect_apply_metadata(mock_image_ctx, 0);
expect_get_group(mock_image_ctx, 0);
expect_get_snapshots(mock_image_ctx, true, -EOPNOTSUPP);
- expect_get_snapshots_legacy(mock_image_ctx, 0);
+ expect_get_snapshots_legacy(mock_image_ctx, true, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
ASSERT_EQ(0, ctx.wait());
}
+TEST_F(TestMockImageRefreshRequest, SuccessLegacySnapshotNoTimestampV2) {
+ REQUIRE_FORMAT_V2();
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+ ASSERT_EQ(0, snap_create(*ictx, "snap"));
+
+ MockRefreshImageCtx mock_image_ctx(*ictx);
+ MockRefreshParentRequest mock_refresh_parent_request;
+ MockExclusiveLock mock_exclusive_lock;
+ expect_op_work_queue(mock_image_ctx);
+ expect_test_features(mock_image_ctx);
+
+ InSequence seq;
+ 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);
+ 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);
+ expect_get_snapshots_legacy(mock_image_ctx, true, -EOPNOTSUPP);
+ expect_get_snapshots_legacy(mock_image_ctx, false, 0);
+ expect_refresh_parent_is_required(mock_refresh_parent_request, false);
+ if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
+ expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
+ }
+ expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
+
+ C_SaferCond ctx;
+ MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
+ req->send();
+
+ ASSERT_EQ(0, ctx.wait());
+}
+
+
TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
REQUIRE_FORMAT_V2();