1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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>
23 void register_test_migration() {
26 struct TestMigration
: public TestFixture
{
27 static void SetUpTestCase() {
28 TestFixture::SetUpTestCase();
30 _other_pool_name
= get_temp_pool_name("test-librbd-");
31 ASSERT_EQ(0, _rados
.pool_create(_other_pool_name
.c_str()));
34 static void TearDownTestCase() {
35 ASSERT_EQ(0, _rados
.pool_delete(_other_pool_name
.c_str()));
37 TestFixture::TearDownTestCase();
40 void SetUp() override
{
43 ASSERT_EQ(0, _rados
.ioctx_create(_other_pool_name
.c_str(),
46 open_image(m_ioctx
, m_image_name
, &m_ictx
);
47 m_image_id
= m_ictx
->id
;
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
);
54 resize(20 * (1 << 22));
57 void TearDown() override
{
58 if (m_ref_ictx
!= nullptr) {
59 close_image(m_ref_ictx
);
61 if (m_ictx
!= nullptr) {
65 _other_pool_ioctx
.close();
67 TestFixture::TearDown();
70 void compare(const std::string
&description
= "") {
71 vector
<librbd::snap_info_t
> src_snaps
, dst_snaps
;
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();
85 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
86 m_ref_ictx
, cls::rbd::UserSnapshotNamespace(),
88 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
89 m_ictx
, cls::rbd::UserSnapshotNamespace(),
92 description
+ " snap: " + (src_snap_name
? src_snap_name
: "null"),
97 void compare_snaps(const std::string
&description
, librbd::ImageCtx
*src_ictx
,
98 librbd::ImageCtx
*dst_ictx
) {
99 uint64_t src_size
, dst_size
;
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
);
106 if (src_size
!= dst_size
) {
107 std::cout
<< description
<< ": size differs" << std::endl
;
108 EXPECT_EQ(src_size
, dst_size
);
111 if (dst_ictx
->test_features(RBD_FEATURE_LAYERING
)) {
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
);
120 ssize_t read_size
= 1 << src_ictx
->order
;
122 while (offset
< src_size
) {
123 read_size
= std::min(read_size
, static_cast<ssize_t
>(src_size
- offset
));
125 bufferptr
src_ptr(read_size
);
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));
132 bufferptr
dst_ptr(read_size
);
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));
139 if (!src_bl
.contents_equal(dst_bl
)) {
140 std::cout
<< description
141 << ", block " << offset
<< "~" << read_size
<< " differs"
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
);
149 EXPECT_TRUE(src_bl
.contents_equal(dst_bl
));
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
);
160 ASSERT_EQ(0, (*ictx
)->state
->open(flags
));
161 (*ictx
)->discard_granularity_bytes
= 0;
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
);
169 void migration_prepare(librados::IoCtx
& dst_io_ctx
,
170 const std::string
&dst_name
, int r
= 0) {
171 std::cout
<< __func__
<< std::endl
;
176 EXPECT_EQ(r
, librbd::api::Migration
<>::prepare(m_ioctx
, m_image_name
,
177 dst_io_ctx
, dst_name
,
180 open_image(dst_io_ctx
, dst_name
, &m_ictx
);
182 open_image(m_ioctx
, m_image_name
, &m_ictx
);
184 compare("after prepare");
187 void migration_execute(librados::IoCtx
& io_ctx
, const std::string
&name
,
189 std::cout
<< __func__
<< std::endl
;
191 librbd::NoOpProgressContext no_op
;
192 EXPECT_EQ(r
, librbd::api::Migration
<>::execute(io_ctx
, name
, no_op
));
195 void migration_abort(librados::IoCtx
& io_ctx
, const std::string
&name
,
197 std::cout
<< __func__
<< std::endl
;
199 std::string dst_name
= m_ictx
->name
;
203 librbd::NoOpProgressContext no_op
;
204 EXPECT_EQ(r
, librbd::api::Migration
<>::abort(io_ctx
, name
, no_op
));
207 open_image(m_ioctx
, m_image_name
, &m_ictx
);
209 open_image(m_ioctx
, dst_name
, &m_ictx
);
212 compare("after abort");
215 void migration_commit(librados::IoCtx
& io_ctx
, const std::string
&name
) {
216 std::cout
<< __func__
<< std::endl
;
218 librbd::NoOpProgressContext no_op
;
219 EXPECT_EQ(0, librbd::api::Migration
<>::commit(io_ctx
, name
, no_op
));
221 compare("after commit");
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
,
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
);
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
);
247 void write(uint64_t off
, uint64_t len
, char c
) {
248 std::cout
<< "write: " << c
<< " " << off
<< "~" << len
<< std::endl
;
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));
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));
260 void discard(uint64_t off
, uint64_t len
) {
261 std::cout
<< "discard: " << off
<< "~" << len
<< std::endl
;
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));
270 ASSERT_EQ(0, m_ref_ictx
->io_work_queue
->flush());
271 ASSERT_EQ(0, m_ictx
->io_work_queue
->flush());
274 void snap_create(const std::string
&snap_name
) {
275 std::cout
<< "snap_create: " << snap_name
<< std::endl
;
279 ASSERT_EQ(0, TestFixture::snap_create(*m_ref_ictx
, snap_name
));
280 ASSERT_EQ(0, TestFixture::snap_create(*m_ictx
, snap_name
));
283 void snap_protect(const std::string
&snap_name
) {
284 std::cout
<< "snap_protect: " << snap_name
<< std::endl
;
286 ASSERT_EQ(0, TestFixture::snap_protect(*m_ref_ictx
, snap_name
));
287 ASSERT_EQ(0, TestFixture::snap_protect(*m_ictx
, snap_name
));
290 void clone(const std::string
&snap_name
) {
291 snap_protect(snap_name
);
293 int order
= m_ref_ictx
->order
;
295 ASSERT_EQ(0, librbd::get_features(m_ref_ictx
, &features
));
296 features
&= ~RBD_FEATURES_IMPLICIT_ENABLE
;
298 std::string ref_clone_name
= get_temp_image_name();
299 std::string clone_name
= get_temp_image_name();
301 std::cout
<< "clone " << m_ictx
->name
<< " -> " << clone_name
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
));
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
,
314 m_ictx
->stripe_count
));
316 close_image(m_ref_ictx
);
317 open_image(m_ref_ioctx
, ref_clone_name
, &m_ref_ictx
);
320 open_image(m_ioctx
, clone_name
, &m_ictx
);
321 m_image_name
= m_ictx
->name
;
322 m_image_id
= m_ictx
->id
;
325 void resize(uint64_t size
) {
326 std::cout
<< "resize: " << size
<< std::endl
;
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
));
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');
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');
346 write(0 * len
, 1000, 'X');
347 discard(1000 + 10, 1000);
349 snap_create("snap2");
351 write(1 * len
, 1000, 'X');
352 discard(2 * len
+ 10, 1000);
354 uint64_t size
= m_ictx
->size
;
358 write(size
- 1, len
, '2');
360 snap_create("snap3");
364 discard(size
- 1, 1);
370 uint64_t len
= (1 << m_ictx
->order
) * 2 + 1;
371 write(0 * len
, len
, 'X');
372 write(2 * len
, len
, 'X');
383 write(1000, 1000, 'X');
389 template <typename L
>
390 void test_migrate_parent(uint32_t clone_format
, L
&& test
) {
391 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
393 std::string prev_clone_format
;
394 ASSERT_EQ(0, _rados
.conf_get("rbd_default_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
;
403 snap_create("snap1");
404 snap_protect("snap1");
406 int order
= m_ictx
->order
;
408 ASSERT_EQ(0, librbd::get_features(m_ictx
, &features
));
409 features
&= ~RBD_FEATURES_IMPLICIT_ENABLE
;
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
));
416 librbd::ImageCtx
*child_ictx
;
417 open_image(m_ioctx
, clone_name
, &child_ictx
);
421 ASSERT_EQ(0, child_ictx
->state
->refresh());
426 librbd::io::ReadResult result
{&bl
};
427 ASSERT_EQ(10, child_ictx
->io_work_queue
->read(
428 0, 10, librbd::io::ReadResult
{result
}, 0));
430 ref_bl
.append(std::string(10, 'A'));
431 ASSERT_TRUE(ref_bl
.contents_equal(bl
));
432 close_image(child_ictx
);
435 void test_stress(const std::string
&snap_name_prefix
= "snap",
436 char start_char
= 'A') {
437 uint64_t initial_size
= m_ictx
->size
;
440 const char *c
= getenv("TEST_RBD_MIGRATION_STRESS_NSNAPS");
442 std::stringstream
ss(c
);
443 ASSERT_TRUE(ss
>> nsnaps
);
447 c
= getenv("TEST_RBD_MIGRATION_STRESS_NWRITES");
449 std::stringstream
ss(c
);
450 ASSERT_TRUE(ss
>> nwrites
);
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
);
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
));
468 std::string snap_name
= snap_name_prefix
+ stringify(i
);
469 snap_create(snap_name
);
471 if (m_ictx
->test_features(RBD_FEATURE_LAYERING
) &&
472 !m_ictx
->test_features(RBD_FEATURE_MIGRATING
) &&
478 librbd::NoOpProgressContext no_op
;
479 uint64_t new_size
= initial_size
+ rand() % m_ictx
->size
;
481 ASSERT_EQ(new_size
, m_ictx
->size
);
487 void test_stress2(bool concurrent
) {
490 migration_prepare(m_ioctx
, m_image_name
);
491 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
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
);
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
);
515 compare("before execute");
516 migration_execute(m_ioctx
, m_image_name
);
519 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
520 migration_commit(m_ioctx
, m_image_name
);
523 static std::string _other_pool_name
;
524 static librados::IoCtx _other_pool_ioctx
;
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
;
533 std::string
TestMigration::_other_pool_name
;
534 librados::IoCtx
TestMigration::_other_pool_ioctx
;
536 TEST_F(TestMigration
, Empty
)
538 uint64_t features
= m_ictx
->features
^ RBD_FEATURE_LAYERING
;
539 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FEATURES
, features
));
541 migrate(m_ioctx
, m_image_name
);
543 ASSERT_EQ(features
, m_ictx
->features
);
546 TEST_F(TestMigration
, OtherName
)
548 std::string name
= get_temp_image_name();
550 migrate(m_ioctx
, name
);
552 ASSERT_EQ(name
, m_ictx
->name
);
555 TEST_F(TestMigration
, OtherPool
)
557 migrate(_other_pool_ioctx
, m_image_name
);
559 ASSERT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->md_ctx
.get_id());
562 TEST_F(TestMigration
, OtherNamespace
)
564 ASSERT_EQ(0, librbd::api::Namespace
<>::create(_other_pool_ioctx
, "ns1"));
565 _other_pool_ioctx
.set_namespace("ns1");
567 migrate(_other_pool_ioctx
, m_image_name
);
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("");
574 TEST_F(TestMigration
, DataPool
)
576 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_DATA_POOL
,
577 _other_pool_ioctx
.get_pool_name().c_str()));
579 migrate(m_ioctx
, m_image_name
);
581 ASSERT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->data_ctx
.get_id());
584 TEST_F(TestMigration
, AbortAfterPrepare
)
586 migration_prepare(m_ioctx
, m_image_name
);
587 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
588 migration_abort(m_ioctx
, m_image_name
);
591 TEST_F(TestMigration
, AbortAfterFailedPrepare
)
593 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_DATA_POOL
, "INVALID_POOL"));
595 migration_prepare(m_ioctx
, m_image_name
, -ENOENT
);
597 // Migration is automatically aborted if prepare failed
600 TEST_F(TestMigration
, AbortAfterExecute
)
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
);
609 TEST_F(TestMigration
, OtherPoolAbortAfterExecute
)
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
);
618 TEST_F(TestMigration
, OtherNamespaceAbortAfterExecute
)
620 ASSERT_EQ(0, librbd::api::Namespace
<>::create(_other_pool_ioctx
, "ns2"));
621 _other_pool_ioctx
.set_namespace("ns2");
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
);
629 _other_pool_ioctx
.set_namespace("");
630 ASSERT_EQ(0, librbd::api::Namespace
<>::remove(_other_pool_ioctx
, "ns2"));
633 TEST_F(TestMigration
, MirroringSamePool
)
635 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
637 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
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
);
645 migrate(m_ioctx
, m_image_name
);
647 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
648 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
651 TEST_F(TestMigration
, MirroringAbort
)
653 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
655 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
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
);
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
);
668 migration_abort(m_ioctx
, m_image_name
);
670 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
671 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
674 TEST_F(TestMigration
, MirroringOtherPoolDisabled
)
676 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
678 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
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
);
686 migrate(_other_pool_ioctx
, m_image_name
);
688 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
689 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED
, info
.state
);
692 TEST_F(TestMigration
, MirroringOtherPoolEnabled
)
694 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
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
));
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
);
706 migrate(_other_pool_ioctx
, m_image_name
);
708 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
709 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
712 TEST_F(TestMigration
, MirroringPool
)
714 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
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
);
722 migrate(_other_pool_ioctx
, m_image_name
);
724 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
725 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
728 TEST_F(TestMigration
, Group
)
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
));
738 std::string name
= get_temp_image_name();
740 migrate(m_ioctx
, name
);
742 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
743 ASSERT_EQ(info
.name
, "123");
745 ASSERT_EQ(0, librbd::api::Group
<>::image_remove(m_ioctx
, "123", m_ioctx
,
747 ASSERT_EQ(0, librbd::api::Group
<>::remove(m_ioctx
, "123"));
750 TEST_F(TestMigration
, GroupAbort
)
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
));
760 std::string name
= get_temp_image_name();
762 migration_prepare(m_ioctx
, name
);
763 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
765 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
766 ASSERT_EQ(info
.name
, "123");
768 migration_abort(m_ioctx
, m_image_name
);
770 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
771 ASSERT_EQ(info
.name
, "123");
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"));
778 TEST_F(TestMigration
, NoSnaps
)
781 migrate(m_ioctx
, m_image_name
);
784 TEST_F(TestMigration
, NoSnapsOtherPool
)
789 migrate(_other_pool_ioctx
, m_image_name
);
792 TEST_F(TestMigration
, NoSnapsDataPool
)
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
);
800 EXPECT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->data_ctx
.get_id());
803 TEST_F(TestMigration
, NoSnapsShrinkAfterPrepare
)
807 migration_prepare(m_ioctx
, m_image_name
);
808 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
810 resize(m_ictx
->size
>> 1);
812 migration_execute(m_ioctx
, m_image_name
);
813 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
814 migration_commit(m_ioctx
, m_image_name
);
817 TEST_F(TestMigration
, NoSnapsShrinkToZeroBeforePrepare
)
822 migrate(m_ioctx
, m_image_name
);
825 TEST_F(TestMigration
, NoSnapsShrinkToZeroAfterPrepare
)
829 migration_prepare(m_ioctx
, m_image_name
);
830 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
834 migration_execute(m_ioctx
, m_image_name
);
835 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
836 migration_commit(m_ioctx
, m_image_name
);
839 TEST_F(TestMigration
, NoSnapsExpandAfterPrepare
)
843 migration_prepare(m_ioctx
, m_image_name
);
844 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
846 resize(m_ictx
->size
<< 1);
848 migration_execute(m_ioctx
, m_image_name
);
849 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
850 migration_commit(m_ioctx
, m_image_name
);
853 TEST_F(TestMigration
, NoSnapsSnapAfterPrepare
)
857 migration_prepare(m_ioctx
, m_image_name
);
858 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
860 snap_create("after_prepare_snap");
861 resize(m_ictx
->size
>> 1);
864 migration_execute(m_ioctx
, m_image_name
);
865 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
866 migration_commit(m_ioctx
, m_image_name
);
869 TEST_F(TestMigration
, Snaps
)
872 migrate(m_ioctx
, m_image_name
);
875 TEST_F(TestMigration
, SnapsOtherPool
)
880 migrate(_other_pool_ioctx
, m_image_name
);
882 EXPECT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->md_ctx
.get_id());
885 TEST_F(TestMigration
, SnapsDataPool
)
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
);
893 EXPECT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->data_ctx
.get_id());
896 TEST_F(TestMigration
, SnapsShrinkAfterPrepare
)
900 migration_prepare(m_ioctx
, m_image_name
);
901 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
903 resize(m_ictx
->size
>> 1);
905 migration_execute(m_ioctx
, m_image_name
);
906 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
907 migration_commit(m_ioctx
, m_image_name
);
910 TEST_F(TestMigration
, SnapsShrinkToZeroBeforePrepare
)
915 migrate(m_ioctx
, m_image_name
);
918 TEST_F(TestMigration
, SnapsShrinkToZeroAfterPrepare
)
922 migration_prepare(m_ioctx
, m_image_name
);
923 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
927 migration_execute(m_ioctx
, m_image_name
);
928 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
929 migration_commit(m_ioctx
, m_image_name
);
932 TEST_F(TestMigration
, SnapsExpandAfterPrepare
)
936 migration_prepare(m_ioctx
, m_image_name
);
937 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
939 auto size
= m_ictx
->size
;
941 write(size
, 1000, '*');
943 migration_execute(m_ioctx
, m_image_name
);
944 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
945 migration_commit(m_ioctx
, m_image_name
);
948 TEST_F(TestMigration
, SnapsExpandAfterPrepare2
)
950 auto size
= m_ictx
->size
;
952 write(size
>> 1, 10, 'X');
953 snap_create("snap1");
956 migration_prepare(m_ioctx
, m_image_name
);
957 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
960 write(size
>> 1, 5, 'Y');
962 compare("before execute");
964 migration_execute(m_ioctx
, m_image_name
);
965 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
966 migration_commit(m_ioctx
, m_image_name
);
969 TEST_F(TestMigration
, SnapsSnapAfterPrepare
)
973 migration_prepare(m_ioctx
, m_image_name
);
974 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
976 auto ictx
= new librbd::ImageCtx(m_ictx
->name
.c_str(), "", "snap3", m_ioctx
,
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());
986 snap_create("after_prepare_snap");
987 resize(m_ictx
->size
>> 1);
990 migration_execute(m_ioctx
, m_image_name
);
991 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
992 migration_commit(m_ioctx
, m_image_name
);
995 TEST_F(TestMigration
, SnapsSnapExpandAfterPrepare
)
999 migration_prepare(m_ioctx
, m_image_name
);
1000 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1002 snap_create("after_prepare_snap");
1003 auto size
= m_ictx
->size
;
1005 write(size
, 1000, '*');
1007 migration_execute(m_ioctx
, m_image_name
);
1008 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
1009 migration_commit(m_ioctx
, m_image_name
);
1012 TEST_F(TestMigration
, Clone
)
1014 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
1017 migrate(m_ioctx
, m_image_name
);
1020 TEST_F(TestMigration
, CloneParent
) {
1021 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
1023 snap_create("snap");
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
;
1029 auto it
= m_ictx
->snap_ids
.find({cls::rbd::UserSnapshotNamespace
{}, "snap"});
1030 ASSERT_TRUE(it
!= m_ictx
->snap_ids
.end());
1032 librbd::snap_spec_t expected_parent_snap
;
1033 expected_parent_snap
.id
= it
->second
;
1036 migration_prepare(m_ioctx
, m_image_name
);
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
,
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
);
1046 migration_abort(m_ioctx
, m_image_name
);
1050 TEST_F(TestMigration
, CloneUpdateAfterPrepare
)
1052 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
1055 snap_create("snap");
1058 migration_prepare(m_ioctx
, m_image_name
);
1062 migration_execute(m_ioctx
, m_image_name
);
1063 migration_commit(m_ioctx
, m_image_name
);
1066 TEST_F(TestMigration
, TriggerAssertSnapcSeq
)
1068 auto size
= m_ictx
->size
;
1070 write((size
>> 1) + 0, 10, 'A');
1071 snap_create("snap1");
1072 write((size
>> 1) + 1, 10, 'B');
1074 migration_prepare(m_ioctx
, m_image_name
);
1076 // copyup => deep copy (first time)
1077 write((size
>> 1) + 2, 10, 'C');
1079 // preserve data before resizing
1080 snap_create("snap2");
1082 // decrease head overlap
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
);
1090 TEST_F(TestMigration
, SnapTrimBeforePrepare
)
1092 auto size
= m_ictx
->size
;
1094 write(size
>> 1, 10, 'A');
1095 snap_create("snap1");
1098 migration_prepare(m_ioctx
, m_image_name
);
1101 snap_create("snap3");
1102 write(size
>> 1, 10, 'B');
1103 snap_create("snap4");
1106 migration_execute(m_ioctx
, m_image_name
);
1107 migration_commit(m_ioctx
, m_image_name
);
1110 TEST_F(TestMigration
, CloneV1Parent
)
1112 const uint32_t CLONE_FORMAT
= 1;
1113 test_migrate_parent(
1114 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1115 migrate(m_ioctx
, m_image_name
);
1119 TEST_F(TestMigration
, CloneV2Parent
)
1121 const uint32_t CLONE_FORMAT
= 2;
1122 test_migrate_parent(
1123 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1124 migrate(m_ioctx
, m_image_name
);
1128 TEST_F(TestMigration
, CloneV1ParentAbort
)
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
);
1138 TEST_F(TestMigration
, CloneV2ParentAbort
)
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
);
1148 TEST_F(TestMigration
, CloneV1ParentAbortFixIncompleteChildReattach
)
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
);
1161 auto req
= librbd::image::AttachChildRequest
<>::create(
1162 child_ictx
, src_ictx
, src_ictx
->snaps
[0], nullptr, 0,
1163 CLONE_FORMAT
, &cond
);
1165 ASSERT_EQ(0, cond
.wait());
1166 close_image(src_ictx
);
1167 migration_abort(m_ioctx
, m_image_name
);
1171 TEST_F(TestMigration
, CloneV1ParentAbortFixParentReattach
)
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
);
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
);
1188 ASSERT_EQ(0, cond
.wait());
1189 close_image(src_ictx
);
1190 migration_abort(m_ioctx
, m_image_name
);
1194 TEST_F(TestMigration
, CloneV1ParentAbortRelinkNotNeeded
)
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
1208 auto req
= librbd::image::AttachParentRequest
<>::create(
1209 *child_ictx
, parent_spec
, parent_overlap
, true, &cond
);
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
);
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
);
1220 ASSERT_EQ(0, cond1
.wait());
1221 close_image(src_ictx
);
1222 migration_abort(m_ioctx
, m_image_name
);
1226 TEST_F(TestMigration
, CloneV2ParentAbortFixIncompleteChildReattach
)
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
);
1239 auto req
= librbd::image::AttachChildRequest
<>::create(
1240 child_ictx
, src_ictx
, src_ictx
->snaps
[0], nullptr, 0,
1241 CLONE_FORMAT
, &cond
);
1243 ASSERT_EQ(0, cond
.wait());
1244 close_image(src_ictx
);
1245 migration_abort(m_ioctx
, m_image_name
);
1249 TEST_F(TestMigration
, CloneV2ParentAbortFixParentReattach
)
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
);
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
);
1266 ASSERT_EQ(0, cond
.wait());
1267 close_image(src_ictx
);
1268 migration_abort(m_ioctx
, m_image_name
);
1272 TEST_F(TestMigration
, CloneV2ParentAbortRelinkNotNeeded
)
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
1286 auto req
= librbd::image::AttachParentRequest
<>::create(
1287 *child_ictx
, parent_spec
, parent_overlap
, true, &cond
);
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
);
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
);
1298 ASSERT_EQ(0, cond1
.wait());
1299 close_image(src_ictx
);
1300 migration_abort(m_ioctx
, m_image_name
);
1304 TEST_F(TestMigration
, StressNoMigrate
)
1311 TEST_F(TestMigration
, Stress
)
1315 migrate(m_ioctx
, m_image_name
);
1318 TEST_F(TestMigration
, Stress2
)
1320 test_stress2(false);
1323 TEST_F(TestMigration
, StressLive
)