]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librbd/test_mirroring.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / test / librbd / test_mirroring.cc
CommitLineData
7c673cae
FG
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"
9f95a23c
TL
22#include "librbd/api/Image.h"
23#include "librbd/api/Namespace.h"
7c673cae
FG
24#include "librbd/io/AioCompletion.h"
25#include "librbd/io/ImageRequest.h"
7c673cae 26#include "librbd/journal/Types.h"
9f95a23c
TL
27#include "librbd/mirror/snapshot/GetImageStateRequest.h"
28#include "librbd/mirror/snapshot/RemoveImageStateRequest.h"
29#include "librbd/mirror/snapshot/SetImageStateRequest.h"
30#include "librbd/mirror/snapshot/UnlinkPeerRequest.h"
7c673cae
FG
31#include "journal/Journaler.h"
32#include "journal/Settings.h"
9f95a23c 33#include "common/Cond.h"
7c673cae
FG
34#include <boost/scope_exit.hpp>
35#include <boost/assign/list_of.hpp>
36#include <utility>
37#include <vector>
38
20effc67
TL
39using namespace std;
40
7c673cae
FG
41void register_test_mirroring() {
42}
43
9f95a23c
TL
44namespace librbd {
45
46static bool operator==(const mirror_peer_site_t& lhs,
47 const mirror_peer_site_t& rhs) {
48 return (lhs.uuid == rhs.uuid &&
49 lhs.direction == rhs.direction &&
50 lhs.site_name == rhs.site_name &&
51 lhs.client_name == rhs.client_name &&
52 lhs.last_seen == rhs.last_seen);
53}
54
55static std::ostream& operator<<(std::ostream& os,
56 const mirror_peer_site_t& rhs) {
57 os << "uuid=" << rhs.uuid << ", "
58 << "direction=" << rhs.direction << ", "
59 << "site_name=" << rhs.site_name << ", "
60 << "client_name=" << rhs.client_name << ", "
61 << "last_seen=" << rhs.last_seen;
62 return os;
63}
64
65};
66
7c673cae
FG
67class TestMirroring : public TestFixture {
68public:
69
70 TestMirroring() {}
71
72
73 void TearDown() override {
74 unlock_image();
75
76 TestFixture::TearDown();
77 }
78
79 void SetUp() override {
80 ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), m_ioctx));
81 }
82
83 std::string image_name = "mirrorimg1";
84
9f95a23c
TL
85 int get_local_mirror_image_site_status(
86 const librbd::mirror_image_global_status_t& status,
87 librbd::mirror_image_site_status_t* local_status) {
88 auto it = std::find_if(status.site_statuses.begin(),
89 status.site_statuses.end(),
90 [](auto& site_status) {
91 return (site_status.mirror_uuid ==
92 RBD_MIRROR_IMAGE_STATUS_LOCAL_MIRROR_UUID);
93 });
94 if (it == status.site_statuses.end()) {
95 return -ENOENT;
96 }
97
98 *local_status = *it;
99 return 0;
100 }
101
102 void check_mirror_image_enable(
103 rbd_mirror_mode_t mirror_mode, uint64_t features, int expected_r,
104 rbd_mirror_image_state_t mirror_state,
105 rbd_mirror_image_mode_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL) {
7c673cae
FG
106
107 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
108
109 int order = 20;
110 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
111 librbd::Image image;
112 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
113
114 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
115
9f95a23c 116 ASSERT_EQ(expected_r, image.mirror_image_enable2(mirror_image_mode));
7c673cae
FG
117
118 librbd::mirror_image_info_t mirror_image;
119 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
120 ASSERT_EQ(mirror_state, mirror_image.state);
121
9f95a23c
TL
122 if (mirror_image.state == RBD_MIRROR_IMAGE_ENABLED) {
123 librbd::mirror_image_mode_t mode;
124 ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
125 ASSERT_EQ(mirror_image_mode, mode);
126 }
127
128 librbd::mirror_image_global_status_t status;
129 ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
130 librbd::mirror_image_site_status_t local_status;
131 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
132 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae 133
11fdf7f2
TL
134 std::string instance_id;
135 ASSERT_EQ(mirror_state == RBD_MIRROR_IMAGE_ENABLED ? -ENOENT : -EINVAL,
136 image.mirror_image_get_instance_id(&instance_id));
137
7c673cae
FG
138 ASSERT_EQ(0, image.close());
139 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
140 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
141 }
142
143 void check_mirror_image_disable(rbd_mirror_mode_t mirror_mode,
144 uint64_t features,
145 int expected_r,
146 rbd_mirror_image_state_t mirror_state) {
147
148 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
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 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
156
157 ASSERT_EQ(expected_r, image.mirror_image_disable(false));
158
159 librbd::mirror_image_info_t mirror_image;
160 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
161 ASSERT_EQ(mirror_state, mirror_image.state);
162
9f95a23c
TL
163 librbd::mirror_image_global_status_t status;
164 ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
165 librbd::mirror_image_site_status_t local_status;
166 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
167 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae 168
11fdf7f2
TL
169 std::string instance_id;
170 ASSERT_EQ(mirror_state == RBD_MIRROR_IMAGE_ENABLED ? -ENOENT : -EINVAL,
171 image.mirror_image_get_instance_id(&instance_id));
172
7c673cae
FG
173 ASSERT_EQ(0, image.close());
174 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
175 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
176 }
177
178 void check_mirroring_status(size_t *images_count) {
9f95a23c
TL
179 std::map<std::string, librbd::mirror_image_global_status_t> images;
180 ASSERT_EQ(0, m_rbd.mirror_image_global_status_list(m_ioctx, "", 4096,
181 &images));
7c673cae
FG
182
183 std::map<librbd::mirror_image_status_state_t, int> states;
184 ASSERT_EQ(0, m_rbd.mirror_image_status_summary(m_ioctx, &states));
185 size_t states_count = 0;
186 for (auto &s : states) {
187 states_count += s.second;
188 }
189 ASSERT_EQ(images.size(), states_count);
190
191 *images_count = images.size();
11fdf7f2
TL
192
193 std::map<std::string, std::string> instance_ids;
194 ASSERT_EQ(0, m_rbd.mirror_image_instance_id_list(m_ioctx, "", 4096,
195 &instance_ids));
196 ASSERT_TRUE(instance_ids.empty());
7c673cae
FG
197 }
198
199 void check_mirroring_on_create(uint64_t features,
200 rbd_mirror_mode_t mirror_mode,
201 rbd_mirror_image_state_t mirror_state) {
202
203 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
204
205 size_t mirror_images_count = 0;
206 check_mirroring_status(&mirror_images_count);
207
208 int order = 20;
209 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
210 librbd::Image image;
211 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
212
213 librbd::mirror_image_info_t mirror_image;
214 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
215 ASSERT_EQ(mirror_state, mirror_image.state);
216
9f95a23c
TL
217 librbd::mirror_image_global_status_t status;
218 ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
219 librbd::mirror_image_site_status_t local_status;
220 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
221 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae
FG
222
223 size_t mirror_images_new_count = 0;
224 check_mirroring_status(&mirror_images_new_count);
225 if (mirror_mode == RBD_MIRROR_MODE_POOL &&
226 mirror_state == RBD_MIRROR_IMAGE_ENABLED) {
227 ASSERT_EQ(mirror_images_new_count, mirror_images_count + 1);
228 } else {
229 ASSERT_EQ(mirror_images_new_count, mirror_images_count);
230 }
231
232 ASSERT_EQ(0, image.close());
233 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
234 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
235
236 check_mirroring_status(&mirror_images_new_count);
237 ASSERT_EQ(mirror_images_new_count, mirror_images_count);
238 }
239
9f95a23c
TL
240 void check_mirroring_on_update_features(
241 uint64_t init_features, bool enable, bool enable_mirroring,
242 uint64_t features, int expected_r, rbd_mirror_mode_t mirror_mode,
243 rbd_mirror_image_state_t mirror_state,
244 rbd_mirror_image_mode_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL) {
7c673cae
FG
245
246 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
247
248 int order = 20;
249 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, init_features, &order));
250 librbd::Image image;
251 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
252
253 if (enable_mirroring) {
9f95a23c 254 ASSERT_EQ(0, image.mirror_image_enable2(mirror_image_mode));
7c673cae
FG
255 }
256
257 ASSERT_EQ(expected_r, image.update_features(features, enable));
258
259 librbd::mirror_image_info_t mirror_image;
260 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
261 ASSERT_EQ(mirror_state, mirror_image.state);
262
9f95a23c
TL
263 if (mirror_image.state == RBD_MIRROR_IMAGE_ENABLED) {
264 librbd::mirror_image_mode_t mode;
265 ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
266 ASSERT_EQ(mirror_image_mode, mode);
267 }
268
269 librbd::mirror_image_global_status_t status;
270 ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
271 librbd::mirror_image_site_status_t local_status;
272 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
273 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae
FG
274
275 ASSERT_EQ(0, 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 setup_images_with_mirror_mode(rbd_mirror_mode_t mirror_mode,
281 std::vector<uint64_t>& features_vec) {
282
283 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
284
285 int id = 1;
286 int order = 20;
287 for (const auto& features : features_vec) {
288 std::stringstream img_name("img_");
289 img_name << id++;
290 std::string img_name_str = img_name.str();
291 ASSERT_EQ(0, m_rbd.create2(m_ioctx, img_name_str.c_str(), 2048, features, &order));
292 }
293 }
294
295 void check_mirroring_on_mirror_mode_set(rbd_mirror_mode_t mirror_mode,
296 std::vector<rbd_mirror_image_state_t>& states_vec) {
297
298 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
299
300 std::vector< std::tuple<std::string, rbd_mirror_image_state_t> > images;
301 int id = 1;
302 for (const auto& mirror_state : states_vec) {
303 std::stringstream img_name("img_");
304 img_name << id++;
305 std::string img_name_str = img_name.str();
306 librbd::Image image;
307 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, img_name_str.c_str()));
308 images.push_back(std::make_tuple(img_name_str, mirror_state));
309
310 librbd::mirror_image_info_t mirror_image;
311 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
312 ASSERT_EQ(mirror_state, mirror_image.state);
313
9f95a23c
TL
314 librbd::mirror_image_global_status_t status;
315 ASSERT_EQ(0, image.mirror_image_get_global_status(&status,
316 sizeof(status)));
317 librbd::mirror_image_site_status_t local_status;
318 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
319 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae
FG
320
321 ASSERT_EQ(0, image.close());
322 ASSERT_EQ(0, m_rbd.remove(m_ioctx, img_name_str.c_str()));
323 }
324 }
325
326 void check_remove_image(rbd_mirror_mode_t mirror_mode, uint64_t features,
327 bool enable_mirroring, bool demote = false) {
328
329 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
330
331 int order = 20;
332 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
333 &order));
334 librbd::Image image;
335 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
336
337 if (enable_mirroring) {
9f95a23c 338 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_JOURNAL));
7c673cae
FG
339 }
340
341 if (demote) {
342 ASSERT_EQ(0, image.mirror_image_demote());
343 ASSERT_EQ(0, image.mirror_image_disable(true));
344 }
345
346 image.close();
347 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
348 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
349 }
350
11fdf7f2
TL
351 void check_trash_move_restore(rbd_mirror_mode_t mirror_mode,
352 bool enable_mirroring) {
353
354 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
355
356 int order = 20;
357 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
358 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
359 &order));
360 librbd::Image image;
361 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
362
363 if (enable_mirroring) {
9f95a23c 364 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_JOURNAL));
11fdf7f2
TL
365 }
366
367 std::string image_id;
368 ASSERT_EQ(0, image.get_id(&image_id));
369 image.close();
370
371 ASSERT_EQ(0, m_rbd.trash_move(m_ioctx, image_name.c_str(), 100));
372
373 ASSERT_EQ(0, m_rbd.open_by_id(m_ioctx, image, image_id.c_str(), NULL));
374
375 librbd::mirror_image_info_t mirror_image;
376 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
377 ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_DISABLED);
378
379 ASSERT_EQ(0, m_rbd.trash_restore(m_ioctx, image_id.c_str(), ""));
380
381 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
382 if (mirror_mode == RBD_MIRROR_MODE_POOL) {
383 ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_ENABLED);
384 } else {
385 ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_DISABLED);
386 }
387
388 image.close();
389 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
390 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
391 }
392
7c673cae
FG
393 void setup_mirror_peer(librados::IoCtx &io_ctx, librbd::Image &image) {
394 ASSERT_EQ(0, image.snap_create("sync-point-snap"));
395
396 std::string image_id;
397 ASSERT_EQ(0, get_image_id(image, &image_id));
398
399 librbd::journal::MirrorPeerClientMeta peer_client_meta(
400 "remote-image-id", {{{}, "sync-point-snap", boost::none}}, {});
401 librbd::journal::ClientData client_data(peer_client_meta);
402
9f95a23c 403 journal::Journaler journaler(io_ctx, image_id, "peer-client", {}, nullptr);
7c673cae
FG
404 C_SaferCond init_ctx;
405 journaler.init(&init_ctx);
406 ASSERT_EQ(-ENOENT, init_ctx.wait());
407
408 bufferlist client_data_bl;
11fdf7f2 409 encode(client_data, client_data_bl);
7c673cae
FG
410 ASSERT_EQ(0, journaler.register_client(client_data_bl));
411
412 C_SaferCond shut_down_ctx;
413 journaler.shut_down(&shut_down_ctx);
414 ASSERT_EQ(0, shut_down_ctx.wait());
415 }
416
417};
418
419TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage) {
420 uint64_t features = 0;
421 features |= RBD_FEATURE_OBJECT_MAP;
422 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
423 features |= RBD_FEATURE_JOURNALING;
424 check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
9f95a23c 425 RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_JOURNAL);
7c673cae
FG
426}
427
428TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) {
429 uint64_t features = 0;
430 features |= RBD_FEATURE_OBJECT_MAP;
431 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
432 features |= RBD_FEATURE_JOURNALING;
433 check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
9f95a23c 434 RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_JOURNAL);
7c673cae
FG
435}
436
437TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled) {
438 uint64_t features = 0;
439 features |= RBD_FEATURE_OBJECT_MAP;
440 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
441 features |= RBD_FEATURE_JOURNALING;
442 check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL,
443 RBD_MIRROR_IMAGE_DISABLED);
444}
445
446TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeImage) {
447 uint64_t features = 0;
448 features |= RBD_FEATURE_OBJECT_MAP;
449 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
450 features |= RBD_FEATURE_JOURNALING;
451 check_mirror_image_disable(RBD_MIRROR_MODE_IMAGE, features, 0,
452 RBD_MIRROR_IMAGE_DISABLED);
453}
454
9f95a23c
TL
455TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeImage_NoObjectMap) {
456 uint64_t features = 0;
457 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
458 features |= RBD_FEATURE_JOURNALING;
459 check_mirror_image_disable(RBD_MIRROR_MODE_IMAGE, features, 0,
460 RBD_MIRROR_IMAGE_DISABLED);
461}
462
7c673cae
FG
463TEST_F(TestMirroring, DisableImageMirror_In_MirrorModePool) {
464 uint64_t features = 0;
465 features |= RBD_FEATURE_OBJECT_MAP;
466 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
467 features |= RBD_FEATURE_JOURNALING;
468 check_mirror_image_disable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
469 RBD_MIRROR_IMAGE_ENABLED);
470}
471
472TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeDisabled) {
473 uint64_t features = 0;
474 features |= RBD_FEATURE_OBJECT_MAP;
475 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
476 features |= RBD_FEATURE_JOURNALING;
477 check_mirror_image_disable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL,
478 RBD_MIRROR_IMAGE_DISABLED);
479}
480
481TEST_F(TestMirroring, DisableImageMirrorWithPeer) {
482 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
483
484 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
485
486 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
487 int order = 20;
488 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
489 &order));
490
491 librbd::Image image;
492 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
9f95a23c 493 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_JOURNAL));
7c673cae
FG
494
495 setup_mirror_peer(m_ioctx, image);
496
497 ASSERT_EQ(0, image.mirror_image_disable(false));
498
499 std::vector<librbd::snap_info_t> snaps;
500 ASSERT_EQ(0, image.snap_list(snaps));
501 ASSERT_TRUE(snaps.empty());
502
503 librbd::mirror_image_info_t mirror_image;
504 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
505 sizeof(mirror_image)));
506 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, mirror_image.state);
507
9f95a23c
TL
508 librbd::mirror_image_global_status_t status;
509 ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
510 librbd::mirror_image_site_status_t local_status;
511 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
512 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae
FG
513
514 ASSERT_EQ(0, image.close());
515 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
516 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
517}
518
519TEST_F(TestMirroring, DisableJournalingWithPeer) {
520 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
521
522 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
523
524 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
525 int order = 20;
526 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
527 &order));
528
529 librbd::Image image;
530 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
531
532 setup_mirror_peer(m_ioctx, image);
533
534 ASSERT_EQ(0, image.update_features(RBD_FEATURE_JOURNALING, false));
535
536 std::vector<librbd::snap_info_t> snaps;
537 ASSERT_EQ(0, image.snap_list(snaps));
538 ASSERT_TRUE(snaps.empty());
539
540 librbd::mirror_image_info_t mirror_image;
541 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
542 sizeof(mirror_image)));
543 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, mirror_image.state);
544
9f95a23c
TL
545 librbd::mirror_image_global_status_t status;
546 ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
547 librbd::mirror_image_site_status_t local_status;
548 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
549 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
7c673cae
FG
550
551 ASSERT_EQ(0, image.close());
552 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
553 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
554}
555
9f95a23c 556TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled_WithoutJournaling) {
7c673cae
FG
557 uint64_t features = 0;
558 features |= RBD_FEATURE_OBJECT_MAP;
559 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
560 check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL,
561 RBD_MIRROR_IMAGE_DISABLED);
562}
563
9f95a23c
TL
564TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool_WithoutJournaling) {
565 uint64_t features = 0;
566 features |= RBD_FEATURE_OBJECT_MAP;
567 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
568 check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
569 RBD_MIRROR_IMAGE_DISABLED);
570}
571
572TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutJournaling) {
573 uint64_t features = 0;
574 features |= RBD_FEATURE_OBJECT_MAP;
575 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
576 check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
577 RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_SNAPSHOT);
578}
579
580TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutExclusiveLock) {
581 uint64_t features = 0;
582 check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
583 RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_SNAPSHOT);
584}
585
7c673cae
FG
586TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) {
587 uint64_t features = 0;
588 features |= RBD_FEATURE_OBJECT_MAP;
589 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
590 features |= RBD_FEATURE_JOURNALING;
591 check_mirroring_on_create(features, RBD_MIRROR_MODE_DISABLED,
592 RBD_MIRROR_IMAGE_DISABLED);
593}
594
595TEST_F(TestMirroring, CreateImage_In_MirrorModeImage) {
596 uint64_t features = 0;
597 features |= RBD_FEATURE_OBJECT_MAP;
598 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
599 features |= RBD_FEATURE_JOURNALING;
600 check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE,
601 RBD_MIRROR_IMAGE_DISABLED);
602}
603
604TEST_F(TestMirroring, CreateImage_In_MirrorModePool) {
605 uint64_t features = 0;
606 features |= RBD_FEATURE_OBJECT_MAP;
607 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
608 features |= RBD_FEATURE_JOURNALING;
609 check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL,
610 RBD_MIRROR_IMAGE_ENABLED);
611}
612
613TEST_F(TestMirroring, CreateImage_In_MirrorModePool_WithoutJournaling) {
614 uint64_t features = 0;
615 features |= RBD_FEATURE_OBJECT_MAP;
616 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
617 check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL,
618 RBD_MIRROR_IMAGE_DISABLED);
619}
620
621TEST_F(TestMirroring, CreateImage_In_MirrorModeImage_WithoutJournaling) {
622 uint64_t features = 0;
623 features |= RBD_FEATURE_OBJECT_MAP;
624 features |= RBD_FEATURE_EXCLUSIVE_LOCK;
625 check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE,
626 RBD_MIRROR_IMAGE_DISABLED);
627}
628
629TEST_F(TestMirroring, EnableJournaling_In_MirrorModeDisabled) {
630 uint64_t init_features = 0;
631 init_features |= RBD_FEATURE_OBJECT_MAP;
632 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
633 uint64_t features = RBD_FEATURE_JOURNALING;
634 check_mirroring_on_update_features(init_features, true, false, features, 0,
635 RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_IMAGE_DISABLED);
636}
637
638TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage) {
639 uint64_t init_features = 0;
640 init_features |= RBD_FEATURE_OBJECT_MAP;
641 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
642 uint64_t features = RBD_FEATURE_JOURNALING;
643 check_mirroring_on_update_features(init_features, true, false, features, 0,
644 RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_DISABLED);
645}
646
9f95a23c
TL
647TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage_SnapshotMirroringEnabled) {
648 uint64_t init_features = 0;
649 init_features |= RBD_FEATURE_OBJECT_MAP;
650 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
651 uint64_t features = RBD_FEATURE_JOURNALING;
652 check_mirroring_on_update_features(init_features, true, true, features,
653 0, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED,
654 RBD_MIRROR_IMAGE_MODE_SNAPSHOT);
655}
656
7c673cae
FG
657TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) {
658 uint64_t init_features = 0;
659 init_features |= RBD_FEATURE_OBJECT_MAP;
660 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
661 uint64_t features = RBD_FEATURE_JOURNALING;
662 check_mirroring_on_update_features(init_features, true, false, features, 0,
9f95a23c
TL
663 RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED,
664 RBD_MIRROR_IMAGE_MODE_JOURNAL);
7c673cae
FG
665}
666
667TEST_F(TestMirroring, DisableJournaling_In_MirrorModePool) {
668 uint64_t init_features = 0;
669 init_features |= RBD_FEATURE_OBJECT_MAP;
670 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
671 init_features |= RBD_FEATURE_JOURNALING;
672 uint64_t features = RBD_FEATURE_JOURNALING;
673 check_mirroring_on_update_features(init_features, false, false, features, 0,
674 RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_DISABLED);
675}
676
677TEST_F(TestMirroring, DisableJournaling_In_MirrorModeImage) {
678 uint64_t init_features = 0;
679 init_features |= RBD_FEATURE_OBJECT_MAP;
680 init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
681 init_features |= RBD_FEATURE_JOURNALING;
682 uint64_t features = RBD_FEATURE_JOURNALING;
9f95a23c
TL
683 check_mirroring_on_update_features(init_features, false, true, features,
684 -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED,
685 RBD_MIRROR_IMAGE_MODE_JOURNAL);
7c673cae
FG
686}
687
688TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_PoolMode) {
689 std::vector<uint64_t> features_vec;
690 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
691 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
692
693 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec);
694
695 std::vector<rbd_mirror_image_state_t> states_vec;
696 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
697 states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED);
698 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL, states_vec);
699}
700
701TEST_F(TestMirroring, MirrorModeSet_PoolMode_To_DisabledMode) {
702 std::vector<uint64_t> features_vec;
703 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
704 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
705
706 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
707
708 std::vector<rbd_mirror_image_state_t> states_vec;
709 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
710 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
711 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED, states_vec);
712}
713
714TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_ImageMode) {
715 std::vector<uint64_t> features_vec;
716 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
717 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
718
719 setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec);
720
721 std::vector<rbd_mirror_image_state_t> states_vec;
722 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
723 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
724 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE, states_vec);
725}
726
727
728TEST_F(TestMirroring, MirrorModeSet_PoolMode_To_ImageMode) {
729 std::vector<uint64_t> features_vec;
730 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
731 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
732
733 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
734
735 std::vector<rbd_mirror_image_state_t> states_vec;
736 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
737 states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED);
738 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE, states_vec);
739}
740
741TEST_F(TestMirroring, MirrorModeSet_ImageMode_To_PoolMode) {
742 std::vector<uint64_t> features_vec;
743 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
744 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
745
746 setup_images_with_mirror_mode(RBD_MIRROR_MODE_IMAGE, features_vec);
747
748 std::vector<rbd_mirror_image_state_t> states_vec;
749 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
750 states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED);
751 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL, states_vec);
752}
753
754TEST_F(TestMirroring, MirrorModeSet_ImageMode_To_DisabledMode) {
755 std::vector<uint64_t> features_vec;
756 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK);
757 features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
758
759 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
760
761 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
762 ASSERT_EQ(-EINVAL, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
763 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
764
765 std::vector<rbd_mirror_image_state_t> states_vec;
766 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
767 states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED);
768 check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED, states_vec);
769}
770
771TEST_F(TestMirroring, RemoveImage_With_MirrorImageEnabled) {
772 check_remove_image(RBD_MIRROR_MODE_IMAGE,
773 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
774 true);
775}
776
777TEST_F(TestMirroring, RemoveImage_With_MirrorImageDisabled) {
778 check_remove_image(RBD_MIRROR_MODE_IMAGE,
779 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
780 false);
781}
782
783TEST_F(TestMirroring, RemoveImage_With_ImageWithoutJournal) {
784 check_remove_image(RBD_MIRROR_MODE_IMAGE,
785 RBD_FEATURE_EXCLUSIVE_LOCK,
786 false);
787}
788
789TEST_F(TestMirroring, RemoveImage_With_MirrorImageDemoted) {
790 check_remove_image(RBD_MIRROR_MODE_IMAGE,
791 RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING,
792 true, true);
793}
794
11fdf7f2
TL
795TEST_F(TestMirroring, TrashMoveRestore_PoolMode) {
796 check_trash_move_restore(RBD_MIRROR_MODE_POOL, false);
797}
798
799TEST_F(TestMirroring, TrashMoveRestore_ImageMode_MirroringDisabled) {
800 check_trash_move_restore(RBD_MIRROR_MODE_IMAGE, false);
801}
802
803TEST_F(TestMirroring, TrashMoveRestore_ImageMode_MirroringEnabled) {
804 check_trash_move_restore(RBD_MIRROR_MODE_IMAGE, true);
805}
806
7c673cae
FG
807TEST_F(TestMirroring, MirrorStatusList) {
808 std::vector<uint64_t>
809 features_vec(5, RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING);
810 setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec);
811
812 std::string last_read = "";
9f95a23c
TL
813 std::map<std::string, librbd::mirror_image_global_status_t> images;
814 ASSERT_EQ(0, m_rbd.mirror_image_global_status_list(m_ioctx, last_read, 2,
815 &images));
7c673cae
FG
816 ASSERT_EQ(2U, images.size());
817
818 last_read = images.rbegin()->first;
819 images.clear();
9f95a23c
TL
820 ASSERT_EQ(0, m_rbd.mirror_image_global_status_list(m_ioctx, last_read, 2,
821 &images));
7c673cae
FG
822 ASSERT_EQ(2U, images.size());
823
824 last_read = images.rbegin()->first;
825 images.clear();
9f95a23c
TL
826 ASSERT_EQ(0, m_rbd.mirror_image_global_status_list(m_ioctx, last_read, 4096,
827 &images));
7c673cae
FG
828 ASSERT_EQ(1U, images.size());
829
830 last_read = images.rbegin()->first;
831 images.clear();
9f95a23c
TL
832 ASSERT_EQ(0, m_rbd.mirror_image_global_status_list(m_ioctx, last_read, 4096,
833 &images));
7c673cae
FG
834 ASSERT_EQ(0U, images.size());
835}
836
837TEST_F(TestMirroring, RemoveBootstrapped)
838{
839 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
840
841 uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
842 int order = 20;
843 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
844 &order));
845 librbd::Image image;
846 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
11fdf7f2
TL
847
848 librbd::NoOpProgressContext no_op;
849 ASSERT_EQ(-EBUSY, librbd::api::Image<>::remove(m_ioctx, image_name, no_op));
7c673cae
FG
850
851 // simulate the image is open by rbd-mirror bootstrap
852 uint64_t handle;
853 struct MirrorWatcher : public librados::WatchCtx2 {
11fdf7f2 854 explicit MirrorWatcher(librados::IoCtx &ioctx) : m_ioctx(ioctx) {
7c673cae
FG
855 }
856 void handle_notify(uint64_t notify_id, uint64_t cookie,
857 uint64_t notifier_id, bufferlist& bl) override {
858 // received IMAGE_UPDATED notification from remove
859 m_notified = true;
860 m_ioctx.notify_ack(RBD_MIRRORING, notify_id, cookie, bl);
861 }
862 void handle_error(uint64_t cookie, int err) override {
863 }
864 librados::IoCtx &m_ioctx;
865 bool m_notified = false;
866 } watcher(m_ioctx);
867 ASSERT_EQ(0, m_ioctx.create(RBD_MIRRORING, false));
868 ASSERT_EQ(0, m_ioctx.watch2(RBD_MIRRORING, &handle, &watcher));
869 // now remove should succeed
11fdf7f2 870 ASSERT_EQ(0, librbd::api::Image<>::remove(m_ioctx, image_name, no_op));
7c673cae
FG
871 ASSERT_EQ(0, m_ioctx.unwatch2(handle));
872 ASSERT_TRUE(watcher.m_notified);
873 ASSERT_EQ(0, image.close());
874}
875
876TEST_F(TestMirroring, AioPromoteDemote) {
877 std::list<std::string> image_names;
878 for (size_t idx = 0; idx < 10; ++idx) {
879 image_names.push_back(get_temp_image_name());
880 }
881
882 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
883
884 // create mirror images
885 int order = 20;
886 std::list<librbd::Image> images;
887 for (auto &image_name : image_names) {
888 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048,
889 RBD_FEATURE_EXCLUSIVE_LOCK |
890 RBD_FEATURE_JOURNALING,
891 &order));
892
893 images.emplace_back();
894 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
9f95a23c
TL
895 ASSERT_EQ(0, images.back().mirror_image_enable2(
896 RBD_MIRROR_IMAGE_MODE_JOURNAL));
7c673cae
FG
897 }
898
899 // demote all images
900 std::list<librbd::RBD::AioCompletion *> aio_comps;
901 for (auto &image : images) {
902 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
903 ASSERT_EQ(0, image.aio_mirror_image_demote(aio_comps.back()));
904 }
905 for (auto aio_comp : aio_comps) {
906 ASSERT_EQ(0, aio_comp->wait_for_complete());
907 ASSERT_EQ(1, aio_comp->is_complete());
908 ASSERT_EQ(0, aio_comp->get_return_value());
909 aio_comp->release();
910 }
911 aio_comps.clear();
912
913 // verify demotions
914 for (auto &image : images) {
915 librbd::mirror_image_info_t mirror_image;
916 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
917 sizeof(mirror_image)));
918 ASSERT_FALSE(mirror_image.primary);
919 }
920
921 // promote all images
922 for (auto &image : images) {
923 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
924 ASSERT_EQ(0, image.aio_mirror_image_promote(false, aio_comps.back()));
925 }
926 for (auto aio_comp : aio_comps) {
927 ASSERT_EQ(0, aio_comp->wait_for_complete());
928 ASSERT_EQ(1, aio_comp->is_complete());
929 ASSERT_EQ(0, aio_comp->get_return_value());
930 aio_comp->release();
931 }
932
933 // verify promotions
934 for (auto &image : images) {
935 librbd::mirror_image_info_t mirror_image;
936 ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image,
937 sizeof(mirror_image)));
938 ASSERT_TRUE(mirror_image.primary);
939 }
940}
941
942TEST_F(TestMirroring, AioGetInfo) {
943 std::list<std::string> image_names;
944 for (size_t idx = 0; idx < 10; ++idx) {
945 image_names.push_back(get_temp_image_name());
946 }
947
948 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
949
950 // create mirror images
951 int order = 20;
952 std::list<librbd::Image> images;
953 for (auto &image_name : image_names) {
954 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048,
955 RBD_FEATURE_EXCLUSIVE_LOCK |
956 RBD_FEATURE_JOURNALING,
957 &order));
958
959 images.emplace_back();
960 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
961 }
962
963 std::list<librbd::RBD::AioCompletion *> aio_comps;
964 std::list<librbd::mirror_image_info_t> infos;
965 for (auto &image : images) {
966 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
967 infos.emplace_back();
968 ASSERT_EQ(0, image.aio_mirror_image_get_info(&infos.back(),
969 sizeof(infos.back()),
970 aio_comps.back()));
971 }
972 for (auto aio_comp : aio_comps) {
973 ASSERT_EQ(0, aio_comp->wait_for_complete());
974 ASSERT_EQ(1, aio_comp->is_complete());
975 ASSERT_EQ(0, aio_comp->get_return_value());
976 aio_comp->release();
977 }
978 aio_comps.clear();
979
980 for (auto &info : infos) {
981 ASSERT_NE("", info.global_id);
982 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
983 ASSERT_TRUE(info.primary);
984 }
985}
986
987TEST_F(TestMirroring, AioGetStatus) {
988 std::list<std::string> image_names;
989 for (size_t idx = 0; idx < 10; ++idx) {
990 image_names.push_back(get_temp_image_name());
991 }
992
993 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
994
995 // create mirror images
996 int order = 20;
997 std::list<librbd::Image> images;
998 for (auto &image_name : image_names) {
999 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048,
1000 RBD_FEATURE_EXCLUSIVE_LOCK |
1001 RBD_FEATURE_JOURNALING,
1002 &order));
1003
1004 images.emplace_back();
1005 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
1006 }
1007
1008 std::list<librbd::RBD::AioCompletion *> aio_comps;
9f95a23c 1009 std::list<librbd::mirror_image_global_status_t> statuses;
7c673cae
FG
1010 for (auto &image : images) {
1011 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
1012 statuses.emplace_back();
9f95a23c
TL
1013 ASSERT_EQ(0, image.aio_mirror_image_get_global_status(
1014 &statuses.back(), sizeof(statuses.back()),
1015 aio_comps.back()));
7c673cae
FG
1016 }
1017 for (auto aio_comp : aio_comps) {
1018 ASSERT_EQ(0, aio_comp->wait_for_complete());
1019 ASSERT_EQ(1, aio_comp->is_complete());
1020 ASSERT_EQ(0, aio_comp->get_return_value());
1021 aio_comp->release();
1022 }
1023 aio_comps.clear();
1024
1025 for (auto &status : statuses) {
1026 ASSERT_NE("", status.name);
1027 ASSERT_NE("", status.info.global_id);
1028 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, status.info.state);
1029 ASSERT_TRUE(status.info.primary);
9f95a23c
TL
1030
1031 librbd::mirror_image_site_status_t local_status;
1032 ASSERT_EQ(0, get_local_mirror_image_site_status(status, &local_status));
1033 ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, local_status.state);
1034 ASSERT_EQ("status not found", local_status.description);
1035 ASSERT_FALSE(local_status.up);
1036 ASSERT_EQ(0, local_status.last_update);
7c673cae
FG
1037 }
1038}
eafe8130
TL
1039
1040TEST_F(TestMirroring, SiteName) {
1041 REQUIRE(!is_librados_test_stub(_rados));
1042
1043 const std::string expected_site_name("us-east-1a");
1044 ASSERT_EQ(0, m_rbd.mirror_site_name_set(_rados, expected_site_name));
1045
1046 std::string site_name;
1047 ASSERT_EQ(0, m_rbd.mirror_site_name_get(_rados, &site_name));
1048 ASSERT_EQ(expected_site_name, site_name);
1049
1050 ASSERT_EQ(0, m_rbd.mirror_site_name_set(_rados, ""));
1051
1052 std::string fsid;
1053 ASSERT_EQ(0, _rados.cluster_fsid(&fsid));
1054 ASSERT_EQ(0, m_rbd.mirror_site_name_get(_rados, &site_name));
1055 ASSERT_EQ(fsid, site_name);
1056}
1057
1058TEST_F(TestMirroring, Bootstrap) {
1059 REQUIRE(!is_librados_test_stub(_rados));
1060
1061 std::string token_b64;
1062 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1063 ASSERT_EQ(-EINVAL, m_rbd.mirror_peer_bootstrap_create(m_ioctx, &token_b64));
1064
1065 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
1066 ASSERT_EQ(0, m_rbd.mirror_peer_bootstrap_create(m_ioctx, &token_b64));
1067
1068 bufferlist token_b64_bl;
1069 token_b64_bl.append(token_b64);
1070
1071 bufferlist token_bl;
1072 token_bl.decode_base64(token_b64_bl);
1073
1074 // cannot import token into same cluster
1075 ASSERT_EQ(-EINVAL,
1076 m_rbd.mirror_peer_bootstrap_import(
1077 m_ioctx, RBD_MIRROR_PEER_DIRECTION_RX, token_b64));
1078}
9f95a23c
TL
1079
1080TEST_F(TestMirroring, PeerDirection) {
1081 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL));
1082
1083 std::string uuid;
1084 ASSERT_EQ(-EINVAL, m_rbd.mirror_peer_site_add(
1085 m_ioctx, &uuid, RBD_MIRROR_PEER_DIRECTION_TX, "siteA",
1086 "client.admin"));
1087 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &uuid,
1088 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1089 "siteA", "client.admin"));
1090
1091 std::vector<librbd::mirror_peer_site_t> peers;
1092 ASSERT_EQ(0, m_rbd.mirror_peer_site_list(m_ioctx, &peers));
1093 std::vector<librbd::mirror_peer_site_t> expected_peers = {
1094 {uuid, RBD_MIRROR_PEER_DIRECTION_RX_TX, "siteA", "", "client.admin", 0}};
1095 ASSERT_EQ(expected_peers, peers);
1096
1097 ASSERT_EQ(0, m_rbd.mirror_peer_site_set_direction(
1098 m_ioctx, uuid, RBD_MIRROR_PEER_DIRECTION_RX));
1099 ASSERT_EQ(0, m_rbd.mirror_peer_site_list(m_ioctx, &peers));
1100 expected_peers = {
1101 {uuid, RBD_MIRROR_PEER_DIRECTION_RX, "siteA", "", "client.admin", 0}};
1102 ASSERT_EQ(expected_peers, peers);
1103
1104 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, uuid));
1105}
1106
1107TEST_F(TestMirroring, Snapshot)
1108{
1109 REQUIRE_FORMAT_V2();
1110
1111 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1112
1113 uint64_t features;
1114 ASSERT_TRUE(get_features(&features));
1115 int order = 20;
1116 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
1117 &order));
1118
1119 librbd::Image image;
1120 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
1121
1122 ASSERT_EQ(0, image.metadata_set(
1123 "conf_rbd_mirroring_max_mirroring_snapshots", "3"));
1124
1125 uint64_t snap_id;
1126
1127 ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id));
1128 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
1129 ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id));
1130 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1131 librbd::mirror_image_mode_t mode;
1132 ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
1133 ASSERT_EQ(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mode);
1134 ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id));
1135 std::string peer_uuid;
1136 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer_uuid,
1137 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1138 "cluster", "client"));
b3b6e05e
TL
1139 // The mirroring was enabled when no peer was configured. Therefore, the
1140 // initial snapshot has no peers linked and will be removed after the
1141 // creation of a new mirror snapshot.
9f95a23c
TL
1142 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
1143 vector<librbd::snap_info_t> snaps;
1144 ASSERT_EQ(0, image.snap_list(snaps));
b3b6e05e
TL
1145 ASSERT_EQ(1U, snaps.size());
1146 ASSERT_EQ(snaps[0].id, snap_id);
9f95a23c 1147
b3b6e05e 1148 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
9f95a23c
TL
1149 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
1150 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
1151 snaps.clear();
1152 ASSERT_EQ(0, image.snap_list(snaps));
1153 ASSERT_EQ(3U, snaps.size());
1154 ASSERT_EQ(snaps[2].id, snap_id);
1155
1156 // automatic peer unlink on max_mirroring_snapshots reached
1157 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
1158 vector<librbd::snap_info_t> snaps1;
1159 ASSERT_EQ(0, image.snap_list(snaps1));
1160 ASSERT_EQ(3U, snaps1.size());
1161 ASSERT_EQ(snaps1[0].id, snaps[0].id);
f67539c2 1162 ASSERT_EQ(snaps1[1].id, snaps[1].id);
9f95a23c
TL
1163 ASSERT_EQ(snaps1[2].id, snap_id);
1164
1165 librbd::snap_namespace_type_t snap_ns_type;
1166 ASSERT_EQ(0, image.snap_get_namespace_type(snap_id, &snap_ns_type));
1167 ASSERT_EQ(RBD_SNAP_NAMESPACE_TYPE_MIRROR, snap_ns_type);
1168 librbd::snap_mirror_namespace_t mirror_snap;
1169 ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
1170 sizeof(mirror_snap)));
1171 ASSERT_EQ(1U, mirror_snap.mirror_peer_uuids.size());
1172 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer_uuid));
1173
1174 for (auto &snap : snaps1) {
1175 ASSERT_EQ(0, image.snap_remove_by_id(snap.id));
1176 }
1177
1178 ASSERT_EQ(0, image.close());
1179 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
1180 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer_uuid));
1181 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1182}
1183
1184TEST_F(TestMirroring, SnapshotRemoveOnDisable)
1185{
1186 REQUIRE_FORMAT_V2();
1187
1188 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
1189 std::string peer_uuid;
1190 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer_uuid,
1191 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1192 "cluster", "client"));
1193
1194 uint64_t features;
1195 ASSERT_TRUE(get_features(&features));
1196 int order = 20;
1197 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
1198 &order));
1199 librbd::Image image;
1200 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
1201 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1202 uint64_t snap_id;
1203 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
1204
1205 vector<librbd::snap_info_t> snaps;
1206 ASSERT_EQ(0, image.snap_list(snaps));
1207 ASSERT_EQ(2U, snaps.size());
1208 ASSERT_EQ(snaps[1].id, snap_id);
1209
1210 ASSERT_EQ(0, image.mirror_image_disable(false));
1211
1212 snaps.clear();
1213 ASSERT_EQ(0, image.snap_list(snaps));
1214 ASSERT_TRUE(snaps.empty());
1215
1216 ASSERT_EQ(0, image.close());
1217 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
1218 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer_uuid));
1219 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1220}
1221
1222TEST_F(TestMirroring, SnapshotUnlinkPeer)
1223{
1224 REQUIRE_FORMAT_V2();
1225
1226 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
1227 std::string peer1_uuid;
1228 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer1_uuid,
1229 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1230 "cluster1", "client"));
1231 std::string peer2_uuid;
1232 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer2_uuid,
1233 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1234 "cluster2", "client"));
1235 std::string peer3_uuid;
1236 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer3_uuid,
1237 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1238 "cluster3", "client"));
1239 uint64_t features;
1240 ASSERT_TRUE(get_features(&features));
1241 features &= ~RBD_FEATURE_JOURNALING;
1242 int order = 20;
1243 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
1244 &order));
1245 librbd::Image image;
1246 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
1247 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1248 uint64_t snap_id;
1249 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
1250 uint64_t snap_id2;
1251 ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id2));
1252 librbd::snap_mirror_namespace_t mirror_snap;
1253 ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
1254 sizeof(mirror_snap)));
1255 ASSERT_EQ(3U, mirror_snap.mirror_peer_uuids.size());
1256 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer1_uuid));
1257 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
1258 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer3_uuid));
1259
1260 auto ictx = new librbd::ImageCtx(image_name, "", nullptr, m_ioctx, false);
1261 ASSERT_EQ(0, ictx->state->open(0));
1262 BOOST_SCOPE_EXIT(&ictx) {
1263 if (ictx != nullptr) {
1264 ictx->state->close();
1265 }
1266 } BOOST_SCOPE_EXIT_END;
1267
1268 C_SaferCond cond1;
1269 auto req = librbd::mirror::snapshot::UnlinkPeerRequest<>::create(
1270 ictx, snap_id, peer1_uuid, &cond1);
1271 req->send();
1272 ASSERT_EQ(0, cond1.wait());
1273
1274 ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
1275 sizeof(mirror_snap)));
1276 ASSERT_EQ(2U, mirror_snap.mirror_peer_uuids.size());
1277 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
1278 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer3_uuid));
1279
1280 ASSERT_EQ(0, librbd::api::Namespace<>::create(m_ioctx, "ns1"));
1281 librados::IoCtx ns_ioctx;
1282 ns_ioctx.dup(m_ioctx);
1283 ns_ioctx.set_namespace("ns1");
1284 ASSERT_EQ(0, m_rbd.mirror_mode_set(ns_ioctx, RBD_MIRROR_MODE_IMAGE));
1285 ASSERT_EQ(0, m_rbd.create2(ns_ioctx, image_name.c_str(), 4096, features,
1286 &order));
1287
1288 librbd::Image ns_image;
1289 ASSERT_EQ(0, m_rbd.open(ns_ioctx, ns_image, image_name.c_str()));
1290 ASSERT_EQ(0, ns_image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1291 uint64_t ns_snap_id;
1292 ASSERT_EQ(0, ns_image.mirror_image_create_snapshot(&ns_snap_id));
1293 ASSERT_EQ(0, ns_image.snap_get_mirror_namespace(ns_snap_id, &mirror_snap,
1294 sizeof(mirror_snap)));
1295 ASSERT_EQ(3U, mirror_snap.mirror_peer_uuids.size());
1296 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer1_uuid));
1297 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
1298 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer3_uuid));
1299
1300 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer3_uuid));
1301
1302 ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
1303 sizeof(mirror_snap)));
1304 ASSERT_EQ(1U, mirror_snap.mirror_peer_uuids.size());
1305 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
1306
1307 ASSERT_EQ(0, ns_image.snap_get_mirror_namespace(ns_snap_id, &mirror_snap,
1308 sizeof(mirror_snap)));
1309 ASSERT_EQ(2U, mirror_snap.mirror_peer_uuids.size());
1310 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer1_uuid));
1311 ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
1312
1313 C_SaferCond cond2;
1314 req = librbd::mirror::snapshot::UnlinkPeerRequest<>::create(
1315 ictx, snap_id, peer2_uuid, &cond2);
1316 req->send();
1317 ASSERT_EQ(0, cond2.wait());
1318
1319 ASSERT_EQ(-ENOENT, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
1320 sizeof(mirror_snap)));
1321 ictx->state->close();
1322 ictx = nullptr;
1323 ASSERT_EQ(0, image.close());
1324 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
1325
1326 ASSERT_EQ(0, ns_image.close());
1327 ASSERT_EQ(0, m_rbd.remove(ns_ioctx, image_name.c_str()));
1328 ASSERT_EQ(0, librbd::api::Namespace<>::remove(m_ioctx, "ns1"));
1329
1330 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer1_uuid));
1331 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer2_uuid));
1332 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1333}
1334
1335TEST_F(TestMirroring, SnapshotImageState)
1336{
1337 REQUIRE_FORMAT_V2();
1338
1339 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
1340
1341 uint64_t features;
1342 ASSERT_TRUE(get_features(&features));
1343 int order = 20;
1344 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
1345 &order));
1346
1347 librbd::Image image;
1348 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
1349 ASSERT_EQ(0, image.snap_create("snap"));
1350 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1351 std::vector<librbd::snap_info_t> snaps;
1352 ASSERT_EQ(0, image.snap_list(snaps));
1353 ASSERT_EQ(2U, snaps.size());
1354 auto snap_id = snaps[1].id;
1355
1356 auto ictx = new librbd::ImageCtx(image_name, "", nullptr, m_ioctx, false);
1357 ASSERT_EQ(0, ictx->state->open(0));
1358 BOOST_SCOPE_EXIT(&ictx) {
1359 if (ictx != nullptr) {
1360 ictx->state->close();
1361 }
1362 } BOOST_SCOPE_EXIT_END;
1363
1364 {
1365 C_SaferCond cond;
1366 auto req = librbd::mirror::snapshot::SetImageStateRequest<>::create(
1367 ictx, snap_id, &cond);
1368 req->send();
1369 ASSERT_EQ(0, cond.wait());
1370 }
1371
1372 librbd::mirror::snapshot::ImageState image_state;
1373 {
1374 C_SaferCond cond;
1375 auto req = librbd::mirror::snapshot::GetImageStateRequest<>::create(
1376 ictx, snap_id, &image_state, &cond);
1377 req->send();
1378 ASSERT_EQ(0, cond.wait());
1379 }
1380
1381 ASSERT_EQ(image_name, image_state.name);
1382 ASSERT_EQ(0, image.features(&features));
1383 ASSERT_EQ(features & ~RBD_FEATURES_IMPLICIT_ENABLE, image_state.features);
1384 ASSERT_EQ(1U, image_state.snapshots.size());
1385 ASSERT_EQ("snap", image_state.snapshots.begin()->second.name);
f67539c2 1386 uint8_t original_pairs_num = image_state.metadata.size();
9f95a23c
TL
1387
1388 {
1389 C_SaferCond cond;
1390 auto req = librbd::mirror::snapshot::RemoveImageStateRequest<>::create(
1391 ictx, snap_id, &cond);
1392 req->send();
1393 ASSERT_EQ(0, cond.wait());
1394 }
1395
1396 // test storing "large" image state in multiple objects
1397
1398 ASSERT_EQ(0, ictx->config.set_val("rbd_default_order", "8"));
1399
1400 for (int i = 0; i < 10; i++) {
1401 ASSERT_EQ(0, image.metadata_set(stringify(i), std::string(1024, 'A' + i)));
1402 }
1403
1404 {
1405 C_SaferCond cond;
1406 auto req = librbd::mirror::snapshot::SetImageStateRequest<>::create(
1407 ictx, snap_id, &cond);
1408 req->send();
1409 ASSERT_EQ(0, cond.wait());
1410 }
1411
1412 {
1413 C_SaferCond cond;
1414 auto req = librbd::mirror::snapshot::GetImageStateRequest<>::create(
1415 ictx, snap_id, &image_state, &cond);
1416 req->send();
1417 ASSERT_EQ(0, cond.wait());
1418 }
1419
1420 ASSERT_EQ(image_name, image_state.name);
1421 ASSERT_EQ(features & ~RBD_FEATURES_IMPLICIT_ENABLE, image_state.features);
f67539c2 1422 ASSERT_EQ(original_pairs_num + 10, image_state.metadata.size());
9f95a23c
TL
1423 for (int i = 0; i < 10; i++) {
1424 auto &bl = image_state.metadata[stringify(i)];
1425 ASSERT_EQ(0, strncmp(std::string(1024, 'A' + i).c_str(), bl.c_str(),
1426 bl.length()));
1427 }
1428
1429 {
1430 C_SaferCond cond;
1431 auto req = librbd::mirror::snapshot::RemoveImageStateRequest<>::create(
1432 ictx, snap_id, &cond);
1433 req->send();
1434 ASSERT_EQ(0, cond.wait());
1435 }
1436
1437 ASSERT_EQ(0, ictx->state->close());
1438 ictx = nullptr;
1439
1440 ASSERT_EQ(0, image.snap_remove("snap"));
1441 ASSERT_EQ(0, image.close());
1442 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
1443}
1444
1445TEST_F(TestMirroring, SnapshotPromoteDemote)
1446{
1447 REQUIRE_FORMAT_V2();
1448
1449 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
1450 std::string peer_uuid;
1451 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer_uuid,
1452 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1453 "cluster", "client"));
1454
1455 uint64_t features;
1456 ASSERT_TRUE(get_features(&features));
1457 int order = 20;
1458 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features,
1459 &order));
1460
1461 librbd::Image image;
1462 ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
1463 ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1464 librbd::mirror_image_mode_t mode;
1465 ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
1466 ASSERT_EQ(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mode);
1467
1468 ASSERT_EQ(-EINVAL, image.mirror_image_promote(false));
1469 ASSERT_EQ(0, image.mirror_image_demote());
1470 ASSERT_EQ(0, image.mirror_image_promote(false));
1471 ASSERT_EQ(0, image.mirror_image_demote());
1472 ASSERT_EQ(0, image.mirror_image_promote(false));
1473
1474 ASSERT_EQ(0, image.close());
1475 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
1476 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer_uuid));
1477 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1478}
cd265ab1
TL
1479
1480TEST_F(TestMirroring, AioSnapshotCreate)
1481{
1482 REQUIRE_FORMAT_V2();
1483
1484 std::list<std::string> image_names;
1485 for (size_t idx = 0; idx < 10; ++idx) {
1486 image_names.push_back(get_temp_image_name());
1487 }
1488
1489 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
1490 std::string peer_uuid;
1491 ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer_uuid,
1492 RBD_MIRROR_PEER_DIRECTION_RX_TX,
1493 "cluster", "client"));
1494 // create mirror images
1495 uint64_t features;
1496 ASSERT_TRUE(get_features(&features));
1497 int order = 20;
1498 std::list<librbd::Image> images;
1499 for (auto &image_name : image_names) {
1500 ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048, features,
1501 &order));
1502 images.emplace_back();
1503 ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str()));
1504 ASSERT_EQ(0, images.back().mirror_image_enable2(
1505 RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
1506 }
1507
1508 // create snapshots
1509 std::list<uint64_t> snap_ids;
1510 std::list<librbd::RBD::AioCompletion *> aio_comps;
1511 for (auto &image : images) {
1512 snap_ids.emplace_back();
1513 aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr));
1514 ASSERT_EQ(0, image.aio_mirror_image_create_snapshot(0, &snap_ids.back(),
1515 aio_comps.back()));
1516 }
1517 for (auto aio_comp : aio_comps) {
1518 ASSERT_EQ(0, aio_comp->wait_for_complete());
1519 ASSERT_EQ(1, aio_comp->is_complete());
1520 ASSERT_EQ(0, aio_comp->get_return_value());
1521 aio_comp->release();
1522 }
1523 aio_comps.clear();
1524
1525 // verify
1526 for (auto &image : images) {
1527 vector<librbd::snap_info_t> snaps;
1528 ASSERT_EQ(0, image.snap_list(snaps));
1529 ASSERT_EQ(2U, snaps.size());
1530 ASSERT_EQ(snaps[1].id, snap_ids.front());
1531
1532 std::string image_name;
1533 ASSERT_EQ(0, image.get_name(&image_name));
1534 ASSERT_EQ(0, image.close());
1535 ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
1536 snap_ids.pop_front();
1537 }
1538
1539 ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer_uuid));
1540 ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
1541}