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