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/Io.h"
12 #include "librbd/api/Migration.h"
13 #include "librbd/api/Mirror.h"
14 #include "librbd/api/Namespace.h"
15 #include "librbd/api/Snapshot.h"
16 #include "librbd/image/AttachChildRequest.h"
17 #include "librbd/image/AttachParentRequest.h"
18 #include "librbd/internal.h"
19 #include "librbd/io/ReadResult.h"
20 #include "common/Cond.h"
21 #include <boost/scope_exit.hpp>
23 void register_test_migration() {
28 struct TestMigration
: public TestFixture
{
29 static void SetUpTestCase() {
30 TestFixture::SetUpTestCase();
32 _other_pool_name
= get_temp_pool_name("test-librbd-");
33 ASSERT_EQ(0, _rados
.pool_create(_other_pool_name
.c_str()));
36 static void TearDownTestCase() {
37 ASSERT_EQ(0, _rados
.pool_delete(_other_pool_name
.c_str()));
39 TestFixture::TearDownTestCase();
42 void SetUp() override
{
45 ASSERT_EQ(0, _rados
.ioctx_create(_other_pool_name
.c_str(),
48 open_image(m_ioctx
, m_image_name
, &m_ictx
);
49 m_image_id
= m_ictx
->id
;
51 std::string ref_image_name
= get_temp_image_name();
52 ASSERT_EQ(0, create_image_pp(m_rbd
, m_ioctx
, ref_image_name
, m_ictx
->size
));
53 EXPECT_EQ(0, _rados
.ioctx_create2(m_ioctx
.get_id(), m_ref_ioctx
));
54 open_image(m_ref_ioctx
, ref_image_name
, &m_ref_ictx
);
56 resize(20 * (1 << 22));
59 void TearDown() override
{
60 if (m_ref_ictx
!= nullptr) {
61 close_image(m_ref_ictx
);
63 if (m_ictx
!= nullptr) {
67 _other_pool_ioctx
.close();
69 TestFixture::TearDown();
72 void compare(const std::string
&description
= "") {
73 std::vector
<librbd::snap_info_t
> src_snaps
, dst_snaps
;
75 EXPECT_EQ(m_ref_ictx
->size
, m_ictx
->size
);
76 EXPECT_EQ(0, librbd::api::Snapshot
<>::list(m_ref_ictx
, src_snaps
));
77 EXPECT_EQ(0, librbd::api::Snapshot
<>::list(m_ictx
, dst_snaps
));
78 EXPECT_EQ(src_snaps
.size(), dst_snaps
.size());
79 for (size_t i
= 0; i
<= src_snaps
.size(); i
++) {
80 const char *src_snap_name
= nullptr;
81 const char *dst_snap_name
= nullptr;
82 if (i
< src_snaps
.size()) {
83 EXPECT_EQ(src_snaps
[i
].name
, dst_snaps
[i
].name
);
84 src_snap_name
= src_snaps
[i
].name
.c_str();
85 dst_snap_name
= dst_snaps
[i
].name
.c_str();
87 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
88 m_ref_ictx
, cls::rbd::UserSnapshotNamespace(),
90 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
91 m_ictx
, cls::rbd::UserSnapshotNamespace(),
94 description
+ " snap: " + (src_snap_name
? src_snap_name
: "null"),
99 void compare_snaps(const std::string
&description
, librbd::ImageCtx
*src_ictx
,
100 librbd::ImageCtx
*dst_ictx
) {
101 uint64_t src_size
, dst_size
;
103 std::shared_lock src_locker
{src_ictx
->image_lock
};
104 std::shared_lock dst_locker
{dst_ictx
->image_lock
};
105 src_size
= src_ictx
->get_image_size(src_ictx
->snap_id
);
106 dst_size
= dst_ictx
->get_image_size(dst_ictx
->snap_id
);
108 if (src_size
!= dst_size
) {
109 std::cout
<< description
<< ": size differs" << std::endl
;
110 EXPECT_EQ(src_size
, dst_size
);
113 if (dst_ictx
->test_features(RBD_FEATURE_LAYERING
)) {
115 std::shared_lock dst_locker
{dst_ictx
->image_lock
};
116 EXPECT_EQ(0, dst_ictx
->test_flags(dst_ictx
->snap_id
,
117 RBD_FLAG_OBJECT_MAP_INVALID
,
118 dst_ictx
->image_lock
, &flags_set
));
119 EXPECT_FALSE(flags_set
);
122 ssize_t read_size
= 1 << src_ictx
->order
;
124 while (offset
< src_size
) {
125 read_size
= std::min(read_size
, static_cast<ssize_t
>(src_size
- offset
));
127 bufferptr
src_ptr(read_size
);
129 src_bl
.push_back(src_ptr
);
130 librbd::io::ReadResult src_result
{&src_bl
};
131 EXPECT_EQ(read_size
, api::Io
<>::read(
132 *src_ictx
, offset
, read_size
,
133 librbd::io::ReadResult
{src_result
}, 0));
135 bufferptr
dst_ptr(read_size
);
137 dst_bl
.push_back(dst_ptr
);
138 librbd::io::ReadResult dst_result
{&dst_bl
};
139 EXPECT_EQ(read_size
, api::Io
<>::read(
140 *dst_ictx
, offset
, read_size
,
141 librbd::io::ReadResult
{dst_result
}, 0));
143 if (!src_bl
.contents_equal(dst_bl
)) {
144 std::cout
<< description
145 << ", block " << offset
<< "~" << read_size
<< " differs"
147 std::cout
<< "src block: " << src_ictx
->id
<< ": " << std::endl
; src_bl
.hexdump(std::cout
);
148 std::cout
<< "dst block: " << dst_ictx
->id
<< ": " << std::endl
; dst_bl
.hexdump(std::cout
);
150 EXPECT_TRUE(src_bl
.contents_equal(dst_bl
));
155 void open_image(librados::IoCtx
& io_ctx
, const std::string
&name
,
156 const std::string
&id
, bool read_only
, int flags
,
157 librbd::ImageCtx
**ictx
) {
158 *ictx
= new librbd::ImageCtx(name
, id
, nullptr, io_ctx
, read_only
);
159 m_ictxs
.insert(*ictx
);
161 ASSERT_EQ(0, (*ictx
)->state
->open(flags
));
162 (*ictx
)->discard_granularity_bytes
= 0;
165 void open_image(librados::IoCtx
& io_ctx
, const std::string
&name
,
166 librbd::ImageCtx
**ictx
) {
167 open_image(io_ctx
, name
, "", false, 0, ictx
);
170 void migration_prepare(librados::IoCtx
& dst_io_ctx
,
171 const std::string
&dst_name
, int r
= 0) {
172 std::cout
<< __func__
<< std::endl
;
177 EXPECT_EQ(r
, librbd::api::Migration
<>::prepare(m_ioctx
, m_image_name
,
178 dst_io_ctx
, dst_name
,
181 open_image(dst_io_ctx
, dst_name
, &m_ictx
);
183 open_image(m_ioctx
, m_image_name
, &m_ictx
);
185 compare("after prepare");
188 void migration_execute(librados::IoCtx
& io_ctx
, const std::string
&name
,
190 std::cout
<< __func__
<< std::endl
;
192 librbd::NoOpProgressContext no_op
;
193 EXPECT_EQ(r
, librbd::api::Migration
<>::execute(io_ctx
, name
, no_op
));
196 void migration_abort(librados::IoCtx
& io_ctx
, const std::string
&name
,
198 std::cout
<< __func__
<< std::endl
;
200 std::string dst_name
= m_ictx
->name
;
204 librbd::NoOpProgressContext no_op
;
205 EXPECT_EQ(r
, librbd::api::Migration
<>::abort(io_ctx
, name
, no_op
));
208 open_image(m_ioctx
, m_image_name
, &m_ictx
);
210 open_image(m_ioctx
, dst_name
, &m_ictx
);
213 compare("after abort");
216 void migration_commit(librados::IoCtx
& io_ctx
, const std::string
&name
) {
217 std::cout
<< __func__
<< std::endl
;
219 librbd::NoOpProgressContext no_op
;
220 EXPECT_EQ(0, librbd::api::Migration
<>::commit(io_ctx
, name
, no_op
));
222 compare("after commit");
225 void migration_status(librbd::image_migration_state_t state
) {
226 librbd::image_migration_status_t status
;
227 EXPECT_EQ(0, librbd::api::Migration
<>::status(m_ioctx
, m_image_name
,
229 EXPECT_EQ(status
.source_pool_id
, m_ioctx
.get_id());
230 EXPECT_EQ(status
.source_pool_namespace
, m_ioctx
.get_namespace());
231 EXPECT_EQ(status
.source_image_name
, m_image_name
);
232 EXPECT_EQ(status
.source_image_id
, m_image_id
);
233 EXPECT_EQ(status
.dest_pool_id
, m_ictx
->md_ctx
.get_id());
234 EXPECT_EQ(status
.dest_pool_namespace
, m_ictx
->md_ctx
.get_namespace());
235 EXPECT_EQ(status
.dest_image_name
, m_ictx
->name
);
236 EXPECT_EQ(status
.dest_image_id
, m_ictx
->id
);
237 EXPECT_EQ(status
.state
, state
);
240 void migrate(librados::IoCtx
& dst_io_ctx
, const std::string
&dst_name
) {
241 migration_prepare(dst_io_ctx
, dst_name
);
242 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
243 migration_execute(dst_io_ctx
, dst_name
);
244 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
245 migration_commit(dst_io_ctx
, dst_name
);
248 void write(uint64_t off
, uint64_t len
, char c
) {
249 std::cout
<< "write: " << c
<< " " << off
<< "~" << len
<< std::endl
;
252 ref_bl
.append(std::string(len
, c
));
253 ASSERT_EQ(static_cast<ssize_t
>(len
),
254 api::Io
<>::write(*m_ref_ictx
, off
, len
, std::move(ref_bl
), 0));
256 bl
.append(std::string(len
, c
));
257 ASSERT_EQ(static_cast<ssize_t
>(len
),
258 api::Io
<>::write(*m_ictx
, off
, len
, std::move(bl
), 0));
261 void discard(uint64_t off
, uint64_t len
) {
262 std::cout
<< "discard: " << off
<< "~" << len
<< std::endl
;
264 ASSERT_EQ(static_cast<ssize_t
>(len
),
265 api::Io
<>::discard(*m_ref_ictx
, off
, len
, false));
266 ASSERT_EQ(static_cast<ssize_t
>(len
),
267 api::Io
<>::discard(*m_ictx
, off
, len
, false));
271 ASSERT_EQ(0, TestFixture::flush_writeback_cache(m_ref_ictx
));
272 ASSERT_EQ(0, TestFixture::flush_writeback_cache(m_ictx
));
275 void snap_create(const std::string
&snap_name
) {
276 std::cout
<< "snap_create: " << snap_name
<< std::endl
;
280 ASSERT_EQ(0, TestFixture::snap_create(*m_ref_ictx
, snap_name
));
281 ASSERT_EQ(0, TestFixture::snap_create(*m_ictx
, snap_name
));
284 void snap_protect(const std::string
&snap_name
) {
285 std::cout
<< "snap_protect: " << snap_name
<< std::endl
;
287 ASSERT_EQ(0, TestFixture::snap_protect(*m_ref_ictx
, snap_name
));
288 ASSERT_EQ(0, TestFixture::snap_protect(*m_ictx
, snap_name
));
291 void clone(const std::string
&snap_name
) {
292 snap_protect(snap_name
);
294 int order
= m_ref_ictx
->order
;
296 ASSERT_EQ(0, librbd::get_features(m_ref_ictx
, &features
));
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
));
410 std::string clone_name
= get_temp_image_name();
411 ASSERT_EQ(0, librbd::clone(m_ictx
->md_ctx
, m_ictx
->name
.c_str(), "snap1",
412 m_ioctx
, clone_name
.c_str(), features
, &order
,
413 m_ictx
->stripe_unit
, m_ictx
->stripe_count
));
415 librbd::ImageCtx
*child_ictx
;
416 open_image(m_ioctx
, clone_name
, &child_ictx
);
420 ASSERT_EQ(0, child_ictx
->state
->refresh());
425 librbd::io::ReadResult result
{&bl
};
426 ASSERT_EQ(10, api::Io
<>::read(
427 *child_ictx
, 0, 10, librbd::io::ReadResult
{result
}, 0));
429 ref_bl
.append(std::string(10, 'A'));
430 ASSERT_TRUE(ref_bl
.contents_equal(bl
));
431 close_image(child_ictx
);
434 void test_stress(const std::string
&snap_name_prefix
= "snap",
435 char start_char
= 'A') {
436 uint64_t initial_size
= m_ictx
->size
;
439 const char *c
= getenv("TEST_RBD_MIGRATION_STRESS_NSNAPS");
441 std::stringstream
ss(c
);
442 ASSERT_TRUE(ss
>> nsnaps
);
446 c
= getenv("TEST_RBD_MIGRATION_STRESS_NWRITES");
448 std::stringstream
ss(c
);
449 ASSERT_TRUE(ss
>> nwrites
);
452 for (int i
= 0; i
< nsnaps
; i
++) {
453 for (int j
= 0; j
< nwrites
; j
++) {
454 size_t len
= rand() % ((1 << m_ictx
->order
) * 2);
455 ASSERT_GT(m_ictx
->size
, len
);
456 uint64_t off
= std::min(static_cast<uint64_t>(rand() % m_ictx
->size
),
457 static_cast<uint64_t>(m_ictx
->size
- len
));
458 write(off
, len
, start_char
+ i
);
460 len
= rand() % ((1 << m_ictx
->order
) * 2);
461 ASSERT_GT(m_ictx
->size
, len
);
462 off
= std::min(static_cast<uint64_t>(rand() % m_ictx
->size
),
463 static_cast<uint64_t>(m_ictx
->size
- len
));
467 std::string snap_name
= snap_name_prefix
+ stringify(i
);
468 snap_create(snap_name
);
470 if (m_ictx
->test_features(RBD_FEATURE_LAYERING
) &&
471 !m_ictx
->test_features(RBD_FEATURE_MIGRATING
) &&
477 librbd::NoOpProgressContext no_op
;
478 uint64_t new_size
= initial_size
+ rand() % m_ictx
->size
;
480 ASSERT_EQ(new_size
, m_ictx
->size
);
486 void test_stress2(bool concurrent
) {
489 migration_prepare(m_ioctx
, m_image_name
);
490 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
492 std::thread
user([this]() {
493 test_stress("user", 'a');
494 for (int i
= 0; i
< 5; i
++) {
495 uint64_t off
= (i
+ 1) * m_ictx
->size
/ 10;
496 uint64_t len
= m_ictx
->size
/ 40;
497 write(off
, len
, '1' + i
);
507 librados::IoCtx io_ctx
;
508 EXPECT_EQ(0, _rados
.ioctx_create2(m_ioctx
.get_id(), io_ctx
));
509 migration_execute(io_ctx
, m_image_name
);
514 compare("before execute");
515 migration_execute(m_ioctx
, m_image_name
);
518 migration_status(RBD_IMAGE_MIGRATION_STATE_EXECUTED
);
519 migration_commit(m_ioctx
, m_image_name
);
522 static std::string _other_pool_name
;
523 static librados::IoCtx _other_pool_ioctx
;
525 std::string m_image_id
;
526 librbd::ImageCtx
*m_ictx
= nullptr;
527 librados::IoCtx m_ref_ioctx
;
528 librbd::ImageCtx
*m_ref_ictx
= nullptr;
529 librbd::ImageOptions m_opts
;
532 std::string
TestMigration::_other_pool_name
;
533 librados::IoCtx
TestMigration::_other_pool_ioctx
;
535 TEST_F(TestMigration
, Empty
)
537 uint64_t features
= m_ictx
->features
^ RBD_FEATURE_LAYERING
;
538 features
&= ~RBD_FEATURE_DIRTY_CACHE
;
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
, AbortInUseImage
) {
1111 migration_prepare(m_ioctx
, m_image_name
);
1112 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1114 librbd::NoOpProgressContext no_op
;
1115 EXPECT_EQ(-EBUSY
, librbd::api::Migration
<>::abort(m_ioctx
, m_ictx
->name
,
1119 TEST_F(TestMigration
, AbortWithoutSnapshots
) {
1121 migration_prepare(m_ioctx
, m_image_name
);
1122 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1124 migration_abort(m_ioctx
, m_image_name
);
1127 TEST_F(TestMigration
, AbortWithSnapshots
) {
1129 migration_prepare(m_ioctx
, m_image_name
);
1130 migration_status(RBD_IMAGE_MIGRATION_STATE_PREPARED
);
1134 ASSERT_EQ(0, TestFixture::snap_create(*m_ictx
, "dst-only-snap"));
1138 migration_abort(m_ioctx
, m_image_name
);
1141 TEST_F(TestMigration
, CloneV1Parent
)
1143 const uint32_t CLONE_FORMAT
= 1;
1144 test_migrate_parent(
1145 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1146 migrate(m_ioctx
, m_image_name
);
1150 TEST_F(TestMigration
, CloneV2Parent
)
1152 const uint32_t CLONE_FORMAT
= 2;
1153 test_migrate_parent(
1154 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1155 migrate(m_ioctx
, m_image_name
);
1159 TEST_F(TestMigration
, CloneV1ParentAbort
)
1161 const uint32_t CLONE_FORMAT
= 1;
1162 test_migrate_parent(
1163 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1164 migration_prepare(m_ioctx
, m_image_name
);
1165 migration_abort(m_ioctx
, m_image_name
);
1169 TEST_F(TestMigration
, CloneV2ParentAbort
)
1171 const uint32_t CLONE_FORMAT
= 2;
1172 test_migrate_parent(
1173 CLONE_FORMAT
, [this](librbd::ImageCtx
*) {
1174 migration_prepare(m_ioctx
, m_image_name
);
1175 migration_abort(m_ioctx
, m_image_name
);
1179 TEST_F(TestMigration
, CloneV1ParentAbortFixIncompleteChildReattach
)
1181 const uint32_t CLONE_FORMAT
= 1;
1182 test_migrate_parent(
1183 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1184 auto src_image_id
= m_ictx
->id
;
1185 migration_prepare(m_ioctx
, m_image_name
);
1186 // Attach the child to both source and destination
1187 // to emulate a crash when re-attaching the child
1188 librbd::ImageCtx
*src_ictx
;
1189 open_image(m_ioctx
, "", src_image_id
, false,
1190 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1192 auto req
= librbd::image::AttachChildRequest
<>::create(
1193 child_ictx
, src_ictx
, src_ictx
->snaps
[0], nullptr, 0,
1194 CLONE_FORMAT
, &cond
);
1196 ASSERT_EQ(0, cond
.wait());
1197 close_image(src_ictx
);
1198 migration_abort(m_ioctx
, m_image_name
);
1202 TEST_F(TestMigration
, CloneV1ParentAbortFixParentReattach
)
1204 const uint32_t CLONE_FORMAT
= 1;
1205 test_migrate_parent(
1206 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1207 auto src_image_id
= m_ictx
->id
;
1208 migration_prepare(m_ioctx
, m_image_name
);
1209 // Re-attach the child back to the source to emulate a crash
1210 // after the parent reattach but before the child reattach
1211 librbd::ImageCtx
*src_ictx
;
1212 open_image(m_ioctx
, "", src_image_id
, false,
1213 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1215 auto req
= librbd::image::AttachChildRequest
<>::create(
1216 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1217 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond
);
1219 ASSERT_EQ(0, cond
.wait());
1220 close_image(src_ictx
);
1221 migration_abort(m_ioctx
, m_image_name
);
1225 TEST_F(TestMigration
, CloneV1ParentAbortRelinkNotNeeded
)
1227 const uint32_t CLONE_FORMAT
= 1;
1228 test_migrate_parent(
1229 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1230 auto src_image_id
= m_ictx
->id
;
1231 auto parent_spec
= child_ictx
->parent_md
.spec
;
1232 parent_spec
.image_id
= m_ictx
->id
;
1233 parent_spec
.snap_id
= m_ictx
->snaps
[0];
1234 auto parent_overlap
= child_ictx
->parent_md
.overlap
;
1235 migration_prepare(m_ioctx
, m_image_name
);
1236 // Relink the child back to emulate a crash
1237 // before relinking the child
1239 auto req
= librbd::image::AttachParentRequest
<>::create(
1240 *child_ictx
, parent_spec
, parent_overlap
, true, &cond
);
1242 ASSERT_EQ(0, cond
.wait());
1243 librbd::ImageCtx
*src_ictx
;
1244 open_image(m_ioctx
, "", src_image_id
, false,
1245 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1247 auto req1
= librbd::image::AttachChildRequest
<>::create(
1248 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1249 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond1
);
1251 ASSERT_EQ(0, cond1
.wait());
1252 close_image(src_ictx
);
1253 migration_abort(m_ioctx
, m_image_name
);
1257 TEST_F(TestMigration
, CloneV2ParentAbortFixIncompleteChildReattach
)
1259 const uint32_t CLONE_FORMAT
= 2;
1260 test_migrate_parent(
1261 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1262 auto src_image_id
= m_ictx
->id
;
1263 migration_prepare(m_ioctx
, m_image_name
);
1264 // Attach the child to both source and destination
1265 // to emulate a crash when re-attaching the child
1266 librbd::ImageCtx
*src_ictx
;
1267 open_image(m_ioctx
, "", src_image_id
, false,
1268 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1270 auto req
= librbd::image::AttachChildRequest
<>::create(
1271 child_ictx
, src_ictx
, src_ictx
->snaps
[0], nullptr, 0,
1272 CLONE_FORMAT
, &cond
);
1274 ASSERT_EQ(0, cond
.wait());
1275 close_image(src_ictx
);
1276 migration_abort(m_ioctx
, m_image_name
);
1280 TEST_F(TestMigration
, CloneV2ParentAbortFixParentReattach
)
1282 const uint32_t CLONE_FORMAT
= 2;
1283 test_migrate_parent(
1284 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1285 auto src_image_id
= m_ictx
->id
;
1286 migration_prepare(m_ioctx
, m_image_name
);
1287 // Re-attach the child back to the source to emulate a crash
1288 // after the parent reattach but before the child reattach
1289 librbd::ImageCtx
*src_ictx
;
1290 open_image(m_ioctx
, "", src_image_id
, false,
1291 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1293 auto req
= librbd::image::AttachChildRequest
<>::create(
1294 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1295 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond
);
1297 ASSERT_EQ(0, cond
.wait());
1298 close_image(src_ictx
);
1299 migration_abort(m_ioctx
, m_image_name
);
1303 TEST_F(TestMigration
, CloneV2ParentAbortRelinkNotNeeded
)
1305 const uint32_t CLONE_FORMAT
= 2;
1306 test_migrate_parent(
1307 CLONE_FORMAT
, [this](librbd::ImageCtx
*child_ictx
) {
1308 auto src_image_id
= m_ictx
->id
;
1309 auto parent_spec
= child_ictx
->parent_md
.spec
;
1310 parent_spec
.image_id
= m_ictx
->id
;
1311 parent_spec
.snap_id
= m_ictx
->snaps
[0];
1312 auto parent_overlap
= child_ictx
->parent_md
.overlap
;
1313 migration_prepare(m_ioctx
, m_image_name
);
1314 // Relink the child back to emulate a crash
1315 // before relinking the child
1317 auto req
= librbd::image::AttachParentRequest
<>::create(
1318 *child_ictx
, parent_spec
, parent_overlap
, true, &cond
);
1320 ASSERT_EQ(0, cond
.wait());
1321 librbd::ImageCtx
*src_ictx
;
1322 open_image(m_ioctx
, "", src_image_id
, false,
1323 librbd::OPEN_FLAG_IGNORE_MIGRATING
, &src_ictx
);
1325 auto req1
= librbd::image::AttachChildRequest
<>::create(
1326 child_ictx
, src_ictx
, src_ictx
->snaps
[0], m_ictx
,
1327 m_ictx
->snaps
[0], CLONE_FORMAT
, &cond1
);
1329 ASSERT_EQ(0, cond1
.wait());
1330 close_image(src_ictx
);
1331 migration_abort(m_ioctx
, m_image_name
);
1335 TEST_F(TestMigration
, StressNoMigrate
)
1342 TEST_F(TestMigration
, Stress
)
1346 migrate(m_ioctx
, m_image_name
);
1349 TEST_F(TestMigration
, Stress2
)
1351 test_stress2(false);
1354 TEST_F(TestMigration
, StressLive
)
1359 } // namespace librbd