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
));
297 std::string ref_clone_name
= get_temp_image_name();
298 std::string clone_name
= get_temp_image_name();
300 std::cout
<< "clone " << m_ictx
->name
<< " -> " << clone_name
303 ASSERT_EQ(0, librbd::clone(m_ref_ictx
->md_ctx
, m_ref_ictx
->name
.c_str(),
304 snap_name
.c_str(), m_ref_ioctx
,
305 ref_clone_name
.c_str(), features
, &order
,
306 m_ref_ictx
->stripe_unit
,
307 m_ref_ictx
->stripe_count
));
309 ASSERT_EQ(0, librbd::clone(m_ictx
->md_ctx
, m_ictx
->name
.c_str(),
310 snap_name
.c_str(), m_ioctx
,
311 clone_name
.c_str(), features
, &order
,
313 m_ictx
->stripe_count
));
315 close_image(m_ref_ictx
);
316 open_image(m_ref_ioctx
, ref_clone_name
, &m_ref_ictx
);
319 open_image(m_ioctx
, clone_name
, &m_ictx
);
320 m_image_name
= m_ictx
->name
;
321 m_image_id
= m_ictx
->id
;
324 void resize(uint64_t size
) {
325 std::cout
<< "resize: " << size
<< std::endl
;
327 librbd::NoOpProgressContext no_op
;
328 ASSERT_EQ(0, m_ref_ictx
->operations
->resize(size
, true, no_op
));
329 ASSERT_EQ(0, m_ictx
->operations
->resize(size
, true, no_op
));
332 void test_no_snaps() {
333 uint64_t len
= (1 << m_ictx
->order
) * 2 + 1;
334 write(0 * len
, len
, '1');
335 write(2 * len
, len
, '1');
340 uint64_t len
= (1 << m_ictx
->order
) * 2 + 1;
341 write(0 * len
, len
, '1');
342 snap_create("snap1");
343 write(1 * len
, len
, '1');
345 write(0 * len
, 1000, 'X');
346 discard(1000 + 10, 1000);
348 snap_create("snap2");
350 write(1 * len
, 1000, 'X');
351 discard(2 * len
+ 10, 1000);
353 uint64_t size
= m_ictx
->size
;
357 write(size
- 1, len
, '2');
359 snap_create("snap3");
363 discard(size
- 1, 1);
369 uint64_t len
= (1 << m_ictx
->order
) * 2 + 1;
370 write(0 * len
, len
, 'X');
371 write(2 * len
, len
, 'X');
382 write(1000, 1000, 'X');
388 template <typename L
>
389 void test_migrate_parent(uint32_t clone_format
, L
&& test
) {
390 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
392 std::string prev_clone_format
;
393 ASSERT_EQ(0, _rados
.conf_get("rbd_default_clone_format",
395 ASSERT_EQ(0, _rados
.conf_set("rbd_default_clone_format",
396 stringify(clone_format
).c_str()));
397 BOOST_SCOPE_EXIT_TPL(&prev_clone_format
) {
398 _rados
.conf_set("rbd_default_clone_format", prev_clone_format
.c_str());
399 } BOOST_SCOPE_EXIT_END
;
402 snap_create("snap1");
403 snap_protect("snap1");
405 int order
= m_ictx
->order
;
407 ASSERT_EQ(0, librbd::get_features(m_ictx
, &features
));
409 std::string clone_name
= get_temp_image_name();
410 ASSERT_EQ(0, librbd::clone(m_ictx
->md_ctx
, m_ictx
->name
.c_str(), "snap1",
411 m_ioctx
, clone_name
.c_str(), features
, &order
,
412 m_ictx
->stripe_unit
, m_ictx
->stripe_count
));
414 librbd::ImageCtx
*child_ictx
;
415 open_image(m_ioctx
, clone_name
, &child_ictx
);
419 ASSERT_EQ(0, child_ictx
->state
->refresh());
424 librbd::io::ReadResult result
{&bl
};
425 ASSERT_EQ(10, child_ictx
->io_work_queue
->read(
426 0, 10, librbd::io::ReadResult
{result
}, 0));
428 ref_bl
.append(std::string(10, 'A'));
429 ASSERT_TRUE(ref_bl
.contents_equal(bl
));
430 close_image(child_ictx
);
433 void test_stress(const std::string
&snap_name_prefix
= "snap",
434 char start_char
= 'A') {
435 uint64_t initial_size
= m_ictx
->size
;
438 const char *c
= getenv("TEST_RBD_MIGRATION_STRESS_NSNAPS");
440 std::stringstream
ss(c
);
441 ASSERT_TRUE(ss
>> nsnaps
);
445 c
= getenv("TEST_RBD_MIGRATION_STRESS_NWRITES");
447 std::stringstream
ss(c
);
448 ASSERT_TRUE(ss
>> nwrites
);
451 for (int i
= 0; i
< nsnaps
; i
++) {
452 for (int j
= 0; j
< nwrites
; j
++) {
453 size_t len
= rand() % ((1 << m_ictx
->order
) * 2);
454 ASSERT_GT(m_ictx
->size
, len
);
455 uint64_t off
= std::min(static_cast<uint64_t>(rand() % m_ictx
->size
),
456 static_cast<uint64_t>(m_ictx
->size
- len
));
457 write(off
, len
, start_char
+ i
);
459 len
= rand() % ((1 << m_ictx
->order
) * 2);
460 ASSERT_GT(m_ictx
->size
, len
);
461 off
= std::min(static_cast<uint64_t>(rand() % m_ictx
->size
),
462 static_cast<uint64_t>(m_ictx
->size
- len
));
466 std::string snap_name
= snap_name_prefix
+ stringify(i
);
467 snap_create(snap_name
);
469 if (m_ictx
->test_features(RBD_FEATURE_LAYERING
) &&
470 !m_ictx
->test_features(RBD_FEATURE_MIGRATING
) &&
476 librbd::NoOpProgressContext no_op
;
477 uint64_t new_size
= initial_size
+ rand() % m_ictx
->size
;
479 ASSERT_EQ(new_size
, m_ictx
->size
);
485 void test_stress2(bool concurrent
) {
488 migration_prepare(m_ioctx
, m_image_name
);
489 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
491 thread
user([this]() {
492 test_stress("user", 'a');
493 for (int i
= 0; i
< 5; i
++) {
494 uint64_t off
= (i
+ 1) * m_ictx
->size
/ 10;
495 uint64_t len
= m_ictx
->size
/ 40;
496 write(off
, len
, '1' + i
);
506 librados::IoCtx io_ctx
;
507 EXPECT_EQ(0, _rados
.ioctx_create2(m_ioctx
.get_id(), io_ctx
));
508 migration_execute(io_ctx
, m_image_name
);
513 compare("before execute");
514 migration_execute(m_ioctx
, m_image_name
);
517 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
518 migration_commit(m_ioctx
, m_image_name
);
521 static std::string _other_pool_name
;
522 static librados::IoCtx _other_pool_ioctx
;
524 std::string m_image_id
;
525 librbd::ImageCtx
*m_ictx
= nullptr;
526 librados::IoCtx m_ref_ioctx
;
527 librbd::ImageCtx
*m_ref_ictx
= nullptr;
528 librbd::ImageOptions m_opts
;
531 std::string
TestMigration::_other_pool_name
;
532 librados::IoCtx
TestMigration::_other_pool_ioctx
;
534 TEST_F(TestMigration
, Empty
)
536 uint64_t features
= m_ictx
->features
^ RBD_FEATURE_LAYERING
;
537 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FEATURES
, features
));
539 migrate(m_ioctx
, m_image_name
);
541 ASSERT_EQ(features
, m_ictx
->features
);
544 TEST_F(TestMigration
, OtherName
)
546 std::string name
= get_temp_image_name();
548 migrate(m_ioctx
, name
);
550 ASSERT_EQ(name
, m_ictx
->name
);
553 TEST_F(TestMigration
, OtherPool
)
555 migrate(_other_pool_ioctx
, m_image_name
);
557 ASSERT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->md_ctx
.get_id());
560 TEST_F(TestMigration
, OtherNamespace
)
562 ASSERT_EQ(0, librbd::api::Namespace
<>::create(_other_pool_ioctx
, "ns1"));
563 _other_pool_ioctx
.set_namespace("ns1");
565 migrate(_other_pool_ioctx
, m_image_name
);
567 ASSERT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->md_ctx
.get_id());
568 ASSERT_EQ(_other_pool_ioctx
.get_namespace(), m_ictx
->md_ctx
.get_namespace());
569 _other_pool_ioctx
.set_namespace("");
572 TEST_F(TestMigration
, DataPool
)
574 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_DATA_POOL
,
575 _other_pool_ioctx
.get_pool_name().c_str()));
577 migrate(m_ioctx
, m_image_name
);
579 ASSERT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->data_ctx
.get_id());
582 TEST_F(TestMigration
, AbortAfterPrepare
)
584 migration_prepare(m_ioctx
, m_image_name
);
585 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
586 migration_abort(m_ioctx
, m_image_name
);
589 TEST_F(TestMigration
, AbortAfterFailedPrepare
)
591 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_DATA_POOL
, "INVALID_POOL"));
593 migration_prepare(m_ioctx
, m_image_name
, -ENOENT
);
595 // Migration is automatically aborted if prepare failed
598 TEST_F(TestMigration
, AbortAfterExecute
)
600 migration_prepare(m_ioctx
, m_image_name
);
601 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
602 migration_execute(m_ioctx
, m_image_name
);
603 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
604 migration_abort(m_ioctx
, m_image_name
);
607 TEST_F(TestMigration
, OtherPoolAbortAfterExecute
)
609 migration_prepare(_other_pool_ioctx
, m_image_name
);
610 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
611 migration_execute(_other_pool_ioctx
, m_image_name
);
612 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
613 migration_abort(_other_pool_ioctx
, m_image_name
);
616 TEST_F(TestMigration
, OtherNamespaceAbortAfterExecute
)
618 ASSERT_EQ(0, librbd::api::Namespace
<>::create(_other_pool_ioctx
, "ns2"));
619 _other_pool_ioctx
.set_namespace("ns2");
621 migration_prepare(_other_pool_ioctx
, m_image_name
);
622 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
623 migration_execute(_other_pool_ioctx
, m_image_name
);
624 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
625 migration_abort(_other_pool_ioctx
, m_image_name
);
627 _other_pool_ioctx
.set_namespace("");
628 ASSERT_EQ(0, librbd::api::Namespace
<>::remove(_other_pool_ioctx
, "ns2"));
631 TEST_F(TestMigration
, MirroringSamePool
)
633 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
635 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
637 ASSERT_EQ(0, librbd::api::Mirror
<>::image_enable(
638 m_ictx
, RBD_MIRROR_IMAGE_MODE_JOURNAL
, false));
639 librbd::mirror_image_info_t info
;
640 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
641 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
643 migrate(m_ioctx
, m_image_name
);
645 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
646 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
649 TEST_F(TestMigration
, MirroringAbort
)
651 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
653 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
655 ASSERT_EQ(0, librbd::api::Mirror
<>::image_enable(
656 m_ictx
, RBD_MIRROR_IMAGE_MODE_JOURNAL
, false));
657 librbd::mirror_image_info_t info
;
658 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
659 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
661 migration_prepare(m_ioctx
, m_image_name
);
662 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
663 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
664 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED
, info
.state
);
666 migration_abort(m_ioctx
, m_image_name
);
668 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
669 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
672 TEST_F(TestMigration
, MirroringOtherPoolDisabled
)
674 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
676 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
678 ASSERT_EQ(0, librbd::api::Mirror
<>::image_enable(
679 m_ictx
, RBD_MIRROR_IMAGE_MODE_JOURNAL
, false));
680 librbd::mirror_image_info_t info
;
681 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
682 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
684 migrate(_other_pool_ioctx
, m_image_name
);
686 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
687 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED
, info
.state
);
690 TEST_F(TestMigration
, MirroringOtherPoolEnabled
)
692 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
694 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(m_ioctx
, RBD_MIRROR_MODE_IMAGE
));
695 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(_other_pool_ioctx
,
696 RBD_MIRROR_MODE_IMAGE
));
698 ASSERT_EQ(0, librbd::api::Mirror
<>::image_enable(
699 m_ictx
, RBD_MIRROR_IMAGE_MODE_JOURNAL
, false));
700 librbd::mirror_image_info_t info
;
701 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
702 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
704 migrate(_other_pool_ioctx
, m_image_name
);
706 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
707 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
710 TEST_F(TestMigration
, MirroringPool
)
712 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
714 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(_other_pool_ioctx
,
715 RBD_MIRROR_MODE_POOL
));
716 librbd::mirror_image_info_t info
;
717 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
718 ASSERT_EQ(RBD_MIRROR_IMAGE_DISABLED
, info
.state
);
720 migrate(_other_pool_ioctx
, m_image_name
);
722 ASSERT_EQ(0, librbd::api::Mirror
<>::image_get_info(m_ictx
, &info
));
723 ASSERT_EQ(RBD_MIRROR_IMAGE_ENABLED
, info
.state
);
726 TEST_F(TestMigration
, Group
)
730 ASSERT_EQ(0, librbd::api::Group
<>::create(m_ioctx
, "123"));
731 ASSERT_EQ(0, librbd::api::Group
<>::image_add(m_ioctx
, "123", m_ioctx
,
732 m_image_name
.c_str()));
733 librbd::group_info_t info
;
734 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
736 std::string name
= get_temp_image_name();
738 migrate(m_ioctx
, name
);
740 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
741 ASSERT_EQ(info
.name
, "123");
743 ASSERT_EQ(0, librbd::api::Group
<>::image_remove(m_ioctx
, "123", m_ioctx
,
745 ASSERT_EQ(0, librbd::api::Group
<>::remove(m_ioctx
, "123"));
748 TEST_F(TestMigration
, GroupAbort
)
752 ASSERT_EQ(0, librbd::api::Group
<>::create(m_ioctx
, "123"));
753 ASSERT_EQ(0, librbd::api::Group
<>::image_add(m_ioctx
, "123", m_ioctx
,
754 m_image_name
.c_str()));
755 librbd::group_info_t info
;
756 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
758 std::string name
= get_temp_image_name();
760 migration_prepare(m_ioctx
, name
);
761 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
763 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
764 ASSERT_EQ(info
.name
, "123");
766 migration_abort(m_ioctx
, m_image_name
);
768 ASSERT_EQ(0, librbd::api::Group
<>::image_get_group(m_ictx
, &info
));
769 ASSERT_EQ(info
.name
, "123");
771 ASSERT_EQ(0, librbd::api::Group
<>::image_remove(m_ioctx
, "123", m_ioctx
,
772 m_image_name
.c_str()));
773 ASSERT_EQ(0, librbd::api::Group
<>::remove(m_ioctx
, "123"));
776 TEST_F(TestMigration
, NoSnaps
)
779 migrate(m_ioctx
, m_image_name
);
782 TEST_F(TestMigration
, NoSnapsOtherPool
)
787 migrate(_other_pool_ioctx
, m_image_name
);
790 TEST_F(TestMigration
, NoSnapsDataPool
)
794 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_DATA_POOL
,
795 _other_pool_ioctx
.get_pool_name().c_str()));
796 migrate(m_ioctx
, m_image_name
);
798 EXPECT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->data_ctx
.get_id());
801 TEST_F(TestMigration
, NoSnapsShrinkAfterPrepare
)
805 migration_prepare(m_ioctx
, m_image_name
);
806 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
808 resize(m_ictx
->size
>> 1);
810 migration_execute(m_ioctx
, m_image_name
);
811 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
812 migration_commit(m_ioctx
, m_image_name
);
815 TEST_F(TestMigration
, NoSnapsShrinkToZeroBeforePrepare
)
820 migrate(m_ioctx
, m_image_name
);
823 TEST_F(TestMigration
, NoSnapsShrinkToZeroAfterPrepare
)
827 migration_prepare(m_ioctx
, m_image_name
);
828 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
832 migration_execute(m_ioctx
, m_image_name
);
833 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
834 migration_commit(m_ioctx
, m_image_name
);
837 TEST_F(TestMigration
, NoSnapsExpandAfterPrepare
)
841 migration_prepare(m_ioctx
, m_image_name
);
842 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
844 resize(m_ictx
->size
<< 1);
846 migration_execute(m_ioctx
, m_image_name
);
847 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
848 migration_commit(m_ioctx
, m_image_name
);
851 TEST_F(TestMigration
, NoSnapsSnapAfterPrepare
)
855 migration_prepare(m_ioctx
, m_image_name
);
856 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
858 snap_create("after_prepare_snap");
859 resize(m_ictx
->size
>> 1);
862 migration_execute(m_ioctx
, m_image_name
);
863 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
864 migration_commit(m_ioctx
, m_image_name
);
867 TEST_F(TestMigration
, Snaps
)
870 migrate(m_ioctx
, m_image_name
);
873 TEST_F(TestMigration
, SnapsOtherPool
)
878 migrate(_other_pool_ioctx
, m_image_name
);
880 EXPECT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->md_ctx
.get_id());
883 TEST_F(TestMigration
, SnapsDataPool
)
887 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_DATA_POOL
,
888 _other_pool_ioctx
.get_pool_name().c_str()));
889 migrate(m_ioctx
, m_image_name
);
891 EXPECT_EQ(_other_pool_ioctx
.get_id(), m_ictx
->data_ctx
.get_id());
894 TEST_F(TestMigration
, SnapsShrinkAfterPrepare
)
898 migration_prepare(m_ioctx
, m_image_name
);
899 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
901 resize(m_ictx
->size
>> 1);
903 migration_execute(m_ioctx
, m_image_name
);
904 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
905 migration_commit(m_ioctx
, m_image_name
);
908 TEST_F(TestMigration
, SnapsShrinkToZeroBeforePrepare
)
913 migrate(m_ioctx
, m_image_name
);
916 TEST_F(TestMigration
, SnapsShrinkToZeroAfterPrepare
)
920 migration_prepare(m_ioctx
, m_image_name
);
921 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
925 migration_execute(m_ioctx
, m_image_name
);
926 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
927 migration_commit(m_ioctx
, m_image_name
);
930 TEST_F(TestMigration
, SnapsExpandAfterPrepare
)
934 migration_prepare(m_ioctx
, m_image_name
);
935 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
937 auto size
= m_ictx
->size
;
939 write(size
, 1000, '*');
941 migration_execute(m_ioctx
, m_image_name
);
942 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
943 migration_commit(m_ioctx
, m_image_name
);
946 TEST_F(TestMigration
, SnapsExpandAfterPrepare2
)
948 auto size
= m_ictx
->size
;
950 write(size
>> 1, 10, 'X');
951 snap_create("snap1");
954 migration_prepare(m_ioctx
, m_image_name
);
955 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
958 write(size
>> 1, 5, 'Y');
960 compare("before execute");
962 migration_execute(m_ioctx
, m_image_name
);
963 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
964 migration_commit(m_ioctx
, m_image_name
);
967 TEST_F(TestMigration
, SnapsSnapAfterPrepare
)
971 migration_prepare(m_ioctx
, m_image_name
);
972 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
974 auto ictx
= new librbd::ImageCtx(m_ictx
->name
.c_str(), "", "snap3", m_ioctx
,
976 ASSERT_EQ(0, ictx
->state
->open(0));
977 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
978 m_ref_ictx
, cls::rbd::UserSnapshotNamespace(), "snap3"));
979 compare_snaps("opened after prepare snap3", m_ref_ictx
, ictx
);
980 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
981 m_ref_ictx
, cls::rbd::UserSnapshotNamespace(), nullptr));
982 EXPECT_EQ(0, ictx
->state
->close());
984 snap_create("after_prepare_snap");
985 resize(m_ictx
->size
>> 1);
988 migration_execute(m_ioctx
, m_image_name
);
989 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
990 migration_commit(m_ioctx
, m_image_name
);
993 TEST_F(TestMigration
, SnapsSnapExpandAfterPrepare
)
997 migration_prepare(m_ioctx
, m_image_name
);
998 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1000 snap_create("after_prepare_snap");
1001 auto size
= m_ictx
->size
;
1003 write(size
, 1000, '*');
1005 migration_execute(m_ioctx
, m_image_name
);
1006 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
1007 migration_commit(m_ioctx
, m_image_name
);
1010 TEST_F(TestMigration
, Clone
)
1012 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
1015 migrate(m_ioctx
, m_image_name
);
1018 TEST_F(TestMigration
, CloneParent
) {
1019 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
1021 snap_create("snap");
1023 librbd::linked_image_spec_t expected_parent_image
;
1024 expected_parent_image
.image_id
= m_ictx
->id
;
1025 expected_parent_image
.image_name
= m_ictx
->name
;
1027 auto it
= m_ictx
->snap_ids
.find({cls::rbd::UserSnapshotNamespace
{}, "snap"});
1028 ASSERT_TRUE(it
!= m_ictx
->snap_ids
.end());
1030 librbd::snap_spec_t expected_parent_snap
;
1031 expected_parent_snap
.id
= it
->second
;
1034 migration_prepare(m_ioctx
, m_image_name
);
1036 librbd::linked_image_spec_t parent_image
;
1037 librbd::snap_spec_t parent_snap
;
1038 ASSERT_EQ(0, librbd::api::Image
<>::get_parent(m_ictx
, &parent_image
,
1040 ASSERT_EQ(expected_parent_image
.image_id
, parent_image
.image_id
);
1041 ASSERT_EQ(expected_parent_image
.image_name
, parent_image
.image_name
);
1042 ASSERT_EQ(expected_parent_snap
.id
, parent_snap
.id
);
1044 migration_abort(m_ioctx
, m_image_name
);
1048 TEST_F(TestMigration
, CloneUpdateAfterPrepare
)
1050 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
1053 snap_create("snap");
1056 migration_prepare(m_ioctx
, m_image_name
);
1060 migration_execute(m_ioctx
, m_image_name
);
1061 migration_commit(m_ioctx
, m_image_name
);
1064 TEST_F(TestMigration
, TriggerAssertSnapcSeq
)
1066 auto size
= m_ictx
->size
;
1068 write((size
>> 1) + 0, 10, 'A');
1069 snap_create("snap1");
1070 write((size
>> 1) + 1, 10, 'B');
1072 migration_prepare(m_ioctx
, m_image_name
);
1074 // copyup => deep copy (first time)
1075 write((size
>> 1) + 2, 10, 'C');
1077 // preserve data before resizing
1078 snap_create("snap2");
1080 // decrease head overlap
1083 // migrate object => deep copy (second time) => assert_snapc_seq => -ERANGE
1084 migration_execute(m_ioctx
, m_image_name
);
1085 migration_commit(m_ioctx
, m_image_name
);
1088 TEST_F(TestMigration
, SnapTrimBeforePrepare
)
1090 auto size
= m_ictx
->size
;
1092 write(size
>> 1, 10, 'A');
1093 snap_create("snap1");
1096 migration_prepare(m_ioctx
, m_image_name
);
1099 snap_create("snap3");
1100 write(size
>> 1, 10, 'B');
1101 snap_create("snap4");
1104 migration_execute(m_ioctx
, m_image_name
);
1105 migration_commit(m_ioctx
, m_image_name
);
1108 TEST_F(TestMigration
, AbortInUseImage
) {
1109 migration_prepare(m_ioctx
, m_image_name
);
1110 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1112 librbd::NoOpProgressContext no_op
;
1113 EXPECT_EQ(-EBUSY
, librbd::api::Migration
<>::abort(m_ioctx
, m_ictx
->name
,
1117 TEST_F(TestMigration
, AbortWithoutSnapshots
) {
1119 migration_prepare(m_ioctx
, m_image_name
);
1120 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1122 migration_abort(m_ioctx
, m_image_name
);
1125 TEST_F(TestMigration
, AbortWithSnapshots
) {
1127 migration_prepare(m_ioctx
, m_image_name
);
1128 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1132 ASSERT_EQ(0, TestFixture::snap_create(*m_ictx
, "dst-only-snap"));
1136 migration_abort(m_ioctx
, m_image_name
);
1139 TEST_F(TestMigration
, CloneV1Parent
)
1141 const uint32_t CLONE_FORMAT
= 1;
1142 test_migrate_parent(
1143 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1144 migrate(m_ioctx
, m_image_name
);
1148 TEST_F(TestMigration
, CloneV2Parent
)
1150 const uint32_t CLONE_FORMAT
= 2;
1151 test_migrate_parent(
1152 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1153 migrate(m_ioctx
, m_image_name
);
1157 TEST_F(TestMigration
, CloneV1ParentAbort
)
1159 const uint32_t CLONE_FORMAT
= 1;
1160 test_migrate_parent(
1161 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1162 migration_prepare(m_ioctx
, m_image_name
);
1163 migration_abort(m_ioctx
, m_image_name
);
1167 TEST_F(TestMigration
, CloneV2ParentAbort
)
1169 const uint32_t CLONE_FORMAT
= 2;
1170 test_migrate_parent(
1171 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1172 migration_prepare(m_ioctx
, m_image_name
);
1173 migration_abort(m_ioctx
, m_image_name
);
1177 TEST_F(TestMigration
, CloneV1ParentAbortFixIncompleteChildReattach
)
1179 const uint32_t CLONE_FORMAT
= 1;
1180 test_migrate_parent(
1181 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1182 auto src_image_id
= m_ictx
->id
;
1183 migration_prepare(m_ioctx
, m_image_name
);
1184 // Attach the child to both source and destination
1185 // to emulate a crash when re-attaching the child
1186 librbd::ImageCtx
*src_ictx
;
1187 open_image(m_ioctx
, "", src_image_id
, false,
1188 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1190 auto req
= librbd::image::AttachChildRequest
<>::create(
1191 child_ictx
, src_ictx
, src_ictx
->snaps
[0], nullptr, 0,
1192 CLONE_FORMAT
, &cond
);
1194 ASSERT_EQ(0, cond
.wait());
1195 close_image(src_ictx
);
1196 migration_abort(m_ioctx
, m_image_name
);
1200 TEST_F(TestMigration
, CloneV1ParentAbortFixParentReattach
)
1202 const uint32_t CLONE_FORMAT
= 1;
1203 test_migrate_parent(
1204 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1205 auto src_image_id
= m_ictx
->id
;
1206 migration_prepare(m_ioctx
, m_image_name
);
1207 // Re-attach the child back to the source to emulate a crash
1208 // after the parent reattach but before the child reattach
1209 librbd::ImageCtx
*src_ictx
;
1210 open_image(m_ioctx
, "", src_image_id
, false,
1211 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1213 auto req
= librbd::image::AttachChildRequest
<>::create(
1214 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1215 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond
);
1217 ASSERT_EQ(0, cond
.wait());
1218 close_image(src_ictx
);
1219 migration_abort(m_ioctx
, m_image_name
);
1223 TEST_F(TestMigration
, CloneV1ParentAbortRelinkNotNeeded
)
1225 const uint32_t CLONE_FORMAT
= 1;
1226 test_migrate_parent(
1227 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1228 auto src_image_id
= m_ictx
->id
;
1229 auto parent_spec
= child_ictx
->parent_md
.spec
;
1230 parent_spec
.image_id
= m_ictx
->id
;
1231 parent_spec
.snap_id
= m_ictx
->snaps
[0];
1232 auto parent_overlap
= child_ictx
->parent_md
.overlap
;
1233 migration_prepare(m_ioctx
, m_image_name
);
1234 // Relink the child back to emulate a crash
1235 // before relinking the child
1237 auto req
= librbd::image::AttachParentRequest
<>::create(
1238 *child_ictx
, parent_spec
, parent_overlap
, true, &cond
);
1240 ASSERT_EQ(0, cond
.wait());
1241 librbd::ImageCtx
*src_ictx
;
1242 open_image(m_ioctx
, "", src_image_id
, false,
1243 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1245 auto req1
= librbd::image::AttachChildRequest
<>::create(
1246 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1247 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond1
);
1249 ASSERT_EQ(0, cond1
.wait());
1250 close_image(src_ictx
);
1251 migration_abort(m_ioctx
, m_image_name
);
1255 TEST_F(TestMigration
, CloneV2ParentAbortFixIncompleteChildReattach
)
1257 const uint32_t CLONE_FORMAT
= 2;
1258 test_migrate_parent(
1259 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1260 auto src_image_id
= m_ictx
->id
;
1261 migration_prepare(m_ioctx
, m_image_name
);
1262 // Attach the child to both source and destination
1263 // to emulate a crash when re-attaching the child
1264 librbd::ImageCtx
*src_ictx
;
1265 open_image(m_ioctx
, "", src_image_id
, false,
1266 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1268 auto req
= librbd::image::AttachChildRequest
<>::create(
1269 child_ictx
, src_ictx
, src_ictx
->snaps
[0], nullptr, 0,
1270 CLONE_FORMAT
, &cond
);
1272 ASSERT_EQ(0, cond
.wait());
1273 close_image(src_ictx
);
1274 migration_abort(m_ioctx
, m_image_name
);
1278 TEST_F(TestMigration
, CloneV2ParentAbortFixParentReattach
)
1280 const uint32_t CLONE_FORMAT
= 2;
1281 test_migrate_parent(
1282 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1283 auto src_image_id
= m_ictx
->id
;
1284 migration_prepare(m_ioctx
, m_image_name
);
1285 // Re-attach the child back to the source to emulate a crash
1286 // after the parent reattach but before the child reattach
1287 librbd::ImageCtx
*src_ictx
;
1288 open_image(m_ioctx
, "", src_image_id
, false,
1289 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1291 auto req
= librbd::image::AttachChildRequest
<>::create(
1292 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1293 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond
);
1295 ASSERT_EQ(0, cond
.wait());
1296 close_image(src_ictx
);
1297 migration_abort(m_ioctx
, m_image_name
);
1301 TEST_F(TestMigration
, CloneV2ParentAbortRelinkNotNeeded
)
1303 const uint32_t CLONE_FORMAT
= 2;
1304 test_migrate_parent(
1305 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1306 auto src_image_id
= m_ictx
->id
;
1307 auto parent_spec
= child_ictx
->parent_md
.spec
;
1308 parent_spec
.image_id
= m_ictx
->id
;
1309 parent_spec
.snap_id
= m_ictx
->snaps
[0];
1310 auto parent_overlap
= child_ictx
->parent_md
.overlap
;
1311 migration_prepare(m_ioctx
, m_image_name
);
1312 // Relink the child back to emulate a crash
1313 // before relinking the child
1315 auto req
= librbd::image::AttachParentRequest
<>::create(
1316 *child_ictx
, parent_spec
, parent_overlap
, true, &cond
);
1318 ASSERT_EQ(0, cond
.wait());
1319 librbd::ImageCtx
*src_ictx
;
1320 open_image(m_ioctx
, "", src_image_id
, false,
1321 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1323 auto req1
= librbd::image::AttachChildRequest
<>::create(
1324 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1325 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond1
);
1327 ASSERT_EQ(0, cond1
.wait());
1328 close_image(src_ictx
);
1329 migration_abort(m_ioctx
, m_image_name
);
1333 TEST_F(TestMigration
, StressNoMigrate
)
1340 TEST_F(TestMigration
, Stress
)
1344 migrate(m_ioctx
, m_image_name
);
1347 TEST_F(TestMigration
, Stress2
)
1349 test_stress2(false);
1352 TEST_F(TestMigration
, StressLive
)