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 "librbd/api/Image.h"
27 #include "journal/Journaler.h"
28 #include "journal/Settings.h"
29 #include <boost/scope_exit.hpp>
30 #include <boost/assign/list_of.hpp>
34 void register_test_mirroring() {
37 class TestMirroring
: public TestFixture
{
43 void TearDown() override
{
46 TestFixture::TearDown();
49 void SetUp() override
{
50 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), m_ioctx
));
53 std::string image_name
= "mirrorimg1";
55 void check_mirror_image_enable(rbd_mirror_mode_t mirror_mode
,
58 rbd_mirror_image_state_t mirror_state
) {
60 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
63 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
, &order
));
65 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
67 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
69 ASSERT_EQ(expected_r
, image
.mirror_image_enable());
71 librbd::mirror_image_info_t mirror_image
;
72 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
73 ASSERT_EQ(mirror_state
, mirror_image
.state
);
75 librbd::mirror_image_status_t status
;
76 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
77 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
79 std::string instance_id
;
80 ASSERT_EQ(mirror_state
== RBD_MIRROR_IMAGE_ENABLED
? -ENOENT
: -EINVAL
,
81 image
.mirror_image_get_instance_id(&instance_id
));
83 ASSERT_EQ(0, image
.close());
84 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
85 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
88 void check_mirror_image_disable(rbd_mirror_mode_t mirror_mode
,
91 rbd_mirror_image_state_t mirror_state
) {
93 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
96 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
, &order
));
98 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
100 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
102 ASSERT_EQ(expected_r
, image
.mirror_image_disable(false));
104 librbd::mirror_image_info_t mirror_image
;
105 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
106 ASSERT_EQ(mirror_state
, mirror_image
.state
);
108 librbd::mirror_image_status_t status
;
109 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
110 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
112 std::string instance_id
;
113 ASSERT_EQ(mirror_state
== RBD_MIRROR_IMAGE_ENABLED
? -ENOENT
: -EINVAL
,
114 image
.mirror_image_get_instance_id(&instance_id
));
116 ASSERT_EQ(0, image
.close());
117 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
118 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
121 void check_mirroring_status(size_t *images_count
) {
122 std::map
<std::string
, librbd::mirror_image_status_t
> images
;
123 ASSERT_EQ(0, m_rbd
.mirror_image_status_list(m_ioctx
, "", 4096, &images
));
125 std::map
<librbd::mirror_image_status_state_t
, int> states
;
126 ASSERT_EQ(0, m_rbd
.mirror_image_status_summary(m_ioctx
, &states
));
127 size_t states_count
= 0;
128 for (auto &s
: states
) {
129 states_count
+= s
.second
;
131 ASSERT_EQ(images
.size(), states_count
);
133 *images_count
= images
.size();
135 std::map
<std::string
, std::string
> instance_ids
;
136 ASSERT_EQ(0, m_rbd
.mirror_image_instance_id_list(m_ioctx
, "", 4096,
138 ASSERT_TRUE(instance_ids
.empty());
141 void check_mirroring_on_create(uint64_t features
,
142 rbd_mirror_mode_t mirror_mode
,
143 rbd_mirror_image_state_t mirror_state
) {
145 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
147 size_t mirror_images_count
= 0;
148 check_mirroring_status(&mirror_images_count
);
151 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
, &order
));
153 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
155 librbd::mirror_image_info_t mirror_image
;
156 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
157 ASSERT_EQ(mirror_state
, mirror_image
.state
);
159 librbd::mirror_image_status_t status
;
160 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
161 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
163 size_t mirror_images_new_count
= 0;
164 check_mirroring_status(&mirror_images_new_count
);
165 if (mirror_mode
== RBD_MIRROR_MODE_POOL
&&
166 mirror_state
== RBD_MIRROR_IMAGE_ENABLED
) {
167 ASSERT_EQ(mirror_images_new_count
, mirror_images_count
+ 1);
169 ASSERT_EQ(mirror_images_new_count
, mirror_images_count
);
172 ASSERT_EQ(0, image
.close());
173 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
174 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
176 check_mirroring_status(&mirror_images_new_count
);
177 ASSERT_EQ(mirror_images_new_count
, mirror_images_count
);
180 void check_mirroring_on_update_features(uint64_t init_features
,
181 bool enable
, bool enable_mirroring
,
182 uint64_t features
, int expected_r
,
183 rbd_mirror_mode_t mirror_mode
,
184 rbd_mirror_image_state_t mirror_state
) {
186 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
189 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, init_features
, &order
));
191 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
193 if (enable_mirroring
) {
194 ASSERT_EQ(0, image
.mirror_image_enable());
197 ASSERT_EQ(expected_r
, image
.update_features(features
, enable
));
199 librbd::mirror_image_info_t mirror_image
;
200 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
201 ASSERT_EQ(mirror_state
, mirror_image
.state
);
203 librbd::mirror_image_status_t status
;
204 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
205 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
207 ASSERT_EQ(0, image
.close());
208 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
209 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
212 void setup_images_with_mirror_mode(rbd_mirror_mode_t mirror_mode
,
213 std::vector
<uint64_t>& features_vec
) {
215 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
219 for (const auto& features
: features_vec
) {
220 std::stringstream
img_name("img_");
222 std::string img_name_str
= img_name
.str();
223 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, img_name_str
.c_str(), 2048, features
, &order
));
227 void check_mirroring_on_mirror_mode_set(rbd_mirror_mode_t mirror_mode
,
228 std::vector
<rbd_mirror_image_state_t
>& states_vec
) {
230 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
232 std::vector
< std::tuple
<std::string
, rbd_mirror_image_state_t
> > images
;
234 for (const auto& mirror_state
: states_vec
) {
235 std::stringstream
img_name("img_");
237 std::string img_name_str
= img_name
.str();
239 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, img_name_str
.c_str()));
240 images
.push_back(std::make_tuple(img_name_str
, mirror_state
));
242 librbd::mirror_image_info_t mirror_image
;
243 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
244 ASSERT_EQ(mirror_state
, mirror_image
.state
);
246 librbd::mirror_image_status_t status
;
247 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
248 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
250 ASSERT_EQ(0, image
.close());
251 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, img_name_str
.c_str()));
255 void check_remove_image(rbd_mirror_mode_t mirror_mode
, uint64_t features
,
256 bool enable_mirroring
, bool demote
= false) {
258 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
261 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
,
264 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
266 if (enable_mirroring
) {
267 ASSERT_EQ(0, image
.mirror_image_enable());
271 ASSERT_EQ(0, image
.mirror_image_demote());
272 ASSERT_EQ(0, image
.mirror_image_disable(true));
276 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
277 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
280 void check_trash_move_restore(rbd_mirror_mode_t mirror_mode
,
281 bool enable_mirroring
) {
283 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, mirror_mode
));
286 uint64_t features
= RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
;
287 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
,
290 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
292 if (enable_mirroring
) {
293 ASSERT_EQ(0, image
.mirror_image_enable());
296 std::string image_id
;
297 ASSERT_EQ(0, image
.get_id(&image_id
));
300 ASSERT_EQ(0, m_rbd
.trash_move(m_ioctx
, image_name
.c_str(), 100));
302 ASSERT_EQ(0, m_rbd
.open_by_id(m_ioctx
, image
, image_id
.c_str(), NULL
));
304 librbd::mirror_image_info_t mirror_image
;
305 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
306 ASSERT_EQ(mirror_image
.state
, RBD_MIRROR_IMAGE_DISABLED
);
308 ASSERT_EQ(0, m_rbd
.trash_restore(m_ioctx
, image_id
.c_str(), ""));
310 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
, sizeof(mirror_image
)));
311 if (mirror_mode
== RBD_MIRROR_MODE_POOL
) {
312 ASSERT_EQ(mirror_image
.state
, RBD_MIRROR_IMAGE_ENABLED
);
314 ASSERT_EQ(mirror_image
.state
, RBD_MIRROR_IMAGE_DISABLED
);
318 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
319 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
322 void setup_mirror_peer(librados::IoCtx
&io_ctx
, librbd::Image
&image
) {
323 ASSERT_EQ(0, image
.snap_create("sync-point-snap"));
325 std::string image_id
;
326 ASSERT_EQ(0, get_image_id(image
, &image_id
));
328 librbd::journal::MirrorPeerClientMeta
peer_client_meta(
329 "remote-image-id", {{{}, "sync-point-snap", boost::none
}}, {});
330 librbd::journal::ClientData
client_data(peer_client_meta
);
332 journal::Journaler
journaler(io_ctx
, image_id
, "peer-client", {});
333 C_SaferCond init_ctx
;
334 journaler
.init(&init_ctx
);
335 ASSERT_EQ(-ENOENT
, init_ctx
.wait());
337 bufferlist client_data_bl
;
338 encode(client_data
, client_data_bl
);
339 ASSERT_EQ(0, journaler
.register_client(client_data_bl
));
341 C_SaferCond shut_down_ctx
;
342 journaler
.shut_down(&shut_down_ctx
);
343 ASSERT_EQ(0, shut_down_ctx
.wait());
348 TEST_F(TestMirroring
, EnableImageMirror_In_MirrorModeImage
) {
349 uint64_t features
= 0;
350 features
|= RBD_FEATURE_OBJECT_MAP
;
351 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
352 features
|= RBD_FEATURE_JOURNALING
;
353 check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE
, features
, 0,
354 RBD_MIRROR_IMAGE_ENABLED
);
357 TEST_F(TestMirroring
, EnableImageMirror_In_MirrorModePool
) {
358 uint64_t features
= 0;
359 features
|= RBD_FEATURE_OBJECT_MAP
;
360 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
361 features
|= RBD_FEATURE_JOURNALING
;
362 check_mirror_image_enable(RBD_MIRROR_MODE_POOL
, features
, -EINVAL
,
363 RBD_MIRROR_IMAGE_ENABLED
);
366 TEST_F(TestMirroring
, EnableImageMirror_In_MirrorModeDisabled
) {
367 uint64_t features
= 0;
368 features
|= RBD_FEATURE_OBJECT_MAP
;
369 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
370 features
|= RBD_FEATURE_JOURNALING
;
371 check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED
, features
, -EINVAL
,
372 RBD_MIRROR_IMAGE_DISABLED
);
375 TEST_F(TestMirroring
, DisableImageMirror_In_MirrorModeImage
) {
376 uint64_t features
= 0;
377 features
|= RBD_FEATURE_OBJECT_MAP
;
378 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
379 features
|= RBD_FEATURE_JOURNALING
;
380 check_mirror_image_disable(RBD_MIRROR_MODE_IMAGE
, features
, 0,
381 RBD_MIRROR_IMAGE_DISABLED
);
384 TEST_F(TestMirroring
, DisableImageMirror_In_MirrorModePool
) {
385 uint64_t features
= 0;
386 features
|= RBD_FEATURE_OBJECT_MAP
;
387 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
388 features
|= RBD_FEATURE_JOURNALING
;
389 check_mirror_image_disable(RBD_MIRROR_MODE_POOL
, features
, -EINVAL
,
390 RBD_MIRROR_IMAGE_ENABLED
);
393 TEST_F(TestMirroring
, DisableImageMirror_In_MirrorModeDisabled
) {
394 uint64_t features
= 0;
395 features
|= RBD_FEATURE_OBJECT_MAP
;
396 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
397 features
|= RBD_FEATURE_JOURNALING
;
398 check_mirror_image_disable(RBD_MIRROR_MODE_DISABLED
, features
, -EINVAL
,
399 RBD_MIRROR_IMAGE_DISABLED
);
402 TEST_F(TestMirroring
, DisableImageMirrorWithPeer
) {
403 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
405 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
407 uint64_t features
= RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
;
409 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
,
413 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
414 ASSERT_EQ(0, image
.mirror_image_enable());
416 setup_mirror_peer(m_ioctx
, image
);
418 ASSERT_EQ(0, image
.mirror_image_disable(false));
420 std::vector
<librbd::snap_info_t
> snaps
;
421 ASSERT_EQ(0, image
.snap_list(snaps
));
422 ASSERT_TRUE(snaps
.empty());
424 librbd::mirror_image_info_t mirror_image
;
425 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
,
426 sizeof(mirror_image
)));
427 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED
, mirror_image
.state
);
429 librbd::mirror_image_status_t status
;
430 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
431 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
433 ASSERT_EQ(0, image
.close());
434 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
435 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
438 TEST_F(TestMirroring
, DisableJournalingWithPeer
) {
439 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
441 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
443 uint64_t features
= RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
;
445 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
,
449 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
451 setup_mirror_peer(m_ioctx
, image
);
453 ASSERT_EQ(0, image
.update_features(RBD_FEATURE_JOURNALING
, false));
455 std::vector
<librbd::snap_info_t
> snaps
;
456 ASSERT_EQ(0, image
.snap_list(snaps
));
457 ASSERT_TRUE(snaps
.empty());
459 librbd::mirror_image_info_t mirror_image
;
460 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
,
461 sizeof(mirror_image
)));
462 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED
, mirror_image
.state
);
464 librbd::mirror_image_status_t status
;
465 ASSERT_EQ(0, image
.mirror_image_get_status(&status
, sizeof(status
)));
466 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
468 ASSERT_EQ(0, image
.close());
469 ASSERT_EQ(0, m_rbd
.remove(m_ioctx
, image_name
.c_str()));
470 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
473 TEST_F(TestMirroring
, EnableImageMirror_WithoutJournaling
) {
474 uint64_t features
= 0;
475 features
|= RBD_FEATURE_OBJECT_MAP
;
476 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
477 check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED
, features
, -EINVAL
,
478 RBD_MIRROR_IMAGE_DISABLED
);
481 TEST_F(TestMirroring
, CreateImage_In_MirrorModeDisabled
) {
482 uint64_t features
= 0;
483 features
|= RBD_FEATURE_OBJECT_MAP
;
484 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
485 features
|= RBD_FEATURE_JOURNALING
;
486 check_mirroring_on_create(features
, RBD_MIRROR_MODE_DISABLED
,
487 RBD_MIRROR_IMAGE_DISABLED
);
490 TEST_F(TestMirroring
, CreateImage_In_MirrorModeImage
) {
491 uint64_t features
= 0;
492 features
|= RBD_FEATURE_OBJECT_MAP
;
493 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
494 features
|= RBD_FEATURE_JOURNALING
;
495 check_mirroring_on_create(features
, RBD_MIRROR_MODE_IMAGE
,
496 RBD_MIRROR_IMAGE_DISABLED
);
499 TEST_F(TestMirroring
, CreateImage_In_MirrorModePool
) {
500 uint64_t features
= 0;
501 features
|= RBD_FEATURE_OBJECT_MAP
;
502 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
503 features
|= RBD_FEATURE_JOURNALING
;
504 check_mirroring_on_create(features
, RBD_MIRROR_MODE_POOL
,
505 RBD_MIRROR_IMAGE_ENABLED
);
508 TEST_F(TestMirroring
, CreateImage_In_MirrorModePool_WithoutJournaling
) {
509 uint64_t features
= 0;
510 features
|= RBD_FEATURE_OBJECT_MAP
;
511 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
512 check_mirroring_on_create(features
, RBD_MIRROR_MODE_POOL
,
513 RBD_MIRROR_IMAGE_DISABLED
);
516 TEST_F(TestMirroring
, CreateImage_In_MirrorModeImage_WithoutJournaling
) {
517 uint64_t features
= 0;
518 features
|= RBD_FEATURE_OBJECT_MAP
;
519 features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
520 check_mirroring_on_create(features
, RBD_MIRROR_MODE_IMAGE
,
521 RBD_MIRROR_IMAGE_DISABLED
);
524 TEST_F(TestMirroring
, EnableJournaling_In_MirrorModeDisabled
) {
525 uint64_t init_features
= 0;
526 init_features
|= RBD_FEATURE_OBJECT_MAP
;
527 init_features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
528 uint64_t features
= RBD_FEATURE_JOURNALING
;
529 check_mirroring_on_update_features(init_features
, true, false, features
, 0,
530 RBD_MIRROR_MODE_DISABLED
, RBD_MIRROR_IMAGE_DISABLED
);
533 TEST_F(TestMirroring
, EnableJournaling_In_MirrorModeImage
) {
534 uint64_t init_features
= 0;
535 init_features
|= RBD_FEATURE_OBJECT_MAP
;
536 init_features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
537 uint64_t features
= RBD_FEATURE_JOURNALING
;
538 check_mirroring_on_update_features(init_features
, true, false, features
, 0,
539 RBD_MIRROR_MODE_IMAGE
, RBD_MIRROR_IMAGE_DISABLED
);
542 TEST_F(TestMirroring
, EnableJournaling_In_MirrorModePool
) {
543 uint64_t init_features
= 0;
544 init_features
|= RBD_FEATURE_OBJECT_MAP
;
545 init_features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
546 uint64_t features
= RBD_FEATURE_JOURNALING
;
547 check_mirroring_on_update_features(init_features
, true, false, features
, 0,
548 RBD_MIRROR_MODE_POOL
, RBD_MIRROR_IMAGE_ENABLED
);
551 TEST_F(TestMirroring
, DisableJournaling_In_MirrorModePool
) {
552 uint64_t init_features
= 0;
553 init_features
|= RBD_FEATURE_OBJECT_MAP
;
554 init_features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
555 init_features
|= RBD_FEATURE_JOURNALING
;
556 uint64_t features
= RBD_FEATURE_JOURNALING
;
557 check_mirroring_on_update_features(init_features
, false, false, features
, 0,
558 RBD_MIRROR_MODE_POOL
, RBD_MIRROR_IMAGE_DISABLED
);
561 TEST_F(TestMirroring
, DisableJournaling_In_MirrorModeImage
) {
562 uint64_t init_features
= 0;
563 init_features
|= RBD_FEATURE_OBJECT_MAP
;
564 init_features
|= RBD_FEATURE_EXCLUSIVE_LOCK
;
565 init_features
|= RBD_FEATURE_JOURNALING
;
566 uint64_t features
= RBD_FEATURE_JOURNALING
;
567 check_mirroring_on_update_features(init_features
, false, true, features
, -EINVAL
,
568 RBD_MIRROR_MODE_IMAGE
, RBD_MIRROR_IMAGE_ENABLED
);
571 TEST_F(TestMirroring
, MirrorModeSet_DisabledMode_To_PoolMode
) {
572 std::vector
<uint64_t> features_vec
;
573 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
);
574 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
576 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED
, features_vec
);
578 std::vector
<rbd_mirror_image_state_t
> states_vec
;
579 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
580 states_vec
.push_back(RBD_MIRROR_IMAGE_ENABLED
);
581 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL
, states_vec
);
584 TEST_F(TestMirroring
, MirrorModeSet_PoolMode_To_DisabledMode
) {
585 std::vector
<uint64_t> features_vec
;
586 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
);
587 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
589 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL
, features_vec
);
591 std::vector
<rbd_mirror_image_state_t
> states_vec
;
592 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
593 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
594 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED
, states_vec
);
597 TEST_F(TestMirroring
, MirrorModeSet_DisabledMode_To_ImageMode
) {
598 std::vector
<uint64_t> features_vec
;
599 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
);
600 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
602 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED
, features_vec
);
604 std::vector
<rbd_mirror_image_state_t
> states_vec
;
605 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
606 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
607 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE
, states_vec
);
611 TEST_F(TestMirroring
, MirrorModeSet_PoolMode_To_ImageMode
) {
612 std::vector
<uint64_t> features_vec
;
613 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
);
614 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
616 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL
, features_vec
);
618 std::vector
<rbd_mirror_image_state_t
> states_vec
;
619 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
620 states_vec
.push_back(RBD_MIRROR_IMAGE_ENABLED
);
621 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE
, states_vec
);
624 TEST_F(TestMirroring
, MirrorModeSet_ImageMode_To_PoolMode
) {
625 std::vector
<uint64_t> features_vec
;
626 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
);
627 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
629 setup_images_with_mirror_mode(RBD_MIRROR_MODE_IMAGE
, features_vec
);
631 std::vector
<rbd_mirror_image_state_t
> states_vec
;
632 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
633 states_vec
.push_back(RBD_MIRROR_IMAGE_ENABLED
);
634 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL
, states_vec
);
637 TEST_F(TestMirroring
, MirrorModeSet_ImageMode_To_DisabledMode
) {
638 std::vector
<uint64_t> features_vec
;
639 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
);
640 features_vec
.push_back(RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
642 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL
, features_vec
);
644 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
645 ASSERT_EQ(-EINVAL
, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
646 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
648 std::vector
<rbd_mirror_image_state_t
> states_vec
;
649 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
650 states_vec
.push_back(RBD_MIRROR_IMAGE_DISABLED
);
651 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED
, states_vec
);
654 TEST_F(TestMirroring
, RemoveImage_With_MirrorImageEnabled
) {
655 check_remove_image(RBD_MIRROR_MODE_IMAGE
,
656 RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
,
660 TEST_F(TestMirroring
, RemoveImage_With_MirrorImageDisabled
) {
661 check_remove_image(RBD_MIRROR_MODE_IMAGE
,
662 RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
,
666 TEST_F(TestMirroring
, RemoveImage_With_ImageWithoutJournal
) {
667 check_remove_image(RBD_MIRROR_MODE_IMAGE
,
668 RBD_FEATURE_EXCLUSIVE_LOCK
,
672 TEST_F(TestMirroring
, RemoveImage_With_MirrorImageDemoted
) {
673 check_remove_image(RBD_MIRROR_MODE_IMAGE
,
674 RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
,
678 TEST_F(TestMirroring
, TrashMoveRestore_PoolMode
) {
679 check_trash_move_restore(RBD_MIRROR_MODE_POOL
, false);
682 TEST_F(TestMirroring
, TrashMoveRestore_ImageMode_MirroringDisabled
) {
683 check_trash_move_restore(RBD_MIRROR_MODE_IMAGE
, false);
686 TEST_F(TestMirroring
, TrashMoveRestore_ImageMode_MirroringEnabled
) {
687 check_trash_move_restore(RBD_MIRROR_MODE_IMAGE
, true);
690 TEST_F(TestMirroring
, MirrorStatusList
) {
691 std::vector
<uint64_t>
692 features_vec(5, RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
);
693 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL
, features_vec
);
695 std::string last_read
= "";
696 std::map
<std::string
, librbd::mirror_image_status_t
> images
;
697 ASSERT_EQ(0, m_rbd
.mirror_image_status_list(m_ioctx
, last_read
, 2, &images
));
698 ASSERT_EQ(2U, images
.size());
700 last_read
= images
.rbegin()->first
;
702 ASSERT_EQ(0, m_rbd
.mirror_image_status_list(m_ioctx
, last_read
, 2, &images
));
703 ASSERT_EQ(2U, images
.size());
705 last_read
= images
.rbegin()->first
;
707 ASSERT_EQ(0, m_rbd
.mirror_image_status_list(m_ioctx
, last_read
, 4096, &images
));
708 ASSERT_EQ(1U, images
.size());
710 last_read
= images
.rbegin()->first
;
712 ASSERT_EQ(0, m_rbd
.mirror_image_status_list(m_ioctx
, last_read
, 4096, &images
));
713 ASSERT_EQ(0U, images
.size());
716 TEST_F(TestMirroring
, RemoveBootstrapped
)
718 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
720 uint64_t features
= RBD_FEATURE_EXCLUSIVE_LOCK
| RBD_FEATURE_JOURNALING
;
722 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 4096, features
,
725 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, image
, image_name
.c_str()));
727 librbd::NoOpProgressContext no_op
;
728 ASSERT_EQ(-EBUSY
, librbd::api::Image
<>::remove(m_ioctx
, image_name
, no_op
));
730 // simulate the image is open by rbd-mirror bootstrap
732 struct MirrorWatcher
: public librados::WatchCtx2
{
733 explicit MirrorWatcher(librados::IoCtx
&ioctx
) : m_ioctx(ioctx
) {
735 void handle_notify(uint64_t notify_id
, uint64_t cookie
,
736 uint64_t notifier_id
, bufferlist
& bl
) override
{
737 // received IMAGE_UPDATED notification from remove
739 m_ioctx
.notify_ack(RBD_MIRRORING
, notify_id
, cookie
, bl
);
741 void handle_error(uint64_t cookie
, int err
) override
{
743 librados::IoCtx
&m_ioctx
;
744 bool m_notified
= false;
746 ASSERT_EQ(0, m_ioctx
.create(RBD_MIRRORING
, false));
747 ASSERT_EQ(0, m_ioctx
.watch2(RBD_MIRRORING
, &handle
, &watcher
));
748 // now remove should succeed
749 ASSERT_EQ(0, librbd::api::Image
<>::remove(m_ioctx
, image_name
, no_op
));
750 ASSERT_EQ(0, m_ioctx
.unwatch2(handle
));
751 ASSERT_TRUE(watcher
.m_notified
);
752 ASSERT_EQ(0, image
.close());
755 TEST_F(TestMirroring
, AioPromoteDemote
) {
756 std::list
<std::string
> image_names
;
757 for (size_t idx
= 0; idx
< 10; ++idx
) {
758 image_names
.push_back(get_temp_image_name());
761 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
763 // create mirror images
765 std::list
<librbd::Image
> images
;
766 for (auto &image_name
: image_names
) {
767 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 2048,
768 RBD_FEATURE_EXCLUSIVE_LOCK
|
769 RBD_FEATURE_JOURNALING
,
772 images
.emplace_back();
773 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, images
.back(), image_name
.c_str()));
774 ASSERT_EQ(0, images
.back().mirror_image_enable());
778 std::list
<librbd::RBD::AioCompletion
*> aio_comps
;
779 for (auto &image
: images
) {
780 aio_comps
.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
781 ASSERT_EQ(0, image
.aio_mirror_image_demote(aio_comps
.back()));
783 for (auto aio_comp
: aio_comps
) {
784 ASSERT_EQ(0, aio_comp
->wait_for_complete());
785 ASSERT_EQ(1, aio_comp
->is_complete());
786 ASSERT_EQ(0, aio_comp
->get_return_value());
792 for (auto &image
: images
) {
793 librbd::mirror_image_info_t mirror_image
;
794 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
,
795 sizeof(mirror_image
)));
796 ASSERT_FALSE(mirror_image
.primary
);
799 // promote all images
800 for (auto &image
: images
) {
801 aio_comps
.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
802 ASSERT_EQ(0, image
.aio_mirror_image_promote(false, aio_comps
.back()));
804 for (auto aio_comp
: aio_comps
) {
805 ASSERT_EQ(0, aio_comp
->wait_for_complete());
806 ASSERT_EQ(1, aio_comp
->is_complete());
807 ASSERT_EQ(0, aio_comp
->get_return_value());
812 for (auto &image
: images
) {
813 librbd::mirror_image_info_t mirror_image
;
814 ASSERT_EQ(0, image
.mirror_image_get_info(&mirror_image
,
815 sizeof(mirror_image
)));
816 ASSERT_TRUE(mirror_image
.primary
);
820 TEST_F(TestMirroring
, AioGetInfo
) {
821 std::list
<std::string
> image_names
;
822 for (size_t idx
= 0; idx
< 10; ++idx
) {
823 image_names
.push_back(get_temp_image_name());
826 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
828 // create mirror images
830 std::list
<librbd::Image
> images
;
831 for (auto &image_name
: image_names
) {
832 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 2048,
833 RBD_FEATURE_EXCLUSIVE_LOCK
|
834 RBD_FEATURE_JOURNALING
,
837 images
.emplace_back();
838 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, images
.back(), image_name
.c_str()));
841 std::list
<librbd::RBD::AioCompletion
*> aio_comps
;
842 std::list
<librbd::mirror_image_info_t
> infos
;
843 for (auto &image
: images
) {
844 aio_comps
.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
845 infos
.emplace_back();
846 ASSERT_EQ(0, image
.aio_mirror_image_get_info(&infos
.back(),
847 sizeof(infos
.back()),
850 for (auto aio_comp
: aio_comps
) {
851 ASSERT_EQ(0, aio_comp
->wait_for_complete());
852 ASSERT_EQ(1, aio_comp
->is_complete());
853 ASSERT_EQ(0, aio_comp
->get_return_value());
858 for (auto &info
: infos
) {
859 ASSERT_NE("", info
.global_id
);
860 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
861 ASSERT_TRUE(info
.primary
);
865 TEST_F(TestMirroring
, AioGetStatus
) {
866 std::list
<std::string
> image_names
;
867 for (size_t idx
= 0; idx
< 10; ++idx
) {
868 image_names
.push_back(get_temp_image_name());
871 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
873 // create mirror images
875 std::list
<librbd::Image
> images
;
876 for (auto &image_name
: image_names
) {
877 ASSERT_EQ(0, m_rbd
.create2(m_ioctx
, image_name
.c_str(), 2048,
878 RBD_FEATURE_EXCLUSIVE_LOCK
|
879 RBD_FEATURE_JOURNALING
,
882 images
.emplace_back();
883 ASSERT_EQ(0, m_rbd
.open(m_ioctx
, images
.back(), image_name
.c_str()));
886 std::list
<librbd::RBD::AioCompletion
*> aio_comps
;
887 std::list
<librbd::mirror_image_status_t
> statuses
;
888 for (auto &image
: images
) {
889 aio_comps
.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
890 statuses
.emplace_back();
891 ASSERT_EQ(0, image
.aio_mirror_image_get_status(&statuses
.back(),
892 sizeof(statuses
.back()),
895 for (auto aio_comp
: aio_comps
) {
896 ASSERT_EQ(0, aio_comp
->wait_for_complete());
897 ASSERT_EQ(1, aio_comp
->is_complete());
898 ASSERT_EQ(0, aio_comp
->get_return_value());
903 for (auto &status
: statuses
) {
904 ASSERT_NE("", status
.name
);
905 ASSERT_NE("", status
.info
.global_id
);
906 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, status
.info
.state
);
907 ASSERT_TRUE(status
.info
.primary
);
908 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN
, status
.state
);
909 ASSERT_EQ("status not found", status
.description
);
910 ASSERT_FALSE(status
.up
);
911 ASSERT_EQ(0, status
.last_update
);
915 TEST_F(TestMirroring
, SiteName
) {
916 REQUIRE(!is_librados_test_stub(_rados
));
918 const std::string
expected_site_name("us-east-1a");
919 ASSERT_EQ(0, m_rbd
.mirror_site_name_set(_rados
, expected_site_name
));
921 std::string site_name
;
922 ASSERT_EQ(0, m_rbd
.mirror_site_name_get(_rados
, &site_name
));
923 ASSERT_EQ(expected_site_name
, site_name
);
925 ASSERT_EQ(0, m_rbd
.mirror_site_name_set(_rados
, ""));
928 ASSERT_EQ(0, _rados
.cluster_fsid(&fsid
));
929 ASSERT_EQ(0, m_rbd
.mirror_site_name_get(_rados
, &site_name
));
930 ASSERT_EQ(fsid
, site_name
);
933 TEST_F(TestMirroring
, Bootstrap
) {
934 REQUIRE(!is_librados_test_stub(_rados
));
936 std::string token_b64
;
937 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_DISABLED
));
938 ASSERT_EQ(-EINVAL
, m_rbd
.mirror_peer_bootstrap_create(m_ioctx
, &token_b64
));
940 ASSERT_EQ(0, m_rbd
.mirror_mode_set(m_ioctx
, RBD_MIRROR_MODE_POOL
));
941 ASSERT_EQ(0, m_rbd
.mirror_peer_bootstrap_create(m_ioctx
, &token_b64
));
943 bufferlist token_b64_bl
;
944 token_b64_bl
.append(token_b64
);
947 token_bl
.decode_base64(token_b64_bl
);
949 // cannot import token into same cluster
951 m_rbd
.mirror_peer_bootstrap_import(
952 m_ioctx
, RBD_MIRROR_PEER_DIRECTION_RX
, token_b64
));