RBD_IMAGE_OPTION_DATA_POOL = 10,
RBD_IMAGE_OPTION_FLATTEN = 11,
RBD_IMAGE_OPTION_CLONE_FORMAT = 12,
+ RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE = 13,
};
typedef enum {
m_id_obj = util::id_obj_name(m_image_name);
m_header_obj = util::header_name(m_image_id);
m_objmap_name = ObjectMap<>::object_map_name(m_image_id, CEPH_NOSNAP);
- m_force_non_primary = !non_primary_global_image_id.empty();
+ if (!non_primary_global_image_id.empty() &&
+ (m_create_flags & CREATE_FLAG_MIRROR_ENABLE_MASK) == 0) {
+ m_create_flags |= CREATE_FLAG_FORCE_MIRROR_ENABLE;
+ }
if (image_options.get(RBD_IMAGE_OPTION_FEATURES, &m_features) != 0) {
m_features = librbd::rbd_features_from_string(
// only link to remote primary mirror uuid if in journal-based
// mirroring mode
bool use_primary_mirror_uuid = (
- m_force_non_primary &&
+ !m_non_primary_global_image_id.empty() &&
m_mirror_image_mode == cls::rbd::MIRROR_IMAGE_MODE_JOURNAL);
librbd::journal::TagData tag_data;
template<typename I>
void CreateRequest<I>::mirror_image_enable() {
- if (((m_mirror_mode != cls::rbd::MIRROR_MODE_POOL) && !m_force_non_primary) ||
- ((m_create_flags & CREATE_FLAG_MIRROR_ENABLE_MASK) ==
- CREATE_FLAG_SKIP_MIRROR_ENABLE)) {
+ auto mirror_enable_flag = (m_create_flags & CREATE_FLAG_MIRROR_ENABLE_MASK);
+
+ if ((m_mirror_mode != cls::rbd::MIRROR_MODE_POOL &&
+ mirror_enable_flag != CREATE_FLAG_FORCE_MIRROR_ENABLE) ||
+ (mirror_enable_flag == CREATE_FLAG_SKIP_MIRROR_ENABLE)) {
complete(0);
return;
}
CephContext *m_cct;
int m_r_saved = 0; // used to return actual error after cleanup
- bool m_force_non_primary;
file_layout_t m_layout;
std::string m_id_obj, m_header_obj, m_objmap_name;
{RBD_IMAGE_OPTION_DATA_POOL, STR},
{RBD_IMAGE_OPTION_FLATTEN, UINT64},
{RBD_IMAGE_OPTION_CLONE_FORMAT, UINT64},
+ {RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE, UINT64},
};
std::string image_option_name(int optname) {
return "flatten";
case RBD_IMAGE_OPTION_CLONE_FORMAT:
return "clone_format";
+ case RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE:
+ return "mirror_image_mode";
default:
return "unknown (" + stringify(optname) + ")";
}
api::Config<>::apply_pool_overrides(io_ctx, &config);
uint32_t create_flags = 0U;
+ uint64_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL;
if (skip_mirror_enable) {
create_flags = image::CREATE_FLAG_SKIP_MIRROR_ENABLE;
+ } else if (opts.get(RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE,
+ &mirror_image_mode) == 0) {
+ create_flags = image::CREATE_FLAG_FORCE_MIRROR_ENABLE;
}
C_SaferCond cond;
image::CreateRequest<> *req = image::CreateRequest<>::create(
config, io_ctx, image_name, id, size, opts, create_flags,
- cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, non_primary_global_image_id,
- primary_mirror_uuid, op_work_queue, &cond);
+ static_cast<cls::rbd::MirrorImageMode>(mirror_image_mode),
+ non_primary_global_image_id, primary_mirror_uuid, op_work_queue, &cond);
req->send();
r = cond.wait();
auto ctx = create_context_callback<
EnableRequest<I>, &EnableRequest<I>::handle_open_image>(this);
- m_image_ctx->state->open(OPEN_FLAG_SKIP_OPEN_PARENT, ctx);
+ m_image_ctx->state->open(OPEN_FLAG_SKIP_OPEN_PARENT |
+ OPEN_FLAG_IGNORE_MIGRATING, ctx);
}
template <typename I>
ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_DISABLED));
}
+TEST_F(TestLibRBD, CreateWithMirrorEnabled) {
+ REQUIRE_FORMAT_V2();
+
+ librados::IoCtx ioctx;
+ ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+ librbd::RBD rbd;
+ ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE));
+
+ librbd::ImageOptions image_options;
+ ASSERT_EQ(0, image_options.set(
+ RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE,
+ static_cast<uint64_t>(RBD_MIRROR_IMAGE_MODE_SNAPSHOT)));
+
+ std::string image_name = get_temp_image_name();
+ ASSERT_EQ(0, rbd.create4(ioctx, image_name.c_str(), 2<<20, image_options));
+
+ librbd::Image image;
+ ASSERT_EQ(0, rbd.open(ioctx, image, image_name.c_str(), NULL));
+
+ librbd::mirror_image_mode_t mirror_image_mode;
+ ASSERT_EQ(0, image.mirror_image_get_mode(&mirror_image_mode));
+ ASSERT_EQ(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mirror_image_mode);
+
+ ASSERT_EQ(0, image.mirror_image_disable(true));
+ ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_DISABLED));
+}
+
TEST_F(TestLibRBD, FlushCacheWithCopyupOnExternalSnapshot) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);