]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/test_Migration.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / librbd / test_Migration.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "test/librados/test.h"
5 #include "test/librbd/test_fixture.h"
6 #include "test/librbd/test_support.h"
7 #include "librbd/ImageState.h"
8 #include "librbd/Operations.h"
9 #include "librbd/api/Group.h"
10 #include "librbd/api/Image.h"
11 #include "librbd/api/Migration.h"
12 #include "librbd/api/Mirror.h"
13 #include "librbd/api/Namespace.h"
14 #include "librbd/api/Snapshot.h"
15 #include "librbd/image/AttachChildRequest.h"
16 #include "librbd/image/AttachParentRequest.h"
17 #include "librbd/internal.h"
18 #include "librbd/io/ImageRequestWQ.h"
19 #include "librbd/io/ReadResult.h"
20 #include "common/Cond.h"
21 #include <boost/scope_exit.hpp>
22
23 void register_test_migration() {
24 }
25
26 struct TestMigration : public TestFixture {
27 static void SetUpTestCase() {
28 TestFixture::SetUpTestCase();
29
30 _other_pool_name = get_temp_pool_name("test-librbd-");
31 ASSERT_EQ(0, _rados.pool_create(_other_pool_name.c_str()));
32 }
33
34 static void TearDownTestCase() {
35 ASSERT_EQ(0, _rados.pool_delete(_other_pool_name.c_str()));
36
37 TestFixture::TearDownTestCase();
38 }
39
40 void SetUp() override {
41 TestFixture::SetUp();
42
43 ASSERT_EQ(0, _rados.ioctx_create(_other_pool_name.c_str(),
44 _other_pool_ioctx));
45
46 open_image(m_ioctx, m_image_name, &m_ictx);
47 m_image_id = m_ictx->id;
48
49 std::string ref_image_name = get_temp_image_name();
50 ASSERT_EQ(0, create_image_pp(m_rbd, m_ioctx, ref_image_name, m_ictx->size));
51 EXPECT_EQ(0, _rados.ioctx_create2(m_ioctx.get_id(), m_ref_ioctx));
52 open_image(m_ref_ioctx, ref_image_name, &m_ref_ictx);
53
54 resize(20 * (1 << 22));
55 }
56
57 void TearDown() override {
58 if (m_ref_ictx != nullptr) {
59 close_image(m_ref_ictx);
60 }
61 if (m_ictx != nullptr) {
62 close_image(m_ictx);
63 }
64
65 _other_pool_ioctx.close();
66
67 TestFixture::TearDown();
68 }
69
70 void compare(const std::string &description = "") {
71 vector<librbd::snap_info_t> src_snaps, dst_snaps;
72
73 EXPECT_EQ(m_ref_ictx->size, m_ictx->size);
74 EXPECT_EQ(0, librbd::api::Snapshot<>::list(m_ref_ictx, src_snaps));
75 EXPECT_EQ(0, librbd::api::Snapshot<>::list(m_ictx, dst_snaps));
76 EXPECT_EQ(src_snaps.size(), dst_snaps.size());
77 for (size_t i = 0; i <= src_snaps.size(); i++) {
78 const char *src_snap_name = nullptr;
79 const char *dst_snap_name = nullptr;
80 if (i < src_snaps.size()) {
81 EXPECT_EQ(src_snaps[i].name, dst_snaps[i].name);
82 src_snap_name = src_snaps[i].name.c_str();
83 dst_snap_name = dst_snaps[i].name.c_str();
84 }
85 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
86 m_ref_ictx, cls::rbd::UserSnapshotNamespace(),
87 src_snap_name));
88 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
89 m_ictx, cls::rbd::UserSnapshotNamespace(),
90 dst_snap_name));
91 compare_snaps(
92 description + " snap: " + (src_snap_name ? src_snap_name : "null"),
93 m_ref_ictx, m_ictx);
94 }
95 }
96
97 void compare_snaps(const std::string &description, librbd::ImageCtx *src_ictx,
98 librbd::ImageCtx *dst_ictx) {
99 uint64_t src_size, dst_size;
100 {
101 std::shared_lock src_locker{src_ictx->image_lock};
102 std::shared_lock dst_locker{dst_ictx->image_lock};
103 src_size = src_ictx->get_image_size(src_ictx->snap_id);
104 dst_size = dst_ictx->get_image_size(dst_ictx->snap_id);
105 }
106 if (src_size != dst_size) {
107 std::cout << description << ": size differs" << std::endl;
108 EXPECT_EQ(src_size, dst_size);
109 }
110
111 if (dst_ictx->test_features(RBD_FEATURE_LAYERING)) {
112 bool flags_set;
113 std::shared_lock dst_locker{dst_ictx->image_lock};
114 EXPECT_EQ(0, dst_ictx->test_flags(dst_ictx->snap_id,
115 RBD_FLAG_OBJECT_MAP_INVALID,
116 dst_ictx->image_lock, &flags_set));
117 EXPECT_FALSE(flags_set);
118 }
119
120 ssize_t read_size = 1 << src_ictx->order;
121 uint64_t offset = 0;
122 while (offset < src_size) {
123 read_size = std::min(read_size, static_cast<ssize_t>(src_size - offset));
124
125 bufferptr src_ptr(read_size);
126 bufferlist src_bl;
127 src_bl.push_back(src_ptr);
128 librbd::io::ReadResult src_result{&src_bl};
129 EXPECT_EQ(read_size, src_ictx->io_work_queue->read(
130 offset, read_size, librbd::io::ReadResult{src_result}, 0));
131
132 bufferptr dst_ptr(read_size);
133 bufferlist dst_bl;
134 dst_bl.push_back(dst_ptr);
135 librbd::io::ReadResult dst_result{&dst_bl};
136 EXPECT_EQ(read_size, dst_ictx->io_work_queue->read(
137 offset, read_size, librbd::io::ReadResult{dst_result}, 0));
138
139 if (!src_bl.contents_equal(dst_bl)) {
140 std::cout << description
141 << ", block " << offset << "~" << read_size << " differs"
142 << std::endl;
143 char *c = getenv("TEST_RBD_MIGRATION_VERBOSE");
144 if (c != NULL && *c != '\0') {
145 std::cout << "src block: " << src_ictx->id << ": " << std::endl; src_bl.hexdump(std::cout);
146 std::cout << "dst block: " << dst_ictx->id << ": " << std::endl; dst_bl.hexdump(std::cout);
147 }
148 }
149 EXPECT_TRUE(src_bl.contents_equal(dst_bl));
150 offset += read_size;
151 }
152 }
153
154 void open_image(librados::IoCtx& io_ctx, const std::string &name,
155 const std::string &id, bool read_only, int flags,
156 librbd::ImageCtx **ictx) {
157 *ictx = new librbd::ImageCtx(name, id, nullptr, io_ctx, read_only);
158 m_ictxs.insert(*ictx);
159
160 ASSERT_EQ(0, (*ictx)->state->open(flags));
161 (*ictx)->discard_granularity_bytes = 0;
162 }
163
164 void open_image(librados::IoCtx& io_ctx, const std::string &name,
165 librbd::ImageCtx **ictx) {
166 open_image(io_ctx, name, "", false, 0, ictx);
167 }
168
169 void migration_prepare(librados::IoCtx& dst_io_ctx,
170 const std::string &dst_name, int r = 0) {
171 std::cout << __func__ << std::endl;
172
173 close_image(m_ictx);
174 m_ictx = nullptr;
175
176 EXPECT_EQ(r, librbd::api::Migration<>::prepare(m_ioctx, m_image_name,
177 dst_io_ctx, dst_name,
178 m_opts));
179 if (r == 0) {
180 open_image(dst_io_ctx, dst_name, &m_ictx);
181 } else {
182 open_image(m_ioctx, m_image_name, &m_ictx);
183 }
184 compare("after prepare");
185 }
186
187 void migration_execute(librados::IoCtx& io_ctx, const std::string &name,
188 int r = 0) {
189 std::cout << __func__ << std::endl;
190
191 librbd::NoOpProgressContext no_op;
192 EXPECT_EQ(r, librbd::api::Migration<>::execute(io_ctx, name, no_op));
193 }
194
195 void migration_abort(librados::IoCtx& io_ctx, const std::string &name,
196 int r = 0) {
197 std::cout << __func__ << std::endl;
198
199 std::string dst_name = m_ictx->name;
200 close_image(m_ictx);
201 m_ictx = nullptr;
202
203 librbd::NoOpProgressContext no_op;
204 EXPECT_EQ(r, librbd::api::Migration<>::abort(io_ctx, name, no_op));
205
206 if (r == 0) {
207 open_image(m_ioctx, m_image_name, &m_ictx);
208 } else {
209 open_image(m_ioctx, dst_name, &m_ictx);
210 }
211
212 compare("after abort");
213 }
214
215 void migration_commit(librados::IoCtx& io_ctx, const std::string &name) {
216 std::cout << __func__ << std::endl;
217
218 librbd::NoOpProgressContext no_op;
219 EXPECT_EQ(0, librbd::api::Migration<>::commit(io_ctx, name, no_op));
220
221 compare("after commit");
222 }
223
224 void migration_status(librbd::image_migration_state_t state) {
225 librbd::image_migration_status_t status;
226 EXPECT_EQ(0, librbd::api::Migration<>::status(m_ioctx, m_image_name,
227 &status));
228 EXPECT_EQ(status.source_pool_id, m_ioctx.get_id());
229 EXPECT_EQ(status.source_pool_namespace, m_ioctx.get_namespace());
230 EXPECT_EQ(status.source_image_name, m_image_name);
231 EXPECT_EQ(status.source_image_id, m_image_id);
232 EXPECT_EQ(status.dest_pool_id, m_ictx->md_ctx.get_id());
233 EXPECT_EQ(status.dest_pool_namespace, m_ictx->md_ctx.get_namespace());
234 EXPECT_EQ(status.dest_image_name, m_ictx->name);
235 EXPECT_EQ(status.dest_image_id, m_ictx->id);
236 EXPECT_EQ(status.state, state);
237 }
238
239 void migrate(librados::IoCtx& dst_io_ctx, const std::string &dst_name) {
240 migration_prepare(dst_io_ctx, dst_name);
241 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
242 migration_execute(dst_io_ctx, dst_name);
243 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
244 migration_commit(dst_io_ctx, dst_name);
245 }
246
247 void write(uint64_t off, uint64_t len, char c) {
248 std::cout << "write: " << c << " " << off << "~" << len << std::endl;
249
250 bufferlist ref_bl;
251 ref_bl.append(std::string(len, c));
252 ASSERT_EQ(static_cast<ssize_t>(len),
253 m_ref_ictx->io_work_queue->write(off, len, std::move(ref_bl), 0));
254 bufferlist bl;
255 bl.append(std::string(len, c));
256 ASSERT_EQ(static_cast<ssize_t>(len),
257 m_ictx->io_work_queue->write(off, len, std::move(bl), 0));
258 }
259
260 void discard(uint64_t off, uint64_t len) {
261 std::cout << "discard: " << off << "~" << len << std::endl;
262
263 ASSERT_EQ(static_cast<ssize_t>(len),
264 m_ref_ictx->io_work_queue->discard(off, len, false));
265 ASSERT_EQ(static_cast<ssize_t>(len),
266 m_ictx->io_work_queue->discard(off, len, false));
267 }
268
269 void flush() {
270 ASSERT_EQ(0, m_ref_ictx->io_work_queue->flush());
271 ASSERT_EQ(0, m_ictx->io_work_queue->flush());
272 }
273
274 void snap_create(const std::string &snap_name) {
275 std::cout << "snap_create: " << snap_name << std::endl;
276
277 flush();
278
279 ASSERT_EQ(0, TestFixture::snap_create(*m_ref_ictx, snap_name));
280 ASSERT_EQ(0, TestFixture::snap_create(*m_ictx, snap_name));
281 }
282
283 void snap_protect(const std::string &snap_name) {
284 std::cout << "snap_protect: " << snap_name << std::endl;
285
286 ASSERT_EQ(0, TestFixture::snap_protect(*m_ref_ictx, snap_name));
287 ASSERT_EQ(0, TestFixture::snap_protect(*m_ictx, snap_name));
288 }
289
290 void clone(const std::string &snap_name) {
291 snap_protect(snap_name);
292
293 int order = m_ref_ictx->order;
294 uint64_t features;
295 ASSERT_EQ(0, librbd::get_features(m_ref_ictx, &features));
296 features &= ~RBD_FEATURES_IMPLICIT_ENABLE;
297
298 std::string ref_clone_name = get_temp_image_name();
299 std::string clone_name = get_temp_image_name();
300
301 std::cout << "clone " << m_ictx->name << " -> " << clone_name
302 << std::endl;
303
304 ASSERT_EQ(0, librbd::clone(m_ref_ictx->md_ctx, m_ref_ictx->name.c_str(),
305 snap_name.c_str(), m_ref_ioctx,
306 ref_clone_name.c_str(), features, &order,
307 m_ref_ictx->stripe_unit,
308 m_ref_ictx->stripe_count));
309
310 ASSERT_EQ(0, librbd::clone(m_ictx->md_ctx, m_ictx->name.c_str(),
311 snap_name.c_str(), m_ioctx,
312 clone_name.c_str(), features, &order,
313 m_ictx->stripe_unit,
314 m_ictx->stripe_count));
315
316 close_image(m_ref_ictx);
317 open_image(m_ref_ioctx, ref_clone_name, &m_ref_ictx);
318
319 close_image(m_ictx);
320 open_image(m_ioctx, clone_name, &m_ictx);
321 m_image_name = m_ictx->name;
322 m_image_id = m_ictx->id;
323 }
324
325 void resize(uint64_t size) {
326 std::cout << "resize: " << size << std::endl;
327
328 librbd::NoOpProgressContext no_op;
329 ASSERT_EQ(0, m_ref_ictx->operations->resize(size, true, no_op));
330 ASSERT_EQ(0, m_ictx->operations->resize(size, true, no_op));
331 }
332
333 void test_no_snaps() {
334 uint64_t len = (1 << m_ictx->order) * 2 + 1;
335 write(0 * len, len, '1');
336 write(2 * len, len, '1');
337 flush();
338 }
339
340 void test_snaps() {
341 uint64_t len = (1 << m_ictx->order) * 2 + 1;
342 write(0 * len, len, '1');
343 snap_create("snap1");
344 write(1 * len, len, '1');
345
346 write(0 * len, 1000, 'X');
347 discard(1000 + 10, 1000);
348
349 snap_create("snap2");
350
351 write(1 * len, 1000, 'X');
352 discard(2 * len + 10, 1000);
353
354 uint64_t size = m_ictx->size;
355
356 resize(size << 1);
357
358 write(size - 1, len, '2');
359
360 snap_create("snap3");
361
362 resize(size);
363
364 discard(size - 1, 1);
365
366 flush();
367 }
368
369 void test_clone() {
370 uint64_t len = (1 << m_ictx->order) * 2 + 1;
371 write(0 * len, len, 'X');
372 write(2 * len, len, 'X');
373
374 snap_create("snap");
375 clone("snap");
376
377 write(0, 1000, 'X');
378 discard(1010, 1000);
379
380 snap_create("snap");
381 clone("snap");
382
383 write(1000, 1000, 'X');
384 discard(2010, 1000);
385
386 flush();
387 }
388
389 template <typename L>
390 void test_migrate_parent(uint32_t clone_format, L&& test) {
391 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
392
393 std::string prev_clone_format;
394 ASSERT_EQ(0, _rados.conf_get("rbd_default_clone_format",
395 prev_clone_format));
396 ASSERT_EQ(0, _rados.conf_set("rbd_default_clone_format",
397 stringify(clone_format).c_str()));
398 BOOST_SCOPE_EXIT_TPL(&prev_clone_format) {
399 _rados.conf_set("rbd_default_clone_format", prev_clone_format.c_str());
400 } BOOST_SCOPE_EXIT_END;
401
402 write(0, 10, 'A');
403 snap_create("snap1");
404 snap_protect("snap1");
405
406 int order = m_ictx->order;
407 uint64_t features;
408 ASSERT_EQ(0, librbd::get_features(m_ictx, &features));
409 features &= ~RBD_FEATURES_IMPLICIT_ENABLE;
410
411 std::string clone_name = get_temp_image_name();
412 ASSERT_EQ(0, librbd::clone(m_ictx->md_ctx, m_ictx->name.c_str(), "snap1",
413 m_ioctx, clone_name.c_str(), features, &order,
414 m_ictx->stripe_unit, m_ictx->stripe_count));
415
416 librbd::ImageCtx *child_ictx;
417 open_image(m_ioctx, clone_name, &child_ictx);
418
419 test(child_ictx);
420
421 ASSERT_EQ(0, child_ictx->state->refresh());
422
423 bufferlist bl;
424 bufferptr ptr(10);
425 bl.push_back(ptr);
426 librbd::io::ReadResult result{&bl};
427 ASSERT_EQ(10, child_ictx->io_work_queue->read(
428 0, 10, librbd::io::ReadResult{result}, 0));
429 bufferlist ref_bl;
430 ref_bl.append(std::string(10, 'A'));
431 ASSERT_TRUE(ref_bl.contents_equal(bl));
432 close_image(child_ictx);
433 }
434
435 void test_stress(const std::string &snap_name_prefix = "snap",
436 char start_char = 'A') {
437 uint64_t initial_size = m_ictx->size;
438
439 int nsnaps = 4;
440 const char *c = getenv("TEST_RBD_MIGRATION_STRESS_NSNAPS");
441 if (c != NULL) {
442 std::stringstream ss(c);
443 ASSERT_TRUE(ss >> nsnaps);
444 }
445
446 int nwrites = 4;
447 c = getenv("TEST_RBD_MIGRATION_STRESS_NWRITES");
448 if (c != NULL) {
449 std::stringstream ss(c);
450 ASSERT_TRUE(ss >> nwrites);
451 }
452
453 for (int i = 0; i < nsnaps; i++) {
454 for (int j = 0; j < nwrites; j++) {
455 size_t len = rand() % ((1 << m_ictx->order) * 2);
456 ASSERT_GT(m_ictx->size, len);
457 uint64_t off = std::min(static_cast<uint64_t>(rand() % m_ictx->size),
458 static_cast<uint64_t>(m_ictx->size - len));
459 write(off, len, start_char + i);
460
461 len = rand() % ((1 << m_ictx->order) * 2);
462 ASSERT_GT(m_ictx->size, len);
463 off = std::min(static_cast<uint64_t>(rand() % m_ictx->size),
464 static_cast<uint64_t>(m_ictx->size - len));
465 discard(off, len);
466 }
467
468 std::string snap_name = snap_name_prefix + stringify(i);
469 snap_create(snap_name);
470
471 if (m_ictx->test_features(RBD_FEATURE_LAYERING) &&
472 !m_ictx->test_features(RBD_FEATURE_MIGRATING) &&
473 rand() % 4) {
474 clone(snap_name);
475 }
476
477 if (rand() % 2) {
478 librbd::NoOpProgressContext no_op;
479 uint64_t new_size = initial_size + rand() % m_ictx->size;
480 resize(new_size);
481 ASSERT_EQ(new_size, m_ictx->size);
482 }
483 }
484 flush();
485 }
486
487 void test_stress2(bool concurrent) {
488 test_stress();
489
490 migration_prepare(m_ioctx, m_image_name);
491 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
492
493 thread user([this]() {
494 test_stress("user", 'a');
495 for (int i = 0; i < 5; i++) {
496 uint64_t off = (i + 1) * m_ictx->size / 10;
497 uint64_t len = m_ictx->size / 40;
498 write(off, len, '1' + i);
499
500 off += len / 4;
501 len /= 2;
502 discard(off, len);
503 }
504 flush();
505 });
506
507 if (concurrent) {
508 librados::IoCtx io_ctx;
509 EXPECT_EQ(0, _rados.ioctx_create2(m_ioctx.get_id(), io_ctx));
510 migration_execute(io_ctx, m_image_name);
511 io_ctx.close();
512 user.join();
513 } else {
514 user.join();
515 compare("before execute");
516 migration_execute(m_ioctx, m_image_name);
517 }
518
519 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
520 migration_commit(m_ioctx, m_image_name);
521 }
522
523 static std::string _other_pool_name;
524 static librados::IoCtx _other_pool_ioctx;
525
526 std::string m_image_id;
527 librbd::ImageCtx *m_ictx = nullptr;
528 librados::IoCtx m_ref_ioctx;
529 librbd::ImageCtx *m_ref_ictx = nullptr;
530 librbd::ImageOptions m_opts;
531 };
532
533 std::string TestMigration::_other_pool_name;
534 librados::IoCtx TestMigration::_other_pool_ioctx;
535
536 TEST_F(TestMigration, Empty)
537 {
538 uint64_t features = m_ictx->features ^ RBD_FEATURE_LAYERING;
539 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_FEATURES, features));
540
541 migrate(m_ioctx, m_image_name);
542
543 ASSERT_EQ(features, m_ictx->features);
544 }
545
546 TEST_F(TestMigration, OtherName)
547 {
548 std::string name = get_temp_image_name();
549
550 migrate(m_ioctx, name);
551
552 ASSERT_EQ(name, m_ictx->name);
553 }
554
555 TEST_F(TestMigration, OtherPool)
556 {
557 migrate(_other_pool_ioctx, m_image_name);
558
559 ASSERT_EQ(_other_pool_ioctx.get_id(), m_ictx->md_ctx.get_id());
560 }
561
562 TEST_F(TestMigration, OtherNamespace)
563 {
564 ASSERT_EQ(0, librbd::api::Namespace<>::create(_other_pool_ioctx, "ns1"));
565 _other_pool_ioctx.set_namespace("ns1");
566
567 migrate(_other_pool_ioctx, m_image_name);
568
569 ASSERT_EQ(_other_pool_ioctx.get_id(), m_ictx->md_ctx.get_id());
570 ASSERT_EQ(_other_pool_ioctx.get_namespace(), m_ictx->md_ctx.get_namespace());
571 _other_pool_ioctx.set_namespace("");
572 }
573
574 TEST_F(TestMigration, DataPool)
575 {
576 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_DATA_POOL,
577 _other_pool_ioctx.get_pool_name().c_str()));
578
579 migrate(m_ioctx, m_image_name);
580
581 ASSERT_EQ(_other_pool_ioctx.get_id(), m_ictx->data_ctx.get_id());
582 }
583
584 TEST_F(TestMigration, AbortAfterPrepare)
585 {
586 migration_prepare(m_ioctx, m_image_name);
587 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
588 migration_abort(m_ioctx, m_image_name);
589 }
590
591 TEST_F(TestMigration, AbortAfterFailedPrepare)
592 {
593 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_DATA_POOL, "INVALID_POOL"));
594
595 migration_prepare(m_ioctx, m_image_name, -ENOENT);
596
597 // Migration is automatically aborted if prepare failed
598 }
599
600 TEST_F(TestMigration, AbortAfterExecute)
601 {
602 migration_prepare(m_ioctx, m_image_name);
603 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
604 migration_execute(m_ioctx, m_image_name);
605 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
606 migration_abort(m_ioctx, m_image_name);
607 }
608
609 TEST_F(TestMigration, OtherPoolAbortAfterExecute)
610 {
611 migration_prepare(_other_pool_ioctx, m_image_name);
612 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
613 migration_execute(_other_pool_ioctx, m_image_name);
614 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
615 migration_abort(_other_pool_ioctx, m_image_name);
616 }
617
618 TEST_F(TestMigration, OtherNamespaceAbortAfterExecute)
619 {
620 ASSERT_EQ(0, librbd::api::Namespace<>::create(_other_pool_ioctx, "ns2"));
621 _other_pool_ioctx.set_namespace("ns2");
622
623 migration_prepare(_other_pool_ioctx, m_image_name);
624 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
625 migration_execute(_other_pool_ioctx, m_image_name);
626 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
627 migration_abort(_other_pool_ioctx, m_image_name);
628
629 _other_pool_ioctx.set_namespace("");
630 ASSERT_EQ(0, librbd::api::Namespace<>::remove(_other_pool_ioctx, "ns2"));
631 }
632
633 TEST_F(TestMigration, MirroringSamePool)
634 {
635 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
636
637 ASSERT_EQ(0, librbd::api::Mirror<>::mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
638
639 ASSERT_EQ(0, librbd::api::Mirror<>::image_enable(
640 m_ictx, RBD_MIRROR_IMAGE_MODE_JOURNAL, false));
641 librbd::mirror_image_info_t info;
642 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
643 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
644
645 migrate(m_ioctx, m_image_name);
646
647 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
648 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
649 }
650
651 TEST_F(TestMigration, MirroringAbort)
652 {
653 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
654
655 ASSERT_EQ(0, librbd::api::Mirror<>::mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
656
657 ASSERT_EQ(0, librbd::api::Mirror<>::image_enable(
658 m_ictx, RBD_MIRROR_IMAGE_MODE_JOURNAL, false));
659 librbd::mirror_image_info_t info;
660 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
661 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
662
663 migration_prepare(m_ioctx, m_image_name);
664 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
665 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
666 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, info.state);
667
668 migration_abort(m_ioctx, m_image_name);
669
670 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
671 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
672 }
673
674 TEST_F(TestMigration, MirroringOtherPoolDisabled)
675 {
676 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
677
678 ASSERT_EQ(0, librbd::api::Mirror<>::mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
679
680 ASSERT_EQ(0, librbd::api::Mirror<>::image_enable(
681 m_ictx, RBD_MIRROR_IMAGE_MODE_JOURNAL, false));
682 librbd::mirror_image_info_t info;
683 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
684 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
685
686 migrate(_other_pool_ioctx, m_image_name);
687
688 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
689 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, info.state);
690 }
691
692 TEST_F(TestMigration, MirroringOtherPoolEnabled)
693 {
694 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
695
696 ASSERT_EQ(0, librbd::api::Mirror<>::mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
697 ASSERT_EQ(0, librbd::api::Mirror<>::mode_set(_other_pool_ioctx,
698 RBD_MIRROR_MODE_IMAGE));
699
700 ASSERT_EQ(0, librbd::api::Mirror<>::image_enable(
701 m_ictx, RBD_MIRROR_IMAGE_MODE_JOURNAL, false));
702 librbd::mirror_image_info_t info;
703 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
704 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
705
706 migrate(_other_pool_ioctx, m_image_name);
707
708 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
709 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
710 }
711
712 TEST_F(TestMigration, MirroringPool)
713 {
714 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
715
716 ASSERT_EQ(0, librbd::api::Mirror<>::mode_set(_other_pool_ioctx,
717 RBD_MIRROR_MODE_POOL));
718 librbd::mirror_image_info_t info;
719 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
720 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED, info.state);
721
722 migrate(_other_pool_ioctx, m_image_name);
723
724 ASSERT_EQ(0, librbd::api::Mirror<>::image_get_info(m_ictx, &info));
725 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED, info.state);
726 }
727
728 TEST_F(TestMigration, Group)
729 {
730 REQUIRE_FORMAT_V2();
731
732 ASSERT_EQ(0, librbd::api::Group<>::create(m_ioctx, "123"));
733 ASSERT_EQ(0, librbd::api::Group<>::image_add(m_ioctx, "123", m_ioctx,
734 m_image_name.c_str()));
735 librbd::group_info_t info;
736 ASSERT_EQ(0, librbd::api::Group<>::image_get_group(m_ictx, &info));
737
738 std::string name = get_temp_image_name();
739
740 migrate(m_ioctx, name);
741
742 ASSERT_EQ(0, librbd::api::Group<>::image_get_group(m_ictx, &info));
743 ASSERT_EQ(info.name, "123");
744
745 ASSERT_EQ(0, librbd::api::Group<>::image_remove(m_ioctx, "123", m_ioctx,
746 name.c_str()));
747 ASSERT_EQ(0, librbd::api::Group<>::remove(m_ioctx, "123"));
748 }
749
750 TEST_F(TestMigration, GroupAbort)
751 {
752 REQUIRE_FORMAT_V2();
753
754 ASSERT_EQ(0, librbd::api::Group<>::create(m_ioctx, "123"));
755 ASSERT_EQ(0, librbd::api::Group<>::image_add(m_ioctx, "123", m_ioctx,
756 m_image_name.c_str()));
757 librbd::group_info_t info;
758 ASSERT_EQ(0, librbd::api::Group<>::image_get_group(m_ictx, &info));
759
760 std::string name = get_temp_image_name();
761
762 migration_prepare(m_ioctx, name);
763 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
764
765 ASSERT_EQ(0, librbd::api::Group<>::image_get_group(m_ictx, &info));
766 ASSERT_EQ(info.name, "123");
767
768 migration_abort(m_ioctx, m_image_name);
769
770 ASSERT_EQ(0, librbd::api::Group<>::image_get_group(m_ictx, &info));
771 ASSERT_EQ(info.name, "123");
772
773 ASSERT_EQ(0, librbd::api::Group<>::image_remove(m_ioctx, "123", m_ioctx,
774 m_image_name.c_str()));
775 ASSERT_EQ(0, librbd::api::Group<>::remove(m_ioctx, "123"));
776 }
777
778 TEST_F(TestMigration, NoSnaps)
779 {
780 test_no_snaps();
781 migrate(m_ioctx, m_image_name);
782 }
783
784 TEST_F(TestMigration, NoSnapsOtherPool)
785 {
786 test_no_snaps();
787
788 test_no_snaps();
789 migrate(_other_pool_ioctx, m_image_name);
790 }
791
792 TEST_F(TestMigration, NoSnapsDataPool)
793 {
794 test_no_snaps();
795
796 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_DATA_POOL,
797 _other_pool_ioctx.get_pool_name().c_str()));
798 migrate(m_ioctx, m_image_name);
799
800 EXPECT_EQ(_other_pool_ioctx.get_id(), m_ictx->data_ctx.get_id());
801 }
802
803 TEST_F(TestMigration, NoSnapsShrinkAfterPrepare)
804 {
805 test_no_snaps();
806
807 migration_prepare(m_ioctx, m_image_name);
808 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
809
810 resize(m_ictx->size >> 1);
811
812 migration_execute(m_ioctx, m_image_name);
813 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
814 migration_commit(m_ioctx, m_image_name);
815 }
816
817 TEST_F(TestMigration, NoSnapsShrinkToZeroBeforePrepare)
818 {
819 test_no_snaps();
820 resize(0);
821
822 migrate(m_ioctx, m_image_name);
823 }
824
825 TEST_F(TestMigration, NoSnapsShrinkToZeroAfterPrepare)
826 {
827 test_no_snaps();
828
829 migration_prepare(m_ioctx, m_image_name);
830 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
831
832 resize(0);
833
834 migration_execute(m_ioctx, m_image_name);
835 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
836 migration_commit(m_ioctx, m_image_name);
837 }
838
839 TEST_F(TestMigration, NoSnapsExpandAfterPrepare)
840 {
841 test_no_snaps();
842
843 migration_prepare(m_ioctx, m_image_name);
844 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
845
846 resize(m_ictx->size << 1);
847
848 migration_execute(m_ioctx, m_image_name);
849 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
850 migration_commit(m_ioctx, m_image_name);
851 }
852
853 TEST_F(TestMigration, NoSnapsSnapAfterPrepare)
854 {
855 test_no_snaps();
856
857 migration_prepare(m_ioctx, m_image_name);
858 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
859
860 snap_create("after_prepare_snap");
861 resize(m_ictx->size >> 1);
862 write(0, 1000, '*');
863
864 migration_execute(m_ioctx, m_image_name);
865 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
866 migration_commit(m_ioctx, m_image_name);
867 }
868
869 TEST_F(TestMigration, Snaps)
870 {
871 test_snaps();
872 migrate(m_ioctx, m_image_name);
873 }
874
875 TEST_F(TestMigration, SnapsOtherPool)
876 {
877 test_snaps();
878
879 test_no_snaps();
880 migrate(_other_pool_ioctx, m_image_name);
881
882 EXPECT_EQ(_other_pool_ioctx.get_id(), m_ictx->md_ctx.get_id());
883 }
884
885 TEST_F(TestMigration, SnapsDataPool)
886 {
887 test_snaps();
888
889 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_DATA_POOL,
890 _other_pool_ioctx.get_pool_name().c_str()));
891 migrate(m_ioctx, m_image_name);
892
893 EXPECT_EQ(_other_pool_ioctx.get_id(), m_ictx->data_ctx.get_id());
894 }
895
896 TEST_F(TestMigration, SnapsShrinkAfterPrepare)
897 {
898 test_snaps();
899
900 migration_prepare(m_ioctx, m_image_name);
901 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
902
903 resize(m_ictx->size >> 1);
904
905 migration_execute(m_ioctx, m_image_name);
906 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
907 migration_commit(m_ioctx, m_image_name);
908 }
909
910 TEST_F(TestMigration, SnapsShrinkToZeroBeforePrepare)
911 {
912 test_snaps();
913 resize(0);
914
915 migrate(m_ioctx, m_image_name);
916 }
917
918 TEST_F(TestMigration, SnapsShrinkToZeroAfterPrepare)
919 {
920 test_snaps();
921
922 migration_prepare(m_ioctx, m_image_name);
923 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
924
925 resize(0);
926
927 migration_execute(m_ioctx, m_image_name);
928 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
929 migration_commit(m_ioctx, m_image_name);
930 }
931
932 TEST_F(TestMigration, SnapsExpandAfterPrepare)
933 {
934 test_snaps();
935
936 migration_prepare(m_ioctx, m_image_name);
937 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
938
939 auto size = m_ictx->size;
940 resize(size << 1);
941 write(size, 1000, '*');
942
943 migration_execute(m_ioctx, m_image_name);
944 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
945 migration_commit(m_ioctx, m_image_name);
946 }
947
948 TEST_F(TestMigration, SnapsExpandAfterPrepare2)
949 {
950 auto size = m_ictx->size;
951
952 write(size >> 1, 10, 'X');
953 snap_create("snap1");
954 resize(size >> 1);
955
956 migration_prepare(m_ioctx, m_image_name);
957 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
958
959 resize(size);
960 write(size >> 1, 5, 'Y');
961
962 compare("before execute");
963
964 migration_execute(m_ioctx, m_image_name);
965 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
966 migration_commit(m_ioctx, m_image_name);
967 }
968
969 TEST_F(TestMigration, SnapsSnapAfterPrepare)
970 {
971 test_snaps();
972
973 migration_prepare(m_ioctx, m_image_name);
974 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
975
976 auto ictx = new librbd::ImageCtx(m_ictx->name.c_str(), "", "snap3", m_ioctx,
977 false);
978 ASSERT_EQ(0, ictx->state->open(0));
979 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
980 m_ref_ictx, cls::rbd::UserSnapshotNamespace(), "snap3"));
981 compare_snaps("opened after prepare snap3", m_ref_ictx, ictx);
982 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
983 m_ref_ictx, cls::rbd::UserSnapshotNamespace(), nullptr));
984 EXPECT_EQ(0, ictx->state->close());
985
986 snap_create("after_prepare_snap");
987 resize(m_ictx->size >> 1);
988 write(0, 1000, '*');
989
990 migration_execute(m_ioctx, m_image_name);
991 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
992 migration_commit(m_ioctx, m_image_name);
993 }
994
995 TEST_F(TestMigration, SnapsSnapExpandAfterPrepare)
996 {
997 test_snaps();
998
999 migration_prepare(m_ioctx, m_image_name);
1000 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED);
1001
1002 snap_create("after_prepare_snap");
1003 auto size = m_ictx->size;
1004 resize(size << 1);
1005 write(size, 1000, '*');
1006
1007 migration_execute(m_ioctx, m_image_name);
1008 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED);
1009 migration_commit(m_ioctx, m_image_name);
1010 }
1011
1012 TEST_F(TestMigration, Clone)
1013 {
1014 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
1015
1016 test_clone();
1017 migrate(m_ioctx, m_image_name);
1018 }
1019
1020 TEST_F(TestMigration, CloneParent) {
1021 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
1022
1023 snap_create("snap");
1024
1025 librbd::linked_image_spec_t expected_parent_image;
1026 expected_parent_image.image_id = m_ictx->id;
1027 expected_parent_image.image_name = m_ictx->name;
1028
1029 auto it = m_ictx->snap_ids.find({cls::rbd::UserSnapshotNamespace{}, "snap"});
1030 ASSERT_TRUE(it != m_ictx->snap_ids.end());
1031
1032 librbd::snap_spec_t expected_parent_snap;
1033 expected_parent_snap.id = it->second;
1034
1035 clone("snap");
1036 migration_prepare(m_ioctx, m_image_name);
1037
1038 librbd::linked_image_spec_t parent_image;
1039 librbd::snap_spec_t parent_snap;
1040 ASSERT_EQ(0, librbd::api::Image<>::get_parent(m_ictx, &parent_image,
1041 &parent_snap));
1042 ASSERT_EQ(expected_parent_image.image_id, parent_image.image_id);
1043 ASSERT_EQ(expected_parent_image.image_name, parent_image.image_name);
1044 ASSERT_EQ(expected_parent_snap.id, parent_snap.id);
1045
1046 migration_abort(m_ioctx, m_image_name);
1047 }
1048
1049
1050 TEST_F(TestMigration, CloneUpdateAfterPrepare)
1051 {
1052 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
1053
1054 write(0, 10, 'X');
1055 snap_create("snap");
1056 clone("snap");
1057
1058 migration_prepare(m_ioctx, m_image_name);
1059
1060 write(0, 1, 'Y');
1061
1062 migration_execute(m_ioctx, m_image_name);
1063 migration_commit(m_ioctx, m_image_name);
1064 }
1065
1066 TEST_F(TestMigration, TriggerAssertSnapcSeq)
1067 {
1068 auto size = m_ictx->size;
1069
1070 write((size >> 1) + 0, 10, 'A');
1071 snap_create("snap1");
1072 write((size >> 1) + 1, 10, 'B');
1073
1074 migration_prepare(m_ioctx, m_image_name);
1075
1076 // copyup => deep copy (first time)
1077 write((size >> 1) + 2, 10, 'C');
1078
1079 // preserve data before resizing
1080 snap_create("snap2");
1081
1082 // decrease head overlap
1083 resize(size >> 1);
1084
1085 // migrate object => deep copy (second time) => assert_snapc_seq => -ERANGE
1086 migration_execute(m_ioctx, m_image_name);
1087 migration_commit(m_ioctx, m_image_name);
1088 }
1089
1090 TEST_F(TestMigration, SnapTrimBeforePrepare)
1091 {
1092 auto size = m_ictx->size;
1093
1094 write(size >> 1, 10, 'A');
1095 snap_create("snap1");
1096 resize(size >> 1);
1097
1098 migration_prepare(m_ioctx, m_image_name);
1099
1100 resize(size);
1101 snap_create("snap3");
1102 write(size >> 1, 10, 'B');
1103 snap_create("snap4");
1104 resize(size >> 1);
1105
1106 migration_execute(m_ioctx, m_image_name);
1107 migration_commit(m_ioctx, m_image_name);
1108 }
1109
1110 TEST_F(TestMigration, CloneV1Parent)
1111 {
1112 const uint32_t CLONE_FORMAT = 1;
1113 test_migrate_parent(
1114 CLONE_FORMAT, [this](librbd::ImageCtx *) {
1115 migrate(m_ioctx, m_image_name);
1116 });
1117 }
1118
1119 TEST_F(TestMigration, CloneV2Parent)
1120 {
1121 const uint32_t CLONE_FORMAT = 2;
1122 test_migrate_parent(
1123 CLONE_FORMAT, [this](librbd::ImageCtx *) {
1124 migrate(m_ioctx, m_image_name);
1125 });
1126 }
1127
1128 TEST_F(TestMigration, CloneV1ParentAbort)
1129 {
1130 const uint32_t CLONE_FORMAT = 1;
1131 test_migrate_parent(
1132 CLONE_FORMAT, [this](librbd::ImageCtx *) {
1133 migration_prepare(m_ioctx, m_image_name);
1134 migration_abort(m_ioctx, m_image_name);
1135 });
1136 }
1137
1138 TEST_F(TestMigration, CloneV2ParentAbort)
1139 {
1140 const uint32_t CLONE_FORMAT = 2;
1141 test_migrate_parent(
1142 CLONE_FORMAT, [this](librbd::ImageCtx *) {
1143 migration_prepare(m_ioctx, m_image_name);
1144 migration_abort(m_ioctx, m_image_name);
1145 });
1146 }
1147
1148 TEST_F(TestMigration, CloneV1ParentAbortFixIncompleteChildReattach)
1149 {
1150 const uint32_t CLONE_FORMAT = 1;
1151 test_migrate_parent(
1152 CLONE_FORMAT, [this](librbd::ImageCtx *child_ictx) {
1153 auto src_image_id = m_ictx->id;
1154 migration_prepare(m_ioctx, m_image_name);
1155 // Attach the child to both source and destination
1156 // to emulate a crash when re-attaching the child
1157 librbd::ImageCtx *src_ictx;
1158 open_image(m_ioctx, "", src_image_id, false,
1159 librbd::OPEN_FLAG_IGNORE_MIGRATING, &src_ictx);
1160 C_SaferCond cond;
1161 auto req = librbd::image::AttachChildRequest<>::create(
1162 child_ictx, src_ictx, src_ictx->snaps[0], nullptr, 0,
1163 CLONE_FORMAT, &cond);
1164 req->send();
1165 ASSERT_EQ(0, cond.wait());
1166 close_image(src_ictx);
1167 migration_abort(m_ioctx, m_image_name);
1168 });
1169 }
1170
1171 TEST_F(TestMigration, CloneV1ParentAbortFixParentReattach)
1172 {
1173 const uint32_t CLONE_FORMAT = 1;
1174 test_migrate_parent(
1175 CLONE_FORMAT, [this](librbd::ImageCtx *child_ictx) {
1176 auto src_image_id = m_ictx->id;
1177 migration_prepare(m_ioctx, m_image_name);
1178 // Re-attach the child back to the source to emulate a crash
1179 // after the parent reattach but before the child reattach
1180 librbd::ImageCtx *src_ictx;
1181 open_image(m_ioctx, "", src_image_id, false,
1182 librbd::OPEN_FLAG_IGNORE_MIGRATING, &src_ictx);
1183 C_SaferCond cond;
1184 auto req = librbd::image::AttachChildRequest<>::create(
1185 child_ictx, src_ictx, src_ictx->snaps[0], m_ictx,
1186 m_ictx->snaps[0], CLONE_FORMAT, &cond);
1187 req->send();
1188 ASSERT_EQ(0, cond.wait());
1189 close_image(src_ictx);
1190 migration_abort(m_ioctx, m_image_name);
1191 });
1192 }
1193
1194 TEST_F(TestMigration, CloneV1ParentAbortRelinkNotNeeded)
1195 {
1196 const uint32_t CLONE_FORMAT = 1;
1197 test_migrate_parent(
1198 CLONE_FORMAT, [this](librbd::ImageCtx *child_ictx) {
1199 auto src_image_id = m_ictx->id;
1200 auto parent_spec = child_ictx->parent_md.spec;
1201 parent_spec.image_id = m_ictx->id;
1202 parent_spec.snap_id = m_ictx->snaps[0];
1203 auto parent_overlap = child_ictx->parent_md.overlap;
1204 migration_prepare(m_ioctx, m_image_name);
1205 // Relink the child back to emulate a crash
1206 // before relinking the child
1207 C_SaferCond cond;
1208 auto req = librbd::image::AttachParentRequest<>::create(
1209 *child_ictx, parent_spec, parent_overlap, true, &cond);
1210 req->send();
1211 ASSERT_EQ(0, cond.wait());
1212 librbd::ImageCtx *src_ictx;
1213 open_image(m_ioctx, "", src_image_id, false,
1214 librbd::OPEN_FLAG_IGNORE_MIGRATING, &src_ictx);
1215 C_SaferCond cond1;
1216 auto req1 = librbd::image::AttachChildRequest<>::create(
1217 child_ictx, src_ictx, src_ictx->snaps[0], m_ictx,
1218 m_ictx->snaps[0], CLONE_FORMAT, &cond1);
1219 req1->send();
1220 ASSERT_EQ(0, cond1.wait());
1221 close_image(src_ictx);
1222 migration_abort(m_ioctx, m_image_name);
1223 });
1224 }
1225
1226 TEST_F(TestMigration, CloneV2ParentAbortFixIncompleteChildReattach)
1227 {
1228 const uint32_t CLONE_FORMAT = 2;
1229 test_migrate_parent(
1230 CLONE_FORMAT, [this](librbd::ImageCtx *child_ictx) {
1231 auto src_image_id = m_ictx->id;
1232 migration_prepare(m_ioctx, m_image_name);
1233 // Attach the child to both source and destination
1234 // to emulate a crash when re-attaching the child
1235 librbd::ImageCtx *src_ictx;
1236 open_image(m_ioctx, "", src_image_id, false,
1237 librbd::OPEN_FLAG_IGNORE_MIGRATING, &src_ictx);
1238 C_SaferCond cond;
1239 auto req = librbd::image::AttachChildRequest<>::create(
1240 child_ictx, src_ictx, src_ictx->snaps[0], nullptr, 0,
1241 CLONE_FORMAT, &cond);
1242 req->send();
1243 ASSERT_EQ(0, cond.wait());
1244 close_image(src_ictx);
1245 migration_abort(m_ioctx, m_image_name);
1246 });
1247 }
1248
1249 TEST_F(TestMigration, CloneV2ParentAbortFixParentReattach)
1250 {
1251 const uint32_t CLONE_FORMAT = 2;
1252 test_migrate_parent(
1253 CLONE_FORMAT, [this](librbd::ImageCtx *child_ictx) {
1254 auto src_image_id = m_ictx->id;
1255 migration_prepare(m_ioctx, m_image_name);
1256 // Re-attach the child back to the source to emulate a crash
1257 // after the parent reattach but before the child reattach
1258 librbd::ImageCtx *src_ictx;
1259 open_image(m_ioctx, "", src_image_id, false,
1260 librbd::OPEN_FLAG_IGNORE_MIGRATING, &src_ictx);
1261 C_SaferCond cond;
1262 auto req = librbd::image::AttachChildRequest<>::create(
1263 child_ictx, src_ictx, src_ictx->snaps[0], m_ictx,
1264 m_ictx->snaps[0], CLONE_FORMAT, &cond);
1265 req->send();
1266 ASSERT_EQ(0, cond.wait());
1267 close_image(src_ictx);
1268 migration_abort(m_ioctx, m_image_name);
1269 });
1270 }
1271
1272 TEST_F(TestMigration, CloneV2ParentAbortRelinkNotNeeded)
1273 {
1274 const uint32_t CLONE_FORMAT = 2;
1275 test_migrate_parent(
1276 CLONE_FORMAT, [this](librbd::ImageCtx *child_ictx) {
1277 auto src_image_id = m_ictx->id;
1278 auto parent_spec = child_ictx->parent_md.spec;
1279 parent_spec.image_id = m_ictx->id;
1280 parent_spec.snap_id = m_ictx->snaps[0];
1281 auto parent_overlap = child_ictx->parent_md.overlap;
1282 migration_prepare(m_ioctx, m_image_name);
1283 // Relink the child back to emulate a crash
1284 // before relinking the child
1285 C_SaferCond cond;
1286 auto req = librbd::image::AttachParentRequest<>::create(
1287 *child_ictx, parent_spec, parent_overlap, true, &cond);
1288 req->send();
1289 ASSERT_EQ(0, cond.wait());
1290 librbd::ImageCtx *src_ictx;
1291 open_image(m_ioctx, "", src_image_id, false,
1292 librbd::OPEN_FLAG_IGNORE_MIGRATING, &src_ictx);
1293 C_SaferCond cond1;
1294 auto req1 = librbd::image::AttachChildRequest<>::create(
1295 child_ictx, src_ictx, src_ictx->snaps[0], m_ictx,
1296 m_ictx->snaps[0], CLONE_FORMAT, &cond1);
1297 req1->send();
1298 ASSERT_EQ(0, cond1.wait());
1299 close_image(src_ictx);
1300 migration_abort(m_ioctx, m_image_name);
1301 });
1302 }
1303
1304 TEST_F(TestMigration, StressNoMigrate)
1305 {
1306 test_stress();
1307
1308 compare();
1309 }
1310
1311 TEST_F(TestMigration, Stress)
1312 {
1313 test_stress();
1314
1315 migrate(m_ioctx, m_image_name);
1316 }
1317
1318 TEST_F(TestMigration, Stress2)
1319 {
1320 test_stress2(false);
1321 }
1322
1323 TEST_F(TestMigration, StressLive)
1324 {
1325 test_stress2(true);
1326 }