#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/Journal.h"
+#include "librbd/Operations.h"
#include "librbd/Utils.h"
#include "librbd/api/Image.h"
#include "librbd/mirror/DemoteRequest.h"
}
}
- if ((ictx->features & RBD_FEATURE_JOURNALING) == 0) {
- lderr(cct) << "cannot enable mirroring: journaling is not enabled" << dendl;
- return -EINVAL;
+ if (!ictx->test_features(RBD_FEATURE_JOURNALING)) {
+ uint64_t features = RBD_FEATURE_JOURNALING;
+ if (!ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
+ features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+ }
+ r = ictx->operations->update_features(features, true);
+ if (r < 0) {
+ lderr(cct) << "cannot enable journaling: " << cpp_strerror(r) << dendl;
+ return r;
+ }
}
C_SaferCond ctx;
rollback = true;
return r;
}
+
+ r = ictx->operations->update_features(RBD_FEATURE_JOURNALING, false);
+ if (r < 0) {
+ lderr(cct) << "cannot disable journaling: " << cpp_strerror(r) << dendl;
+ // not fatal
+ }
}
return 0;
ASSERT_EQ(mirror_state == RBD_MIRROR_IMAGE_ENABLED ? -ENOENT : -EINVAL,
image.mirror_image_get_instance_id(&instance_id));
+ if (mirror_mode == RBD_MIRROR_MODE_IMAGE &&
+ mirror_state == RBD_MIRROR_IMAGE_DISABLED) {
+ // disabling image mirroring automatically disables journaling feature
+ uint64_t new_features;
+ ASSERT_EQ(0, image.features(&new_features));
+ ASSERT_EQ(0, new_features & RBD_FEATURE_JOURNALING);
+ }
+
ASSERT_EQ(0, image.close());
ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
RBD_MIRROR_IMAGE_DISABLED);
}
+TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeImage_NoObjectMap) {
+ uint64_t features = 0;
+ features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+ features |= RBD_FEATURE_JOURNALING;
+ check_mirror_image_disable(RBD_MIRROR_MODE_IMAGE, features, 0,
+ RBD_MIRROR_IMAGE_DISABLED);
+}
+
TEST_F(TestMirroring, DisableImageMirror_In_MirrorModePool) {
uint64_t features = 0;
features |= RBD_FEATURE_OBJECT_MAP;
ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
}
-TEST_F(TestMirroring, EnableImageMirror_WithoutJournaling) {
+TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled_WithoutJournaling) {
uint64_t features = 0;
features |= RBD_FEATURE_OBJECT_MAP;
features |= RBD_FEATURE_EXCLUSIVE_LOCK;
RBD_MIRROR_IMAGE_DISABLED);
}
+TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool_WithoutJournaling) {
+ uint64_t features = 0;
+ features |= RBD_FEATURE_OBJECT_MAP;
+ features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+ check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
+ RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutJournaling) {
+ uint64_t features = 0;
+ features |= RBD_FEATURE_OBJECT_MAP;
+ features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+ check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
+ RBD_MIRROR_IMAGE_ENABLED);
+}
+
+TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutExclusiveLock) {
+ uint64_t features = 0;
+ check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
+ RBD_MIRROR_IMAGE_ENABLED);
+}
+
TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) {
uint64_t features = 0;
features |= RBD_FEATURE_OBJECT_MAP;