]>
Commit | Line | Data |
---|---|---|
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" | |
22 | #include "librbd/io/AioCompletion.h" | |
23 | #include "librbd/io/ImageRequest.h" | |
24 | #include "librbd/io/ImageRequestWQ.h" | |
25 | #include "librbd/journal/Types.h" | |
11fdf7f2 | 26 | #include "librbd/api/Image.h" |
7c673cae FG |
27 | #include "journal/Journaler.h" |
28 | #include "journal/Settings.h" | |
29 | #include <boost/scope_exit.hpp> | |
30 | #include <boost/assign/list_of.hpp> | |
31 | #include <utility> | |
32 | #include <vector> | |
33 | ||
34 | void register_test_mirroring() { | |
35 | } | |
36 | ||
37 | class TestMirroring : public TestFixture { | |
38 | public: | |
39 | ||
40 | TestMirroring() {} | |
41 | ||
42 | ||
43 | void TearDown() override { | |
44 | unlock_image(); | |
45 | ||
46 | TestFixture::TearDown(); | |
47 | } | |
48 | ||
49 | void SetUp() override { | |
50 | ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), m_ioctx)); | |
51 | } | |
52 | ||
53 | std::string image_name = "mirrorimg1"; | |
54 | ||
55 | void check_mirror_image_enable(rbd_mirror_mode_t mirror_mode, | |
56 | uint64_t features, | |
57 | int expected_r, | |
58 | rbd_mirror_image_state_t mirror_state) { | |
59 | ||
60 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
61 | ||
62 | int order = 20; | |
63 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order)); | |
64 | librbd::Image image; | |
65 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
66 | ||
67 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
68 | ||
69 | ASSERT_EQ(expected_r, image.mirror_image_enable()); | |
70 | ||
71 | librbd::mirror_image_info_t mirror_image; | |
72 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
73 | ASSERT_EQ(mirror_state, mirror_image.state); | |
74 | ||
75 | librbd::mirror_image_status_t status; | |
76 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
77 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
78 | ||
11fdf7f2 TL |
79 | std::string instance_id; |
80 | ASSERT_EQ(mirror_state == RBD_MIRROR_IMAGE_ENABLED ? -ENOENT : -EINVAL, | |
81 | image.mirror_image_get_instance_id(&instance_id)); | |
82 | ||
7c673cae FG |
83 | ASSERT_EQ(0, image.close()); |
84 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
85 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
86 | } | |
87 | ||
88 | void check_mirror_image_disable(rbd_mirror_mode_t mirror_mode, | |
89 | uint64_t features, | |
90 | int expected_r, | |
91 | rbd_mirror_image_state_t mirror_state) { | |
92 | ||
93 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
94 | ||
95 | int order = 20; | |
96 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order)); | |
97 | librbd::Image image; | |
98 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
99 | ||
100 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
101 | ||
102 | ASSERT_EQ(expected_r, image.mirror_image_disable(false)); | |
103 | ||
104 | librbd::mirror_image_info_t mirror_image; | |
105 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
106 | ASSERT_EQ(mirror_state, mirror_image.state); | |
107 | ||
108 | librbd::mirror_image_status_t status; | |
109 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
110 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
111 | ||
11fdf7f2 TL |
112 | std::string instance_id; |
113 | ASSERT_EQ(mirror_state == RBD_MIRROR_IMAGE_ENABLED ? -ENOENT : -EINVAL, | |
114 | image.mirror_image_get_instance_id(&instance_id)); | |
115 | ||
7c673cae FG |
116 | ASSERT_EQ(0, image.close()); |
117 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
118 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
119 | } | |
120 | ||
121 | void check_mirroring_status(size_t *images_count) { | |
122 | std::map<std::string, librbd::mirror_image_status_t> images; | |
123 | ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, "", 4096, &images)); | |
124 | ||
125 | std::map<librbd::mirror_image_status_state_t, int> states; | |
126 | ASSERT_EQ(0, m_rbd.mirror_image_status_summary(m_ioctx, &states)); | |
127 | size_t states_count = 0; | |
128 | for (auto &s : states) { | |
129 | states_count += s.second; | |
130 | } | |
131 | ASSERT_EQ(images.size(), states_count); | |
132 | ||
133 | *images_count = images.size(); | |
11fdf7f2 TL |
134 | |
135 | std::map<std::string, std::string> instance_ids; | |
136 | ASSERT_EQ(0, m_rbd.mirror_image_instance_id_list(m_ioctx, "", 4096, | |
137 | &instance_ids)); | |
138 | ASSERT_TRUE(instance_ids.empty()); | |
7c673cae FG |
139 | } |
140 | ||
141 | void check_mirroring_on_create(uint64_t features, | |
142 | rbd_mirror_mode_t mirror_mode, | |
143 | rbd_mirror_image_state_t mirror_state) { | |
144 | ||
145 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
146 | ||
147 | size_t mirror_images_count = 0; | |
148 | check_mirroring_status(&mirror_images_count); | |
149 | ||
150 | int order = 20; | |
151 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order)); | |
152 | librbd::Image image; | |
153 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
154 | ||
155 | librbd::mirror_image_info_t mirror_image; | |
156 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
157 | ASSERT_EQ(mirror_state, mirror_image.state); | |
158 | ||
159 | librbd::mirror_image_status_t status; | |
160 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
161 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
162 | ||
163 | size_t mirror_images_new_count = 0; | |
164 | check_mirroring_status(&mirror_images_new_count); | |
165 | if (mirror_mode == RBD_MIRROR_MODE_POOL && | |
166 | mirror_state == RBD_MIRROR_IMAGE_ENABLED) { | |
167 | ASSERT_EQ(mirror_images_new_count, mirror_images_count + 1); | |
168 | } else { | |
169 | ASSERT_EQ(mirror_images_new_count, mirror_images_count); | |
170 | } | |
171 | ||
172 | ASSERT_EQ(0, image.close()); | |
173 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
174 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
175 | ||
176 | check_mirroring_status(&mirror_images_new_count); | |
177 | ASSERT_EQ(mirror_images_new_count, mirror_images_count); | |
178 | } | |
179 | ||
180 | void check_mirroring_on_update_features(uint64_t init_features, | |
181 | bool enable, bool enable_mirroring, | |
182 | uint64_t features, int expected_r, | |
183 | rbd_mirror_mode_t mirror_mode, | |
184 | rbd_mirror_image_state_t mirror_state) { | |
185 | ||
186 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
187 | ||
188 | int order = 20; | |
189 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, init_features, &order)); | |
190 | librbd::Image image; | |
191 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
192 | ||
193 | if (enable_mirroring) { | |
194 | ASSERT_EQ(0, image.mirror_image_enable()); | |
195 | } | |
196 | ||
197 | ASSERT_EQ(expected_r, image.update_features(features, enable)); | |
198 | ||
199 | librbd::mirror_image_info_t mirror_image; | |
200 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
201 | ASSERT_EQ(mirror_state, mirror_image.state); | |
202 | ||
203 | librbd::mirror_image_status_t status; | |
204 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
205 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
206 | ||
207 | ASSERT_EQ(0, image.close()); | |
208 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
209 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
210 | } | |
211 | ||
212 | void setup_images_with_mirror_mode(rbd_mirror_mode_t mirror_mode, | |
213 | std::vector<uint64_t>& features_vec) { | |
214 | ||
215 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
216 | ||
217 | int id = 1; | |
218 | int order = 20; | |
219 | for (const auto& features : features_vec) { | |
220 | std::stringstream img_name("img_"); | |
221 | img_name << id++; | |
222 | std::string img_name_str = img_name.str(); | |
223 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, img_name_str.c_str(), 2048, features, &order)); | |
224 | } | |
225 | } | |
226 | ||
227 | void check_mirroring_on_mirror_mode_set(rbd_mirror_mode_t mirror_mode, | |
228 | std::vector<rbd_mirror_image_state_t>& states_vec) { | |
229 | ||
230 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
231 | ||
232 | std::vector< std::tuple<std::string, rbd_mirror_image_state_t> > images; | |
233 | int id = 1; | |
234 | for (const auto& mirror_state : states_vec) { | |
235 | std::stringstream img_name("img_"); | |
236 | img_name << id++; | |
237 | std::string img_name_str = img_name.str(); | |
238 | librbd::Image image; | |
239 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, img_name_str.c_str())); | |
240 | images.push_back(std::make_tuple(img_name_str, mirror_state)); | |
241 | ||
242 | librbd::mirror_image_info_t mirror_image; | |
243 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
244 | ASSERT_EQ(mirror_state, mirror_image.state); | |
245 | ||
246 | librbd::mirror_image_status_t status; | |
247 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
248 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
249 | ||
250 | ASSERT_EQ(0, image.close()); | |
251 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, img_name_str.c_str())); | |
252 | } | |
253 | } | |
254 | ||
255 | void check_remove_image(rbd_mirror_mode_t mirror_mode, uint64_t features, | |
256 | bool enable_mirroring, bool demote = false) { | |
257 | ||
258 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
259 | ||
260 | int order = 20; | |
261 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, | |
262 | &order)); | |
263 | librbd::Image image; | |
264 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
265 | ||
266 | if (enable_mirroring) { | |
267 | ASSERT_EQ(0, image.mirror_image_enable()); | |
268 | } | |
269 | ||
270 | if (demote) { | |
271 | ASSERT_EQ(0, image.mirror_image_demote()); | |
272 | ASSERT_EQ(0, image.mirror_image_disable(true)); | |
273 | } | |
274 | ||
275 | image.close(); | |
276 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
277 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
278 | } | |
279 | ||
11fdf7f2 TL |
280 | void check_trash_move_restore(rbd_mirror_mode_t mirror_mode, |
281 | bool enable_mirroring) { | |
282 | ||
283 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); | |
284 | ||
285 | int order = 20; | |
286 | uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; | |
287 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, | |
288 | &order)); | |
289 | librbd::Image image; | |
290 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
291 | ||
292 | if (enable_mirroring) { | |
293 | ASSERT_EQ(0, image.mirror_image_enable()); | |
294 | } | |
295 | ||
296 | std::string image_id; | |
297 | ASSERT_EQ(0, image.get_id(&image_id)); | |
298 | image.close(); | |
299 | ||
300 | ASSERT_EQ(0, m_rbd.trash_move(m_ioctx, image_name.c_str(), 100)); | |
301 | ||
302 | ASSERT_EQ(0, m_rbd.open_by_id(m_ioctx, image, image_id.c_str(), NULL)); | |
303 | ||
304 | librbd::mirror_image_info_t mirror_image; | |
305 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
306 | ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_DISABLED); | |
307 | ||
308 | ASSERT_EQ(0, m_rbd.trash_restore(m_ioctx, image_id.c_str(), "")); | |
309 | ||
310 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); | |
311 | if (mirror_mode == RBD_MIRROR_MODE_POOL) { | |
312 | ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_ENABLED); | |
313 | } else { | |
314 | ASSERT_EQ(mirror_image.state, RBD_MIRROR_IMAGE_DISABLED); | |
315 | } | |
316 | ||
317 | image.close(); | |
318 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
319 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
320 | } | |
321 | ||
7c673cae FG |
322 | void setup_mirror_peer(librados::IoCtx &io_ctx, librbd::Image &image) { |
323 | ASSERT_EQ(0, image.snap_create("sync-point-snap")); | |
324 | ||
325 | std::string image_id; | |
326 | ASSERT_EQ(0, get_image_id(image, &image_id)); | |
327 | ||
328 | librbd::journal::MirrorPeerClientMeta peer_client_meta( | |
329 | "remote-image-id", {{{}, "sync-point-snap", boost::none}}, {}); | |
330 | librbd::journal::ClientData client_data(peer_client_meta); | |
331 | ||
332 | journal::Journaler journaler(io_ctx, image_id, "peer-client", {}); | |
333 | C_SaferCond init_ctx; | |
334 | journaler.init(&init_ctx); | |
335 | ASSERT_EQ(-ENOENT, init_ctx.wait()); | |
336 | ||
337 | bufferlist client_data_bl; | |
11fdf7f2 | 338 | encode(client_data, client_data_bl); |
7c673cae FG |
339 | ASSERT_EQ(0, journaler.register_client(client_data_bl)); |
340 | ||
341 | C_SaferCond shut_down_ctx; | |
342 | journaler.shut_down(&shut_down_ctx); | |
343 | ASSERT_EQ(0, shut_down_ctx.wait()); | |
344 | } | |
345 | ||
346 | }; | |
347 | ||
348 | TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage) { | |
349 | uint64_t features = 0; | |
350 | features |= RBD_FEATURE_OBJECT_MAP; | |
351 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
352 | features |= RBD_FEATURE_JOURNALING; | |
353 | check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0, | |
354 | RBD_MIRROR_IMAGE_ENABLED); | |
355 | } | |
356 | ||
357 | TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) { | |
358 | uint64_t features = 0; | |
359 | features |= RBD_FEATURE_OBJECT_MAP; | |
360 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
361 | features |= RBD_FEATURE_JOURNALING; | |
362 | check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL, | |
363 | RBD_MIRROR_IMAGE_ENABLED); | |
364 | } | |
365 | ||
366 | TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled) { | |
367 | uint64_t features = 0; | |
368 | features |= RBD_FEATURE_OBJECT_MAP; | |
369 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
370 | features |= RBD_FEATURE_JOURNALING; | |
371 | check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL, | |
372 | RBD_MIRROR_IMAGE_DISABLED); | |
373 | } | |
374 | ||
375 | TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeImage) { | |
376 | uint64_t features = 0; | |
377 | features |= RBD_FEATURE_OBJECT_MAP; | |
378 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
379 | features |= RBD_FEATURE_JOURNALING; | |
380 | check_mirror_image_disable(RBD_MIRROR_MODE_IMAGE, features, 0, | |
381 | RBD_MIRROR_IMAGE_DISABLED); | |
382 | } | |
383 | ||
384 | TEST_F(TestMirroring, DisableImageMirror_In_MirrorModePool) { | |
385 | uint64_t features = 0; | |
386 | features |= RBD_FEATURE_OBJECT_MAP; | |
387 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
388 | features |= RBD_FEATURE_JOURNALING; | |
389 | check_mirror_image_disable(RBD_MIRROR_MODE_POOL, features, -EINVAL, | |
390 | RBD_MIRROR_IMAGE_ENABLED); | |
391 | } | |
392 | ||
393 | TEST_F(TestMirroring, DisableImageMirror_In_MirrorModeDisabled) { | |
394 | uint64_t features = 0; | |
395 | features |= RBD_FEATURE_OBJECT_MAP; | |
396 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
397 | features |= RBD_FEATURE_JOURNALING; | |
398 | check_mirror_image_disable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL, | |
399 | RBD_MIRROR_IMAGE_DISABLED); | |
400 | } | |
401 | ||
402 | TEST_F(TestMirroring, DisableImageMirrorWithPeer) { | |
403 | REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); | |
404 | ||
405 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE)); | |
406 | ||
407 | uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; | |
408 | int order = 20; | |
409 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, | |
410 | &order)); | |
411 | ||
412 | librbd::Image image; | |
413 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
414 | ASSERT_EQ(0, image.mirror_image_enable()); | |
415 | ||
416 | setup_mirror_peer(m_ioctx, image); | |
417 | ||
418 | ASSERT_EQ(0, image.mirror_image_disable(false)); | |
419 | ||
420 | std::vector<librbd::snap_info_t> snaps; | |
421 | ASSERT_EQ(0, image.snap_list(snaps)); | |
422 | ASSERT_TRUE(snaps.empty()); | |
423 | ||
424 | librbd::mirror_image_info_t mirror_image; | |
425 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, | |
426 | sizeof(mirror_image))); | |
427 | ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, mirror_image.state); | |
428 | ||
429 | librbd::mirror_image_status_t status; | |
430 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
431 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
432 | ||
433 | ASSERT_EQ(0, image.close()); | |
434 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
435 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
436 | } | |
437 | ||
438 | TEST_F(TestMirroring, DisableJournalingWithPeer) { | |
439 | REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); | |
440 | ||
441 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
442 | ||
443 | uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; | |
444 | int order = 20; | |
445 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, | |
446 | &order)); | |
447 | ||
448 | librbd::Image image; | |
449 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
450 | ||
451 | setup_mirror_peer(m_ioctx, image); | |
452 | ||
453 | ASSERT_EQ(0, image.update_features(RBD_FEATURE_JOURNALING, false)); | |
454 | ||
455 | std::vector<librbd::snap_info_t> snaps; | |
456 | ASSERT_EQ(0, image.snap_list(snaps)); | |
457 | ASSERT_TRUE(snaps.empty()); | |
458 | ||
459 | librbd::mirror_image_info_t mirror_image; | |
460 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, | |
461 | sizeof(mirror_image))); | |
462 | ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, mirror_image.state); | |
463 | ||
464 | librbd::mirror_image_status_t status; | |
465 | ASSERT_EQ(0, image.mirror_image_get_status(&status, sizeof(status))); | |
466 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
467 | ||
468 | ASSERT_EQ(0, image.close()); | |
469 | ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); | |
470 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
471 | } | |
472 | ||
473 | TEST_F(TestMirroring, EnableImageMirror_WithoutJournaling) { | |
474 | uint64_t features = 0; | |
475 | features |= RBD_FEATURE_OBJECT_MAP; | |
476 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
477 | check_mirror_image_enable(RBD_MIRROR_MODE_DISABLED, features, -EINVAL, | |
478 | RBD_MIRROR_IMAGE_DISABLED); | |
479 | } | |
480 | ||
481 | TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) { | |
482 | uint64_t features = 0; | |
483 | features |= RBD_FEATURE_OBJECT_MAP; | |
484 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
485 | features |= RBD_FEATURE_JOURNALING; | |
486 | check_mirroring_on_create(features, RBD_MIRROR_MODE_DISABLED, | |
487 | RBD_MIRROR_IMAGE_DISABLED); | |
488 | } | |
489 | ||
490 | TEST_F(TestMirroring, CreateImage_In_MirrorModeImage) { | |
491 | uint64_t features = 0; | |
492 | features |= RBD_FEATURE_OBJECT_MAP; | |
493 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
494 | features |= RBD_FEATURE_JOURNALING; | |
495 | check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE, | |
496 | RBD_MIRROR_IMAGE_DISABLED); | |
497 | } | |
498 | ||
499 | TEST_F(TestMirroring, CreateImage_In_MirrorModePool) { | |
500 | uint64_t features = 0; | |
501 | features |= RBD_FEATURE_OBJECT_MAP; | |
502 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
503 | features |= RBD_FEATURE_JOURNALING; | |
504 | check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL, | |
505 | RBD_MIRROR_IMAGE_ENABLED); | |
506 | } | |
507 | ||
508 | TEST_F(TestMirroring, CreateImage_In_MirrorModePool_WithoutJournaling) { | |
509 | uint64_t features = 0; | |
510 | features |= RBD_FEATURE_OBJECT_MAP; | |
511 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
512 | check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL, | |
513 | RBD_MIRROR_IMAGE_DISABLED); | |
514 | } | |
515 | ||
516 | TEST_F(TestMirroring, CreateImage_In_MirrorModeImage_WithoutJournaling) { | |
517 | uint64_t features = 0; | |
518 | features |= RBD_FEATURE_OBJECT_MAP; | |
519 | features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
520 | check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE, | |
521 | RBD_MIRROR_IMAGE_DISABLED); | |
522 | } | |
523 | ||
524 | TEST_F(TestMirroring, EnableJournaling_In_MirrorModeDisabled) { | |
525 | uint64_t init_features = 0; | |
526 | init_features |= RBD_FEATURE_OBJECT_MAP; | |
527 | init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
528 | uint64_t features = RBD_FEATURE_JOURNALING; | |
529 | check_mirroring_on_update_features(init_features, true, false, features, 0, | |
530 | RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_IMAGE_DISABLED); | |
531 | } | |
532 | ||
533 | TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage) { | |
534 | uint64_t init_features = 0; | |
535 | init_features |= RBD_FEATURE_OBJECT_MAP; | |
536 | init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
537 | uint64_t features = RBD_FEATURE_JOURNALING; | |
538 | check_mirroring_on_update_features(init_features, true, false, features, 0, | |
539 | RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_DISABLED); | |
540 | } | |
541 | ||
542 | TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) { | |
543 | uint64_t init_features = 0; | |
544 | init_features |= RBD_FEATURE_OBJECT_MAP; | |
545 | init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
546 | uint64_t features = RBD_FEATURE_JOURNALING; | |
547 | check_mirroring_on_update_features(init_features, true, false, features, 0, | |
548 | RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED); | |
549 | } | |
550 | ||
551 | TEST_F(TestMirroring, DisableJournaling_In_MirrorModePool) { | |
552 | uint64_t init_features = 0; | |
553 | init_features |= RBD_FEATURE_OBJECT_MAP; | |
554 | init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
555 | init_features |= RBD_FEATURE_JOURNALING; | |
556 | uint64_t features = RBD_FEATURE_JOURNALING; | |
557 | check_mirroring_on_update_features(init_features, false, false, features, 0, | |
558 | RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_DISABLED); | |
559 | } | |
560 | ||
561 | TEST_F(TestMirroring, DisableJournaling_In_MirrorModeImage) { | |
562 | uint64_t init_features = 0; | |
563 | init_features |= RBD_FEATURE_OBJECT_MAP; | |
564 | init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; | |
565 | init_features |= RBD_FEATURE_JOURNALING; | |
566 | uint64_t features = RBD_FEATURE_JOURNALING; | |
567 | check_mirroring_on_update_features(init_features, false, true, features, -EINVAL, | |
568 | RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED); | |
569 | } | |
570 | ||
571 | TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_PoolMode) { | |
572 | std::vector<uint64_t> features_vec; | |
573 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK); | |
574 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
575 | ||
576 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec); | |
577 | ||
578 | std::vector<rbd_mirror_image_state_t> states_vec; | |
579 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
580 | states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED); | |
581 | check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL, states_vec); | |
582 | } | |
583 | ||
584 | TEST_F(TestMirroring, MirrorModeSet_PoolMode_To_DisabledMode) { | |
585 | std::vector<uint64_t> features_vec; | |
586 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK); | |
587 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
588 | ||
589 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec); | |
590 | ||
591 | std::vector<rbd_mirror_image_state_t> states_vec; | |
592 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
593 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
594 | check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED, states_vec); | |
595 | } | |
596 | ||
597 | TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_ImageMode) { | |
598 | std::vector<uint64_t> features_vec; | |
599 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK); | |
600 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
601 | ||
602 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_DISABLED, features_vec); | |
603 | ||
604 | std::vector<rbd_mirror_image_state_t> states_vec; | |
605 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
606 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
607 | check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE, states_vec); | |
608 | } | |
609 | ||
610 | ||
611 | TEST_F(TestMirroring, MirrorModeSet_PoolMode_To_ImageMode) { | |
612 | std::vector<uint64_t> features_vec; | |
613 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK); | |
614 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
615 | ||
616 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec); | |
617 | ||
618 | std::vector<rbd_mirror_image_state_t> states_vec; | |
619 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
620 | states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED); | |
621 | check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_IMAGE, states_vec); | |
622 | } | |
623 | ||
624 | TEST_F(TestMirroring, MirrorModeSet_ImageMode_To_PoolMode) { | |
625 | std::vector<uint64_t> features_vec; | |
626 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK); | |
627 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
628 | ||
629 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_IMAGE, features_vec); | |
630 | ||
631 | std::vector<rbd_mirror_image_state_t> states_vec; | |
632 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
633 | states_vec.push_back(RBD_MIRROR_IMAGE_ENABLED); | |
634 | check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_POOL, states_vec); | |
635 | } | |
636 | ||
637 | TEST_F(TestMirroring, MirrorModeSet_ImageMode_To_DisabledMode) { | |
638 | std::vector<uint64_t> features_vec; | |
639 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK); | |
640 | features_vec.push_back(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
641 | ||
642 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec); | |
643 | ||
644 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE)); | |
645 | ASSERT_EQ(-EINVAL, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
646 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
647 | ||
648 | std::vector<rbd_mirror_image_state_t> states_vec; | |
649 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
650 | states_vec.push_back(RBD_MIRROR_IMAGE_DISABLED); | |
651 | check_mirroring_on_mirror_mode_set(RBD_MIRROR_MODE_DISABLED, states_vec); | |
652 | } | |
653 | ||
654 | TEST_F(TestMirroring, RemoveImage_With_MirrorImageEnabled) { | |
655 | check_remove_image(RBD_MIRROR_MODE_IMAGE, | |
656 | RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING, | |
657 | true); | |
658 | } | |
659 | ||
660 | TEST_F(TestMirroring, RemoveImage_With_MirrorImageDisabled) { | |
661 | check_remove_image(RBD_MIRROR_MODE_IMAGE, | |
662 | RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING, | |
663 | false); | |
664 | } | |
665 | ||
666 | TEST_F(TestMirroring, RemoveImage_With_ImageWithoutJournal) { | |
667 | check_remove_image(RBD_MIRROR_MODE_IMAGE, | |
668 | RBD_FEATURE_EXCLUSIVE_LOCK, | |
669 | false); | |
670 | } | |
671 | ||
672 | TEST_F(TestMirroring, RemoveImage_With_MirrorImageDemoted) { | |
673 | check_remove_image(RBD_MIRROR_MODE_IMAGE, | |
674 | RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING, | |
675 | true, true); | |
676 | } | |
677 | ||
11fdf7f2 TL |
678 | TEST_F(TestMirroring, TrashMoveRestore_PoolMode) { |
679 | check_trash_move_restore(RBD_MIRROR_MODE_POOL, false); | |
680 | } | |
681 | ||
682 | TEST_F(TestMirroring, TrashMoveRestore_ImageMode_MirroringDisabled) { | |
683 | check_trash_move_restore(RBD_MIRROR_MODE_IMAGE, false); | |
684 | } | |
685 | ||
686 | TEST_F(TestMirroring, TrashMoveRestore_ImageMode_MirroringEnabled) { | |
687 | check_trash_move_restore(RBD_MIRROR_MODE_IMAGE, true); | |
688 | } | |
689 | ||
7c673cae FG |
690 | TEST_F(TestMirroring, MirrorStatusList) { |
691 | std::vector<uint64_t> | |
692 | features_vec(5, RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING); | |
693 | setup_images_with_mirror_mode(RBD_MIRROR_MODE_POOL, features_vec); | |
694 | ||
695 | std::string last_read = ""; | |
696 | std::map<std::string, librbd::mirror_image_status_t> images; | |
697 | ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 2, &images)); | |
698 | ASSERT_EQ(2U, images.size()); | |
699 | ||
700 | last_read = images.rbegin()->first; | |
701 | images.clear(); | |
702 | ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 2, &images)); | |
703 | ASSERT_EQ(2U, images.size()); | |
704 | ||
705 | last_read = images.rbegin()->first; | |
706 | images.clear(); | |
707 | ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 4096, &images)); | |
708 | ASSERT_EQ(1U, images.size()); | |
709 | ||
710 | last_read = images.rbegin()->first; | |
711 | images.clear(); | |
712 | ASSERT_EQ(0, m_rbd.mirror_image_status_list(m_ioctx, last_read, 4096, &images)); | |
713 | ASSERT_EQ(0U, images.size()); | |
714 | } | |
715 | ||
716 | TEST_F(TestMirroring, RemoveBootstrapped) | |
717 | { | |
718 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
719 | ||
720 | uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; | |
721 | int order = 20; | |
722 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, | |
723 | &order)); | |
724 | librbd::Image image; | |
725 | ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str())); | |
11fdf7f2 TL |
726 | |
727 | librbd::NoOpProgressContext no_op; | |
728 | ASSERT_EQ(-EBUSY, librbd::api::Image<>::remove(m_ioctx, image_name, no_op)); | |
7c673cae FG |
729 | |
730 | // simulate the image is open by rbd-mirror bootstrap | |
731 | uint64_t handle; | |
732 | struct MirrorWatcher : public librados::WatchCtx2 { | |
11fdf7f2 | 733 | explicit MirrorWatcher(librados::IoCtx &ioctx) : m_ioctx(ioctx) { |
7c673cae FG |
734 | } |
735 | void handle_notify(uint64_t notify_id, uint64_t cookie, | |
736 | uint64_t notifier_id, bufferlist& bl) override { | |
737 | // received IMAGE_UPDATED notification from remove | |
738 | m_notified = true; | |
739 | m_ioctx.notify_ack(RBD_MIRRORING, notify_id, cookie, bl); | |
740 | } | |
741 | void handle_error(uint64_t cookie, int err) override { | |
742 | } | |
743 | librados::IoCtx &m_ioctx; | |
744 | bool m_notified = false; | |
745 | } watcher(m_ioctx); | |
746 | ASSERT_EQ(0, m_ioctx.create(RBD_MIRRORING, false)); | |
747 | ASSERT_EQ(0, m_ioctx.watch2(RBD_MIRRORING, &handle, &watcher)); | |
748 | // now remove should succeed | |
11fdf7f2 | 749 | ASSERT_EQ(0, librbd::api::Image<>::remove(m_ioctx, image_name, no_op)); |
7c673cae FG |
750 | ASSERT_EQ(0, m_ioctx.unwatch2(handle)); |
751 | ASSERT_TRUE(watcher.m_notified); | |
752 | ASSERT_EQ(0, image.close()); | |
753 | } | |
754 | ||
755 | TEST_F(TestMirroring, AioPromoteDemote) { | |
756 | std::list<std::string> image_names; | |
757 | for (size_t idx = 0; idx < 10; ++idx) { | |
758 | image_names.push_back(get_temp_image_name()); | |
759 | } | |
760 | ||
761 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE)); | |
762 | ||
763 | // create mirror images | |
764 | int order = 20; | |
765 | std::list<librbd::Image> images; | |
766 | for (auto &image_name : image_names) { | |
767 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048, | |
768 | RBD_FEATURE_EXCLUSIVE_LOCK | | |
769 | RBD_FEATURE_JOURNALING, | |
770 | &order)); | |
771 | ||
772 | images.emplace_back(); | |
773 | ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str())); | |
774 | ASSERT_EQ(0, images.back().mirror_image_enable()); | |
775 | } | |
776 | ||
777 | // demote all images | |
778 | std::list<librbd::RBD::AioCompletion *> aio_comps; | |
779 | for (auto &image : images) { | |
780 | aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr)); | |
781 | ASSERT_EQ(0, image.aio_mirror_image_demote(aio_comps.back())); | |
782 | } | |
783 | for (auto aio_comp : aio_comps) { | |
784 | ASSERT_EQ(0, aio_comp->wait_for_complete()); | |
785 | ASSERT_EQ(1, aio_comp->is_complete()); | |
786 | ASSERT_EQ(0, aio_comp->get_return_value()); | |
787 | aio_comp->release(); | |
788 | } | |
789 | aio_comps.clear(); | |
790 | ||
791 | // verify demotions | |
792 | for (auto &image : images) { | |
793 | librbd::mirror_image_info_t mirror_image; | |
794 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, | |
795 | sizeof(mirror_image))); | |
796 | ASSERT_FALSE(mirror_image.primary); | |
797 | } | |
798 | ||
799 | // promote all images | |
800 | for (auto &image : images) { | |
801 | aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr)); | |
802 | ASSERT_EQ(0, image.aio_mirror_image_promote(false, aio_comps.back())); | |
803 | } | |
804 | for (auto aio_comp : aio_comps) { | |
805 | ASSERT_EQ(0, aio_comp->wait_for_complete()); | |
806 | ASSERT_EQ(1, aio_comp->is_complete()); | |
807 | ASSERT_EQ(0, aio_comp->get_return_value()); | |
808 | aio_comp->release(); | |
809 | } | |
810 | ||
811 | // verify promotions | |
812 | for (auto &image : images) { | |
813 | librbd::mirror_image_info_t mirror_image; | |
814 | ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, | |
815 | sizeof(mirror_image))); | |
816 | ASSERT_TRUE(mirror_image.primary); | |
817 | } | |
818 | } | |
819 | ||
820 | TEST_F(TestMirroring, AioGetInfo) { | |
821 | std::list<std::string> image_names; | |
822 | for (size_t idx = 0; idx < 10; ++idx) { | |
823 | image_names.push_back(get_temp_image_name()); | |
824 | } | |
825 | ||
826 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
827 | ||
828 | // create mirror images | |
829 | int order = 20; | |
830 | std::list<librbd::Image> images; | |
831 | for (auto &image_name : image_names) { | |
832 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048, | |
833 | RBD_FEATURE_EXCLUSIVE_LOCK | | |
834 | RBD_FEATURE_JOURNALING, | |
835 | &order)); | |
836 | ||
837 | images.emplace_back(); | |
838 | ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str())); | |
839 | } | |
840 | ||
841 | std::list<librbd::RBD::AioCompletion *> aio_comps; | |
842 | std::list<librbd::mirror_image_info_t> infos; | |
843 | for (auto &image : images) { | |
844 | aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr)); | |
845 | infos.emplace_back(); | |
846 | ASSERT_EQ(0, image.aio_mirror_image_get_info(&infos.back(), | |
847 | sizeof(infos.back()), | |
848 | aio_comps.back())); | |
849 | } | |
850 | for (auto aio_comp : aio_comps) { | |
851 | ASSERT_EQ(0, aio_comp->wait_for_complete()); | |
852 | ASSERT_EQ(1, aio_comp->is_complete()); | |
853 | ASSERT_EQ(0, aio_comp->get_return_value()); | |
854 | aio_comp->release(); | |
855 | } | |
856 | aio_comps.clear(); | |
857 | ||
858 | for (auto &info : infos) { | |
859 | ASSERT_NE("", info.global_id); | |
860 | ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state); | |
861 | ASSERT_TRUE(info.primary); | |
862 | } | |
863 | } | |
864 | ||
865 | TEST_F(TestMirroring, AioGetStatus) { | |
866 | std::list<std::string> image_names; | |
867 | for (size_t idx = 0; idx < 10; ++idx) { | |
868 | image_names.push_back(get_temp_image_name()); | |
869 | } | |
870 | ||
871 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
872 | ||
873 | // create mirror images | |
874 | int order = 20; | |
875 | std::list<librbd::Image> images; | |
876 | for (auto &image_name : image_names) { | |
877 | ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 2048, | |
878 | RBD_FEATURE_EXCLUSIVE_LOCK | | |
879 | RBD_FEATURE_JOURNALING, | |
880 | &order)); | |
881 | ||
882 | images.emplace_back(); | |
883 | ASSERT_EQ(0, m_rbd.open(m_ioctx, images.back(), image_name.c_str())); | |
884 | } | |
885 | ||
886 | std::list<librbd::RBD::AioCompletion *> aio_comps; | |
887 | std::list<librbd::mirror_image_status_t> statuses; | |
888 | for (auto &image : images) { | |
889 | aio_comps.push_back(new librbd::RBD::AioCompletion(nullptr, nullptr)); | |
890 | statuses.emplace_back(); | |
891 | ASSERT_EQ(0, image.aio_mirror_image_get_status(&statuses.back(), | |
892 | sizeof(statuses.back()), | |
893 | aio_comps.back())); | |
894 | } | |
895 | for (auto aio_comp : aio_comps) { | |
896 | ASSERT_EQ(0, aio_comp->wait_for_complete()); | |
897 | ASSERT_EQ(1, aio_comp->is_complete()); | |
898 | ASSERT_EQ(0, aio_comp->get_return_value()); | |
899 | aio_comp->release(); | |
900 | } | |
901 | aio_comps.clear(); | |
902 | ||
903 | for (auto &status : statuses) { | |
904 | ASSERT_NE("", status.name); | |
905 | ASSERT_NE("", status.info.global_id); | |
906 | ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, status.info.state); | |
907 | ASSERT_TRUE(status.info.primary); | |
908 | ASSERT_EQ(MIRROR_IMAGE_STATUS_STATE_UNKNOWN, status.state); | |
909 | ASSERT_EQ("status not found", status.description); | |
910 | ASSERT_FALSE(status.up); | |
911 | ASSERT_EQ(0, status.last_update); | |
912 | } | |
913 | } | |
eafe8130 TL |
914 | |
915 | TEST_F(TestMirroring, SiteName) { | |
916 | REQUIRE(!is_librados_test_stub(_rados)); | |
917 | ||
918 | const std::string expected_site_name("us-east-1a"); | |
919 | ASSERT_EQ(0, m_rbd.mirror_site_name_set(_rados, expected_site_name)); | |
920 | ||
921 | std::string site_name; | |
922 | ASSERT_EQ(0, m_rbd.mirror_site_name_get(_rados, &site_name)); | |
923 | ASSERT_EQ(expected_site_name, site_name); | |
924 | ||
925 | ASSERT_EQ(0, m_rbd.mirror_site_name_set(_rados, "")); | |
926 | ||
927 | std::string fsid; | |
928 | ASSERT_EQ(0, _rados.cluster_fsid(&fsid)); | |
929 | ASSERT_EQ(0, m_rbd.mirror_site_name_get(_rados, &site_name)); | |
930 | ASSERT_EQ(fsid, site_name); | |
931 | } | |
932 | ||
933 | TEST_F(TestMirroring, Bootstrap) { | |
934 | REQUIRE(!is_librados_test_stub(_rados)); | |
935 | ||
936 | std::string token_b64; | |
937 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); | |
938 | ASSERT_EQ(-EINVAL, m_rbd.mirror_peer_bootstrap_create(m_ioctx, &token_b64)); | |
939 | ||
940 | ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_POOL)); | |
941 | ASSERT_EQ(0, m_rbd.mirror_peer_bootstrap_create(m_ioctx, &token_b64)); | |
942 | ||
943 | bufferlist token_b64_bl; | |
944 | token_b64_bl.append(token_b64); | |
945 | ||
946 | bufferlist token_bl; | |
947 | token_bl.decode_base64(token_b64_bl); | |
948 | ||
949 | // cannot import token into same cluster | |
950 | ASSERT_EQ(-EINVAL, | |
951 | m_rbd.mirror_peer_bootstrap_import( | |
952 | m_ioctx, RBD_MIRROR_PEER_DIRECTION_RX, token_b64)); | |
953 | } |