]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/test_mirroring.cc
import ceph 14.2.5
[ceph.git] / ceph / src / test / librbd / test_mirroring.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2016 SUSE LINUX GmbH
7 *
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.
12 *
13 */
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>
31 #include <utility>
32 #include <vector>
33
34 void register_test_mirroring() {
35 }
36
37 class TestMirroring : public TestFixture {
38 public:
39
40 TestMirroring() {}
41
42
43 void TearDown() override {
44 unlock_image();
45
46 TestFixture::TearDown();
47 }
48
49 void SetUp() override {
50 ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), m_ioctx));
51 }
52
53 std::string image_name = "mirrorimg1";
54
55 void check_mirror_image_enable(rbd_mirror_mode_t mirror_mode,
56 uint64_t features,
57 int expected_r,
58 rbd_mirror_image_state_t mirror_state) {
59
60 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
61
62 int order = 20;
63 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
64 librbd::Image image;
65 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
66
67 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
68
69 ASSERT_EQ(expected_r, image.mirror_image_enable());
70
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);
74
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);
78
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));
82
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));
86 }
87
88 void check_mirror_image_disable(rbd_mirror_mode_t mirror_mode,
89 uint64_t features,
90 int expected_r,
91 rbd_mirror_image_state_t mirror_state) {
92
93 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
94
95 int order = 20;
96 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
97 librbd::Image image;
98 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
99
100 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
101
102 ASSERT_EQ(expected_r, image.mirror_image_disable(false));
103
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);
107
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);
111
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));
115
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));
119 }
120
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));
124
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;
130 }
131 ASSERT_EQ(images.size(), states_count);
132
133 *images_count = images.size();
134
135 std::map<std::string, std::string> instance_ids;
136 ASSERT_EQ(0, m_rbd.mirror_image_instance_id_list(m_ioctx, "", 4096,
137 &instance_ids));
138 ASSERT_TRUE(instance_ids.empty());
139 }
140
141 void check_mirroring_on_create(uint64_t features,
142 rbd_mirror_mode_t mirror_mode,
143 rbd_mirror_image_state_t mirror_state) {
144
145 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
146
147 size_t mirror_images_count = 0;
148 check_mirroring_status(&mirror_images_count);
149
150 int order = 20;
151 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
152 librbd::Image image;
153 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
154
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);
158
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);
162
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);
168 } else {
169 ASSERT_EQ(mirror_images_new_count, mirror_images_count);
170 }
171
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));
175
176 check_mirroring_status(&mirror_images_new_count);
177 ASSERT_EQ(mirror_images_new_count, mirror_images_count);
178 }
179
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) {
185
186 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
187
188 int order = 20;
189 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, init_features, &order));
190 librbd::Image image;
191 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
192
193 if (enable_mirroring) {
194 ASSERT_EQ(0, image.mirror_image_enable());
195 }
196
197 ASSERT_EQ(expected_r, image.update_features(features, enable));
198
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);
202
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);
206
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));
210 }
211
212 void setup_images_with_mirror_mode(rbd_mirror_mode_t mirror_mode,
213 std::vector<uint64_t>& features_vec) {
214
215 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
216
217 int id = 1;
218 int order = 20;
219 for (const auto& features : features_vec) {
220 std::stringstream img_name("img_");
221 img_name << id++;
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));
224 }
225 }
226
227 void check_mirroring_on_mirror_mode_set(rbd_mirror_mode_t mirror_mode,
228 std::vector<rbd_mirror_image_state_t>& states_vec) {
229
230 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
231
232 std::vector< std::tuple<std::string, rbd_mirror_image_state_t> > images;
233 int id = 1;
234 for (const auto& mirror_state : states_vec) {
235 std::stringstream img_name("img_");
236 img_name << id++;
237 std::string img_name_str = img_name.str();
238 librbd::Image image;
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));
241
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);
245
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);
249
250 ASSERT_EQ(0, image.close());
251 ASSERT_EQ(0, m_rbd.remove(m_ioctx, img_name_str.c_str()));
252 }
253 }
254
255 void check_remove_image(rbd_mirror_mode_t mirror_mode, uint64_t features,
256 bool enable_mirroring, bool demote = false) {
257
258 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
259
260 int order = 20;
261 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
262 &order));
263 librbd::Image image;
264 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
265
266 if (enable_mirroring) {
267 ASSERT_EQ(0, image.mirror_image_enable());
268 }
269
270 if (demote) {
271 ASSERT_EQ(0, image.mirror_image_demote());
272 ASSERT_EQ(0, image.mirror_image_disable(true));
273 }
274
275 image.close();
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));
278 }
279
280 void check_trash_move_restore(rbd_mirror_mode_t mirror_mode,
281 bool enable_mirroring) {
282
283 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
284
285 int order = 20;
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,
288 &order));
289 librbd::Image image;
290 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
291
292 if (enable_mirroring) {
293 ASSERT_EQ(0, image.mirror_image_enable());
294 }
295
296 std::string image_id;
297 ASSERT_EQ(0, image.get_id(&image_id));
298 image.close();
299
300 ASSERT_EQ(0, m_rbd.trash_move(m_ioctx, image_name.c_str(), 100));
301
302 ASSERT_EQ(0, m_rbd.open_by_id(m_ioctx, image, image_id.c_str(), NULL));
303
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);
307
308 ASSERT_EQ(0, m_rbd.trash_restore(m_ioctx, image_id.c_str(), ""));
309
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);
313 } else {
314 ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_DISABLED);
315 }
316
317 image.close();
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));
320 }
321
322 void setup_mirror_peer(librados::IoCtx &io_ctx, librbd::Image &image) {
323 ASSERT_EQ(0, image.snap_create("sync-point-snap"));
324
325 std::string image_id;
326 ASSERT_EQ(0, get_image_id(image, &image_id));
327
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);
331
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());
336
337 bufferlist client_data_bl;
338 encode(client_data, client_data_bl);
339 ASSERT_EQ(0, journaler.register_client(client_data_bl));
340
341 C_SaferCond shut_down_ctx;
342 journaler.shut_down(&shut_down_ctx);
343 ASSERT_EQ(0, shut_down_ctx.wait());
344 }
345
346 };
347
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);
355 }
356
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);
364 }
365
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);
373 }
374
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);
382 }
383
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);
391 }
392
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);
400 }
401
402 TEST_F(TestMirroring, DisableImageMirrorWithPeer) {
403 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
404
405 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
406
407 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
408 int order = 20;
409 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
410 &order));
411
412 librbd::Image image;
413 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
414 ASSERT_EQ(0, image.mirror_image_enable());
415
416 setup_mirror_peer(m_ioctx, image);
417
418 ASSERT_EQ(0, image.mirror_image_disable(false));
419
420 std::vector<librbd::snap_info_t> snaps;
421 ASSERT_EQ(0, image.snap_list(snaps));
422 ASSERT_TRUE(snaps.empty());
423
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);
428
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);
432
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));
436 }
437
438 TEST_F(TestMirroring, DisableJournalingWithPeer) {
439 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
440
441 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
442
443 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
444 int order = 20;
445 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
446 &order));
447
448 librbd::Image image;
449 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
450
451 setup_mirror_peer(m_ioctx, image);
452
453 ASSERT_EQ(0, image.update_features(RBD_FEATURE_JOURNALING, false));
454
455 std::vector<librbd::snap_info_t> snaps;
456 ASSERT_EQ(0, image.snap_list(snaps));
457 ASSERT_TRUE(snaps.empty());
458
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);
463
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);
467
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));
471 }
472
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);
479 }
480
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);
488 }
489
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);
497 }
498
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);
506 }
507
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);
514 }
515
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);
522 }
523
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);
531 }
532
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);
540 }
541
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);
549 }
550
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);
559 }
560
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);
569 }
570
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);
575
576 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec);
577
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);
582 }
583
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);
588
589 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
590
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);
595 }
596
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);
601
602 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec);
603
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);
608 }
609
610
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);
615
616 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
617
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);
622 }
623
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);
628
629 setup_images_with_mirror_mode(RBD_MIRROR_MODE_IMAGE, features_vec);
630
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);
635 }
636
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);
641
642 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
643
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));
647
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);
652 }
653
654 TEST_F(TestMirroring, RemoveImage_With_MirrorImageEnabled) {
655 check_remove_image(RBD_MIRROR_MODE_IMAGE,
656 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
657 true);
658 }
659
660 TEST_F(TestMirroring, RemoveImage_With_MirrorImageDisabled) {
661 check_remove_image(RBD_MIRROR_MODE_IMAGE,
662 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
663 false);
664 }
665
666 TEST_F(TestMirroring, RemoveImage_With_ImageWithoutJournal) {
667 check_remove_image(RBD_MIRROR_MODE_IMAGE,
668 RBD_FEATURE_EXCLUSIVE_LOCK,
669 false);
670 }
671
672 TEST_F(TestMirroring, RemoveImage_With_MirrorImageDemoted) {
673 check_remove_image(RBD_MIRROR_MODE_IMAGE,
674 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
675 true, true);
676 }
677
678 TEST_F(TestMirroring, TrashMoveRestore_PoolMode) {
679 check_trash_move_restore(RBD_MIRROR_MODE_POOL, false);
680 }
681
682 TEST_F(TestMirroring, TrashMoveRestore_ImageMode_MirroringDisabled) {
683 check_trash_move_restore(RBD_MIRROR_MODE_IMAGE, false);
684 }
685
686 TEST_F(TestMirroring, TrashMoveRestore_ImageMode_MirroringEnabled) {
687 check_trash_move_restore(RBD_MIRROR_MODE_IMAGE, true);
688 }
689
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);
694
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());
699
700 last_read = images.rbegin()->first;
701 images.clear();
702 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 2, &images));
703 ASSERT_EQ(2U, images.size());
704
705 last_read = images.rbegin()->first;
706 images.clear();
707 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 4096, &images));
708 ASSERT_EQ(1U, images.size());
709
710 last_read = images.rbegin()->first;
711 images.clear();
712 ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 4096, &images));
713 ASSERT_EQ(0U, images.size());
714 }
715
716 TEST_F(TestMirroring, RemoveBootstrapped)
717 {
718 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
719
720 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
721 int order = 20;
722 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
723 &order));
724 librbd::Image image;
725 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
726
727 librbd::NoOpProgressContext no_op;
728 ASSERT_EQ(-EBUSY, librbd::api::Image<>::remove(m_ioctx, image_name, no_op));
729
730 // simulate the image is open by rbd-mirror bootstrap
731 uint64_t handle;
732 struct MirrorWatcher : public librados::WatchCtx2 {
733 explicit MirrorWatcher(librados::IoCtx &ioctx) : m_ioctx(ioctx) {
734 }
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
738 m_notified = true;
739 m_ioctx.notify_ack(RBD_MIRRORING, notify_id, cookie, bl);
740 }
741 void handle_error(uint64_t cookie, int err) override {
742 }
743 librados::IoCtx &m_ioctx;
744 bool m_notified = false;
745 } watcher(m_ioctx);
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());
753 }
754
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());
759 }
760
761 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
762
763 // create mirror images
764 int order = 20;
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,
770 &order));
771
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());
775 }
776
777 // demote all images
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()));
782 }
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());
787 aio_comp->release();
788 }
789 aio_comps.clear();
790
791 // verify demotions
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);
797 }
798
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()));
803 }
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());
808 aio_comp->release();
809 }
810
811 // verify promotions
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);
817 }
818 }
819
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());
824 }
825
826 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
827
828 // create mirror images
829 int order = 20;
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,
835 &order));
836
837 images.emplace_back();
838 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
839 }
840
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()),
848 aio_comps.back()));
849 }
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());
854 aio_comp->release();
855 }
856 aio_comps.clear();
857
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);
862 }
863 }
864
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());
869 }
870
871 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
872
873 // create mirror images
874 int order = 20;
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,
880 &order));
881
882 images.emplace_back();
883 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
884 }
885
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()),
893 aio_comps.back()));
894 }
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());
899 aio_comp->release();
900 }
901 aio_comps.clear();
902
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);
912 }
913 }
914
915 TEST_F(TestMirroring, SiteName) {
916 REQUIRE(!is_librados_test_stub(_rados));
917
918 const std::string expected_site_name("us-east-1a");
919 ASSERT_EQ(0, m_rbd.mirror_site_name_set(_rados, expected_site_name));
920
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);
924
925 ASSERT_EQ(0, m_rbd.mirror_site_name_set(_rados, ""));
926
927 std::string fsid;
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);
931 }
932
933 TEST_F(TestMirroring, Bootstrap) {
934 REQUIRE(!is_librados_test_stub(_rados));
935
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));
939
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));
942
943 bufferlist token_b64_bl;
944 token_b64_bl.append(token_b64);
945
946 bufferlist token_bl;
947 token_bl.decode_base64(token_b64_bl);
948
949 // cannot import token into same cluster
950 ASSERT_EQ(-EINVAL,
951 m_rbd.mirror_peer_bootstrap_import(
952 m_ioctx, RBD_MIRROR_PEER_DIRECTION_RX, token_b64));
953 }