1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2016 SUSE LINUX GmbH
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
14 #include "test/librbd/test_fixture.h"
15 #include "test/librbd/test_support.h"
16 #include "librbd/ExclusiveLock.h"
17 #include "librbd/ImageState.h"
18 #include "librbd/ImageWatcher.h"
19 #include "librbd/internal.h"
20 #include "librbd/ObjectMap.h"
21 #include "librbd/Operations.h"
22 #include "librbd/io/AioCompletion.h"
23 #include "librbd/io/ImageRequest.h"
24 #include "librbd/io/ImageRequestWQ.h"
25 #include "librbd/journal/Types.h"
26 #include "journal/Journaler.h"
27 #include "journal/Settings.h"
28 #include <boost/scope_exit.hpp>
29 #include <boost/assign/list_of.hpp>
33 void register_test_mirroring() {
36 class TestMirroring : public TestFixture {
42 void TearDown() override {
45 TestFixture::TearDown();
48 void SetUp() override {
49 ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), m_ioctx));
52 std::string image_name = "mirrorimg1";
54 void check_mirror_image_enable(rbd_mirror_mode_t mirror_mode,
57 rbd_mirror_image_state_t mirror_state) {
59 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
62 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
64 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
66 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
68 ASSERT_EQ(expected_r, image.mirror_image_enable());
70 librbd::mirror_image_info_t mirror_image;
71 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
72 ASSERT_EQ(mirror_state, mirror_image.state);
74 librbd::mirror_image_status_t status;
75 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
76 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
78 ASSERT_EQ(0, image.close());
79 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
80 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
83 void check_mirror_image_disable(rbd_mirror_mode_t mirror_mode,
86 rbd_mirror_image_state_t mirror_state) {
88 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
91 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
93 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
95 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
97 ASSERT_EQ(expected_r, image.mirror_image_disable(false));
99 librbd::mirror_image_info_t mirror_image;
100 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
101 ASSERT_EQ(mirror_state, mirror_image.state);
103 librbd::mirror_image_status_t status;
104 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
105 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
107 ASSERT_EQ(0, image.close());
108 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
109 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
112 void check_mirroring_status(size_t *images_count) {
113 std::map<std::string, librbd::mirror_image_status_t> images;
114 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, "", 4096, &images));
116 std::map<librbd::mirror_image_status_state_t, int> states;
117 ASSERT_EQ(0, m_rbd.mirror_image_status_summary(m_ioctx, &states));
118 size_t states_count = 0;
119 for (auto &s : states) {
120 states_count += s.second;
122 ASSERT_EQ(images.size(), states_count);
124 *images_count = images.size();
127 void check_mirroring_on_create(uint64_t features,
128 rbd_mirror_mode_t mirror_mode,
129 rbd_mirror_image_state_t mirror_state) {
131 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
133 size_t mirror_images_count = 0;
134 check_mirroring_status(&mirror_images_count);
137 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
139 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
141 librbd::mirror_image_info_t mirror_image;
142 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
143 ASSERT_EQ(mirror_state, mirror_image.state);
145 librbd::mirror_image_status_t status;
146 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
147 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
149 size_t mirror_images_new_count = 0;
150 check_mirroring_status(&mirror_images_new_count);
151 if (mirror_mode == RBD_MIRROR_MODE_POOL &&
152 mirror_state == RBD_MIRROR_IMAGE_ENABLED) {
153 ASSERT_EQ(mirror_images_new_count, mirror_images_count + 1);
155 ASSERT_EQ(mirror_images_new_count, mirror_images_count);
158 ASSERT_EQ(0, image.close());
159 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
160 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
162 check_mirroring_status(&mirror_images_new_count);
163 ASSERT_EQ(mirror_images_new_count, mirror_images_count);
166 void check_mirroring_on_update_features(uint64_t init_features,
167 bool enable, bool enable_mirroring,
168 uint64_t features, int expected_r,
169 rbd_mirror_mode_t mirror_mode,
170 rbd_mirror_image_state_t mirror_state) {
172 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
175 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, init_features, &order));
177 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
179 if (enable_mirroring) {
180 ASSERT_EQ(0, image.mirror_image_enable());
183 ASSERT_EQ(expected_r, image.update_features(features, enable));
185 librbd::mirror_image_info_t mirror_image;
186 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
187 ASSERT_EQ(mirror_state, mirror_image.state);
189 librbd::mirror_image_status_t status;
190 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
191 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
193 ASSERT_EQ(0, image.close());
194 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
195 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
198 void setup_images_with_mirror_mode(rbd_mirror_mode_t mirror_mode,
199 std::vector<uint64_t>& features_vec) {
201 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
205 for (const auto& features : features_vec) {
206 std::stringstream img_name("img_");
208 std::string img_name_str = img_name.str();
209 ASSERT_EQ(0, m_rbd.create2(m_ioctx, img_name_str.c_str(), 2048, features, &order));
213 void check_mirroring_on_mirror_mode_set(rbd_mirror_mode_t mirror_mode,
214 std::vector<rbd_mirror_image_state_t>& states_vec) {
216 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
218 std::vector< std::tuple<std::string, rbd_mirror_image_state_t> > images;
220 for (const auto& mirror_state : states_vec) {
221 std::stringstream img_name("img_");
223 std::string img_name_str = img_name.str();
225 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, img_name_str.c_str()));
226 images.push_back(std::make_tuple(img_name_str, mirror_state));
228 librbd::mirror_image_info_t mirror_image;
229 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
230 ASSERT_EQ(mirror_state, mirror_image.state);
232 librbd::mirror_image_status_t status;
233 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
234 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
236 ASSERT_EQ(0, image.close());
237 ASSERT_EQ(0, m_rbd.remove(m_ioctx, img_name_str.c_str()));
241 void check_remove_image(rbd_mirror_mode_t mirror_mode, uint64_t features,
242 bool enable_mirroring, bool demote = false) {
244 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
247 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
250 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
252 if (enable_mirroring) {
253 ASSERT_EQ(0, image.mirror_image_enable());
257 ASSERT_EQ(0, image.mirror_image_demote());
258 ASSERT_EQ(0, image.mirror_image_disable(true));
262 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
263 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
266 void setup_mirror_peer(librados::IoCtx &io_ctx, librbd::Image &image) {
267 ASSERT_EQ(0, image.snap_create("sync-point-snap"));
269 std::string image_id;
270 ASSERT_EQ(0, get_image_id(image, &image_id));
272 librbd::journal::MirrorPeerClientMeta peer_client_meta(
273 "remote-image-id", {{{}, "sync-point-snap", boost::none}}, {});
274 librbd::journal::ClientData client_data(peer_client_meta);
276 journal::Journaler journaler(io_ctx, image_id, "peer-client", {});
277 C_SaferCond init_ctx;
278 journaler.init(&init_ctx);
279 ASSERT_EQ(-ENOENT, init_ctx.wait());
281 bufferlist client_data_bl;
282 ::encode(client_data, client_data_bl);
283 ASSERT_EQ(0, journaler.register_client(client_data_bl));
285 C_SaferCond shut_down_ctx;
286 journaler.shut_down(&shut_down_ctx);
287 ASSERT_EQ(0, shut_down_ctx.wait());
292 TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage) {
293 uint64_t features = 0;
294 features |= RBD_FEATURE_OBJECT_MAP;
295 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
296 features |= RBD_FEATURE_JOURNALING;
297 check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
298 RBD_MIRROR_IMAGE_ENABLED);
301 TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) {
302 uint64_t features = 0;
303 features |= RBD_FEATURE_OBJECT_MAP;
304 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
305 features |= RBD_FEATURE_JOURNALING;
306 check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
307 RBD_MIRROR_IMAGE_ENABLED);
310 TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled) {
311 uint64_t features = 0;
312 features |= RBD_FEATURE_OBJECT_MAP;
313 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
314 features |= RBD_FEATURE_JOURNALING;
315 check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL,
316 RBD_MIRROR_IMAGE_DISABLED);
319 TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeImage) {
320 uint64_t features = 0;
321 features |= RBD_FEATURE_OBJECT_MAP;
322 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
323 features |= RBD_FEATURE_JOURNALING;
324 check_mirror_image_disable(RBD_MIRROR_MODE_IMAGE, features, 0,
325 RBD_MIRROR_IMAGE_DISABLED);
328 TEST_F(TestMirroring, DisableImageMirror_In_MirrorModePool) {
329 uint64_t features = 0;
330 features |= RBD_FEATURE_OBJECT_MAP;
331 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
332 features |= RBD_FEATURE_JOURNALING;
333 check_mirror_image_disable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
334 RBD_MIRROR_IMAGE_ENABLED);
337 TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeDisabled) {
338 uint64_t features = 0;
339 features |= RBD_FEATURE_OBJECT_MAP;
340 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
341 features |= RBD_FEATURE_JOURNALING;
342 check_mirror_image_disable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL,
343 RBD_MIRROR_IMAGE_DISABLED);
346 TEST_F(TestMirroring, DisableImageMirrorWithPeer) {
347 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
349 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
351 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
353 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
357 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
358 ASSERT_EQ(0, image.mirror_image_enable());
360 setup_mirror_peer(m_ioctx, image);
362 ASSERT_EQ(0, image.mirror_image_disable(false));
364 std::vector<librbd::snap_info_t> snaps;
365 ASSERT_EQ(0, image.snap_list(snaps));
366 ASSERT_TRUE(snaps.empty());
368 librbd::mirror_image_info_t mirror_image;
369 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
370 sizeof(mirror_image)));
371 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, mirror_image.state);
373 librbd::mirror_image_status_t status;
374 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
375 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
377 ASSERT_EQ(0, image.close());
378 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
379 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
382 TEST_F(TestMirroring, DisableJournalingWithPeer) {
383 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
385 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
387 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
389 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
393 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
395 setup_mirror_peer(m_ioctx, image);
397 ASSERT_EQ(0, image.update_features(RBD_FEATURE_JOURNALING, false));
399 std::vector<librbd::snap_info_t> snaps;
400 ASSERT_EQ(0, image.snap_list(snaps));
401 ASSERT_TRUE(snaps.empty());
403 librbd::mirror_image_info_t mirror_image;
404 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
405 sizeof(mirror_image)));
406 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, mirror_image.state);
408 librbd::mirror_image_status_t status;
409 ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status)));
410 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
412 ASSERT_EQ(0, image.close());
413 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
414 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
417 TEST_F(TestMirroring, EnableImageMirror_WithoutJournaling) {
418 uint64_t features = 0;
419 features |= RBD_FEATURE_OBJECT_MAP;
420 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
421 check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL,
422 RBD_MIRROR_IMAGE_DISABLED);
425 TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) {
426 uint64_t features = 0;
427 features |= RBD_FEATURE_OBJECT_MAP;
428 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
429 features |= RBD_FEATURE_JOURNALING;
430 check_mirroring_on_create(features, RBD_MIRROR_MODE_DISABLED,
431 RBD_MIRROR_IMAGE_DISABLED);
434 TEST_F(TestMirroring, CreateImage_In_MirrorModeImage) {
435 uint64_t features = 0;
436 features |= RBD_FEATURE_OBJECT_MAP;
437 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
438 features |= RBD_FEATURE_JOURNALING;
439 check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE,
440 RBD_MIRROR_IMAGE_DISABLED);
443 TEST_F(TestMirroring, CreateImage_In_MirrorModePool) {
444 uint64_t features = 0;
445 features |= RBD_FEATURE_OBJECT_MAP;
446 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
447 features |= RBD_FEATURE_JOURNALING;
448 check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL,
449 RBD_MIRROR_IMAGE_ENABLED);
452 TEST_F(TestMirroring, CreateImage_In_MirrorModePool_WithoutJournaling) {
453 uint64_t features = 0;
454 features |= RBD_FEATURE_OBJECT_MAP;
455 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
456 check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL,
457 RBD_MIRROR_IMAGE_DISABLED);
460 TEST_F(TestMirroring, CreateImage_In_MirrorModeImage_WithoutJournaling) {
461 uint64_t features = 0;
462 features |= RBD_FEATURE_OBJECT_MAP;
463 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
464 check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE,
465 RBD_MIRROR_IMAGE_DISABLED);
468 TEST_F(TestMirroring, EnableJournaling_In_MirrorModeDisabled) {
469 uint64_t init_features = 0;
470 init_features |= RBD_FEATURE_OBJECT_MAP;
471 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
472 uint64_t features = RBD_FEATURE_JOURNALING;
473 check_mirroring_on_update_features(init_features, true, false, features, 0,
474 RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_IMAGE_DISABLED);
477 TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage) {
478 uint64_t init_features = 0;
479 init_features |= RBD_FEATURE_OBJECT_MAP;
480 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
481 uint64_t features = RBD_FEATURE_JOURNALING;
482 check_mirroring_on_update_features(init_features, true, false, features, 0,
483 RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_DISABLED);
486 TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) {
487 uint64_t init_features = 0;
488 init_features |= RBD_FEATURE_OBJECT_MAP;
489 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
490 uint64_t features = RBD_FEATURE_JOURNALING;
491 check_mirroring_on_update_features(init_features, true, false, features, 0,
492 RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED);
495 TEST_F(TestMirroring, DisableJournaling_In_MirrorModePool) {
496 uint64_t init_features = 0;
497 init_features |= RBD_FEATURE_OBJECT_MAP;
498 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
499 init_features |= RBD_FEATURE_JOURNALING;
500 uint64_t features = RBD_FEATURE_JOURNALING;
501 check_mirroring_on_update_features(init_features, false, false, features, 0,
502 RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_DISABLED);
505 TEST_F(TestMirroring, DisableJournaling_In_MirrorModeImage) {
506 uint64_t init_features = 0;
507 init_features |= RBD_FEATURE_OBJECT_MAP;
508 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
509 init_features |= RBD_FEATURE_JOURNALING;
510 uint64_t features = RBD_FEATURE_JOURNALING;
511 check_mirroring_on_update_features(init_features, false, true, features, -EINVAL,
512 RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED);
515 TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_PoolMode) {
516 std::vector<uint64_t> features_vec;
517 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
518 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
520 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec);
522 std::vector<rbd_mirror_image_state_t> states_vec;
523 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
524 states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED);
525 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL, states_vec);
528 TEST_F(TestMirroring, MirrorModeSet_PoolMode_To_DisabledMode) {
529 std::vector<uint64_t> features_vec;
530 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
531 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
533 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
535 std::vector<rbd_mirror_image_state_t> states_vec;
536 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
537 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
538 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED, states_vec);
541 TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_ImageMode) {
542 std::vector<uint64_t> features_vec;
543 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
544 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
546 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec);
548 std::vector<rbd_mirror_image_state_t> states_vec;
549 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
550 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
551 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE, states_vec);
555 TEST_F(TestMirroring, MirrorModeSet_PoolMode_To_ImageMode) {
556 std::vector<uint64_t> features_vec;
557 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
558 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
560 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
562 std::vector<rbd_mirror_image_state_t> states_vec;
563 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
564 states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED);
565 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE, states_vec);
568 TEST_F(TestMirroring, MirrorModeSet_ImageMode_To_PoolMode) {
569 std::vector<uint64_t> features_vec;
570 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
571 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
573 setup_images_with_mirror_mode(RBD_MIRROR_MODE_IMAGE, features_vec);
575 std::vector<rbd_mirror_image_state_t> states_vec;
576 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
577 states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED);
578 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL, states_vec);
581 TEST_F(TestMirroring, MirrorModeSet_ImageMode_To_DisabledMode) {
582 std::vector<uint64_t> features_vec;
583 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
584 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
586 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
588 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
589 ASSERT_EQ(-EINVAL, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
590 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
592 std::vector<rbd_mirror_image_state_t> states_vec;
593 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
594 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
595 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED, states_vec);
598 TEST_F(TestMirroring, RemoveImage_With_MirrorImageEnabled) {
599 check_remove_image(RBD_MIRROR_MODE_IMAGE,
600 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
604 TEST_F(TestMirroring, RemoveImage_With_MirrorImageDisabled) {
605 check_remove_image(RBD_MIRROR_MODE_IMAGE,
606 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
610 TEST_F(TestMirroring, RemoveImage_With_ImageWithoutJournal) {
611 check_remove_image(RBD_MIRROR_MODE_IMAGE,
612 RBD_FEATURE_EXCLUSIVE_LOCK,
616 TEST_F(TestMirroring, RemoveImage_With_MirrorImageDemoted) {
617 check_remove_image(RBD_MIRROR_MODE_IMAGE,
618 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
622 TEST_F(TestMirroring, MirrorStatusList) {
623 std::vector<uint64_t>
624 features_vec(5, RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
625 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
627 std::string last_read = "";
628 std::map<std::string, librbd::mirror_image_status_t> images;
629 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 2, &images));
630 ASSERT_EQ(2U, images.size());
632 last_read = images.rbegin()->first;
634 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 2, &images));
635 ASSERT_EQ(2U, images.size());
637 last_read = images.rbegin()->first;
639 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 4096, &images));
640 ASSERT_EQ(1U, images.size());
642 last_read = images.rbegin()->first;
644 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 4096, &images));
645 ASSERT_EQ(0U, images.size());
648 TEST_F(TestMirroring, RemoveBootstrapped)
650 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
652 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
654 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
657 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
658 ASSERT_EQ(-EBUSY, m_rbd.remove(m_ioctx, image_name.c_str()));
660 // simulate the image is open by rbd-mirror bootstrap
662 struct MirrorWatcher : public librados::WatchCtx2 {
663 MirrorWatcher(librados::IoCtx &ioctx) : m_ioctx(ioctx) {
665 void handle_notify(uint64_t notify_id, uint64_t cookie,
666 uint64_t notifier_id, bufferlist& bl) override {
667 // received IMAGE_UPDATED notification from remove
669 m_ioctx.notify_ack(RBD_MIRRORING, notify_id, cookie, bl);
671 void handle_error(uint64_t cookie, int err) override {
673 librados::IoCtx &m_ioctx;
674 bool m_notified = false;
676 ASSERT_EQ(0, m_ioctx.create(RBD_MIRRORING, false));
677 ASSERT_EQ(0, m_ioctx.watch2(RBD_MIRRORING, &handle, &watcher));
678 // now remove should succeed
679 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
680 ASSERT_EQ(0, m_ioctx.unwatch2(handle));
681 ASSERT_TRUE(watcher.m_notified);
682 ASSERT_EQ(0, image.close());
685 TEST_F(TestMirroring, AioPromoteDemote) {
686 std::list<std::string> image_names;
687 for (size_t idx = 0; idx < 10; ++idx) {
688 image_names.push_back(get_temp_image_name());
691 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
693 // create mirror images
695 std::list<librbd::Image> images;
696 for (auto &image_name : image_names) {
697 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048,
698 RBD_FEATURE_EXCLUSIVE_LOCK |
699 RBD_FEATURE_JOURNALING,
702 images.emplace_back();
703 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
704 ASSERT_EQ(0, images.back().mirror_image_enable());
708 std::list<librbd::RBD::AioCompletion *> aio_comps;
709 for (auto &image : images) {
710 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
711 ASSERT_EQ(0, image.aio_mirror_image_demote(aio_comps.back()));
713 for (auto aio_comp : aio_comps) {
714 ASSERT_EQ(0, aio_comp->wait_for_complete());
715 ASSERT_EQ(1, aio_comp->is_complete());
716 ASSERT_EQ(0, aio_comp->get_return_value());
722 for (auto &image : images) {
723 librbd::mirror_image_info_t mirror_image;
724 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
725 sizeof(mirror_image)));
726 ASSERT_FALSE(mirror_image.primary);
729 // promote all images
730 for (auto &image : images) {
731 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
732 ASSERT_EQ(0, image.aio_mirror_image_promote(false, aio_comps.back()));
734 for (auto aio_comp : aio_comps) {
735 ASSERT_EQ(0, aio_comp->wait_for_complete());
736 ASSERT_EQ(1, aio_comp->is_complete());
737 ASSERT_EQ(0, aio_comp->get_return_value());
742 for (auto &image : images) {
743 librbd::mirror_image_info_t mirror_image;
744 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
745 sizeof(mirror_image)));
746 ASSERT_TRUE(mirror_image.primary);
750 TEST_F(TestMirroring, AioGetInfo) {
751 std::list<std::string> image_names;
752 for (size_t idx = 0; idx < 10; ++idx) {
753 image_names.push_back(get_temp_image_name());
756 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
758 // create mirror images
760 std::list<librbd::Image> images;
761 for (auto &image_name : image_names) {
762 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048,
763 RBD_FEATURE_EXCLUSIVE_LOCK |
764 RBD_FEATURE_JOURNALING,
767 images.emplace_back();
768 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
771 std::list<librbd::RBD::AioCompletion *> aio_comps;
772 std::list<librbd::mirror_image_info_t> infos;
773 for (auto &image : images) {
774 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
775 infos.emplace_back();
776 ASSERT_EQ(0, image.aio_mirror_image_get_info(&infos.back(),
777 sizeof(infos.back()),
780 for (auto aio_comp : aio_comps) {
781 ASSERT_EQ(0, aio_comp->wait_for_complete());
782 ASSERT_EQ(1, aio_comp->is_complete());
783 ASSERT_EQ(0, aio_comp->get_return_value());
788 for (auto &info : infos) {
789 ASSERT_NE("", info.global_id);
790 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
791 ASSERT_TRUE(info.primary);
795 TEST_F(TestMirroring, AioGetStatus) {
796 std::list<std::string> image_names;
797 for (size_t idx = 0; idx < 10; ++idx) {
798 image_names.push_back(get_temp_image_name());
801 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
803 // create mirror images
805 std::list<librbd::Image> images;
806 for (auto &image_name : image_names) {
807 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048,
808 RBD_FEATURE_EXCLUSIVE_LOCK |
809 RBD_FEATURE_JOURNALING,
812 images.emplace_back();
813 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
816 std::list<librbd::RBD::AioCompletion *> aio_comps;
817 std::list<librbd::mirror_image_status_t> statuses;
818 for (auto &image : images) {
819 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
820 statuses.emplace_back();
821 ASSERT_EQ(0, image.aio_mirror_image_get_status(&statuses.back(),
822 sizeof(statuses.back()),
825 for (auto aio_comp : aio_comps) {
826 ASSERT_EQ(0, aio_comp->wait_for_complete());
827 ASSERT_EQ(1, aio_comp->is_complete());
828 ASSERT_EQ(0, aio_comp->get_return_value());
833 for (auto &status : statuses) {
834 ASSERT_NE("", status.name);
835 ASSERT_NE("", status.info.global_id);
836 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, status.info.state);
837 ASSERT_TRUE(status.info.primary);
838 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state);
839 ASSERT_EQ("status not found", status.description);
840 ASSERT_FALSE(status.up);
841 ASSERT_EQ(0, status.last_update);