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