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