1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/librbd/test_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "librbd/Operations.h"
7 #include "librbd/api/Image.h"
8 #include "librbd/api/Snapshot.h"
9 #include "librbd/internal.h"
10 #include "librbd/io/ImageRequestWQ.h"
11 #include "librbd/io/ReadResult.h"
13 void register_test_deep_copy() {
16 struct TestDeepCopy
: public TestFixture
{
17 void SetUp() override
{
20 std::string image_name
= get_temp_image_name();
22 uint64_t size
= (1 << order
) * 20;
23 uint64_t features
= 0;
24 bool old_format
= !get_features(&features
);
25 EXPECT_EQ(0, create_image_full_pp(m_rbd
, m_ioctx
, image_name
, size
,
26 features
, old_format
, &order
));
27 ASSERT_EQ(0, open_image(image_name
, &m_src_ictx
));
30 // The destination should always be in the new format.
32 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FORMAT
, format
));
36 void TearDown() override
{
37 if (m_src_ictx
!= nullptr) {
39 if (m_dst_ictx
!= nullptr) {
41 close_image(m_dst_ictx
);
43 close_image(m_src_ictx
);
46 TestFixture::TearDown();
50 std::string dst_name
= get_temp_image_name();
51 librbd::NoOpProgressContext no_op
;
52 EXPECT_EQ(0, m_src_ictx
->io_work_queue
->flush());
53 EXPECT_EQ(0, librbd::api::Image
<>::deep_copy(m_src_ictx
, m_src_ictx
->md_ctx
,
54 dst_name
.c_str(), m_opts
,
56 EXPECT_EQ(0, open_image(dst_name
, &m_dst_ictx
));
60 vector
<librbd::snap_info_t
> src_snaps
, dst_snaps
;
62 EXPECT_EQ(m_src_ictx
->size
, m_dst_ictx
->size
);
63 EXPECT_EQ(0, librbd::api::Snapshot
<>::list(m_src_ictx
, src_snaps
));
64 EXPECT_EQ(0, librbd::api::Snapshot
<>::list(m_dst_ictx
, dst_snaps
));
65 EXPECT_EQ(src_snaps
.size(), dst_snaps
.size());
66 for (size_t i
= 0; i
<= src_snaps
.size(); i
++) {
67 const char *src_snap_name
= nullptr;
68 const char *dst_snap_name
= nullptr;
69 if (i
< src_snaps
.size()) {
70 EXPECT_EQ(src_snaps
[i
].name
, dst_snaps
[i
].name
);
71 src_snap_name
= src_snaps
[i
].name
.c_str();
72 dst_snap_name
= dst_snaps
[i
].name
.c_str();
74 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
75 m_src_ictx
, cls::rbd::UserSnapshotNamespace(),
77 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
78 m_dst_ictx
, cls::rbd::UserSnapshotNamespace(),
80 uint64_t src_size
, dst_size
;
82 std::shared_lock src_locker
{m_src_ictx
->image_lock
};
83 std::shared_lock dst_locker
{m_dst_ictx
->image_lock
};
84 src_size
= m_src_ictx
->get_image_size(m_src_ictx
->snap_id
);
85 dst_size
= m_dst_ictx
->get_image_size(m_dst_ictx
->snap_id
);
87 EXPECT_EQ(src_size
, dst_size
);
89 if (m_dst_ictx
->test_features(RBD_FEATURE_LAYERING
)) {
91 std::shared_lock dst_locker
{m_dst_ictx
->image_lock
};
92 EXPECT_EQ(0, m_dst_ictx
->test_flags(m_dst_ictx
->snap_id
,
93 RBD_FLAG_OBJECT_MAP_INVALID
,
94 m_dst_ictx
->image_lock
, &flags_set
));
95 EXPECT_FALSE(flags_set
);
98 ssize_t read_size
= 1 << m_src_ictx
->order
;
100 while (offset
< src_size
) {
101 read_size
= std::min(read_size
, static_cast<ssize_t
>(src_size
- offset
));
103 bufferptr
src_ptr(read_size
);
105 src_bl
.push_back(src_ptr
);
106 librbd::io::ReadResult src_result
{&src_bl
};
107 EXPECT_EQ(read_size
, m_src_ictx
->io_work_queue
->read(
108 offset
, read_size
, librbd::io::ReadResult
{src_result
}, 0));
110 bufferptr
dst_ptr(read_size
);
112 dst_bl
.push_back(dst_ptr
);
113 librbd::io::ReadResult dst_result
{&dst_bl
};
114 EXPECT_EQ(read_size
, m_dst_ictx
->io_work_queue
->read(
115 offset
, read_size
, librbd::io::ReadResult
{dst_result
}, 0));
117 if (!src_bl
.contents_equal(dst_bl
)) {
118 std::cout
<< "snap: " << (src_snap_name
? src_snap_name
: "null")
119 << ", block " << offset
<< "~" << read_size
<< " differs"
121 // std::cout << "src block: " << std::endl; src_bl.hexdump(std::cout);
122 // std::cout << "dst block: " << std::endl; dst_bl.hexdump(std::cout);
124 EXPECT_TRUE(src_bl
.contents_equal(dst_bl
));
130 void test_no_snaps() {
132 bl
.append(std::string(((1 << m_src_ictx
->order
) * 2) + 1, '1'));
133 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
134 m_src_ictx
->io_work_queue
->write(0 * bl
.length(), bl
.length(),
136 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
137 m_src_ictx
->io_work_queue
->write(2 * bl
.length(), bl
.length(),
143 bl
.append(std::string(((1 << m_src_ictx
->order
) * 2) + 1, '1'));
144 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
145 m_src_ictx
->io_work_queue
->write(0 * bl
.length(), bl
.length(),
147 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
149 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap1"));
151 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
152 m_src_ictx
->io_work_queue
->write(1 * bl
.length(), bl
.length(),
155 bl1
.append(std::string(1000, 'X'));
156 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
157 m_src_ictx
->io_work_queue
->write(0 * bl
.length(), bl1
.length(),
158 bufferlist
{bl1
}, 0));
159 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
160 m_src_ictx
->io_work_queue
->discard(bl1
.length() + 10,
161 bl1
.length(), false));
163 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
165 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap2"));
166 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
167 m_src_ictx
->io_work_queue
->write(1 * bl
.length(), bl1
.length(),
168 bufferlist
{bl1
}, 0));
169 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
170 m_src_ictx
->io_work_queue
->discard(2 * bl1
.length() + 10,
171 bl1
.length(), false));
174 void test_snap_discard() {
176 bl
.append(std::string(100, '1'));
177 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
178 m_src_ictx
->io_work_queue
->write(0, bl
.length(), bufferlist
{bl
},
180 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
182 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
184 size_t len
= (1 << m_src_ictx
->order
) * 2;
185 ASSERT_EQ(static_cast<ssize_t
>(len
),
186 m_src_ictx
->io_work_queue
->discard(0, len
, false));
189 void test_clone_discard() {
191 bl
.append(std::string(100, '1'));
192 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
193 m_src_ictx
->io_work_queue
->write(0, bl
.length(), bufferlist
{bl
},
195 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
197 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
198 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
200 std::string clone_name
= get_temp_image_name();
201 int order
= m_src_ictx
->order
;
203 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
204 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
205 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
207 close_image(m_src_ictx
);
208 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
210 size_t len
= (1 << m_src_ictx
->order
) * 2;
211 ASSERT_EQ(static_cast<ssize_t
>(len
),
212 m_src_ictx
->io_work_queue
->discard(0, len
, false));
215 void test_clone_shrink() {
217 bl
.append(std::string(100, '1'));
218 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
219 m_src_ictx
->io_work_queue
->write(0, bl
.length(), bufferlist
{bl
},
221 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
223 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
224 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
226 std::string clone_name
= get_temp_image_name();
227 int order
= m_src_ictx
->order
;
229 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
230 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
231 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
233 close_image(m_src_ictx
);
234 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
236 librbd::NoOpProgressContext no_op
;
237 auto new_size
= m_src_ictx
->size
>> 1;
238 ASSERT_EQ(0, m_src_ictx
->operations
->resize(new_size
, true, no_op
));
241 void test_clone_expand() {
243 bl
.append(std::string(100, '1'));
244 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
245 m_src_ictx
->io_work_queue
->write(0, bl
.length(), bufferlist
{bl
},
247 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
249 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
250 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
252 std::string clone_name
= get_temp_image_name();
253 int order
= m_src_ictx
->order
;
255 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
256 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
257 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
259 close_image(m_src_ictx
);
260 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
262 librbd::NoOpProgressContext no_op
;
263 auto new_size
= m_src_ictx
->size
<< 1;
264 ASSERT_EQ(0, m_src_ictx
->operations
->resize(new_size
, true, no_op
));
267 void test_clone_hide_parent() {
268 uint64_t object_size
= 1 << m_src_ictx
->order
;
270 bl
.append(std::string(100, '1'));
271 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
272 m_src_ictx
->io_work_queue
->write(object_size
, bl
.length(),
274 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
276 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
277 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
279 std::string clone_name
= get_temp_image_name();
280 int order
= m_src_ictx
->order
;
282 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
283 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
284 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
286 close_image(m_src_ictx
);
287 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
289 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap1"));
291 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
292 m_src_ictx
->io_work_queue
->discard(object_size
, bl
.length(),
294 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
296 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap2"));
298 librbd::NoOpProgressContext no_op
;
299 ASSERT_EQ(0, m_src_ictx
->operations
->resize(object_size
, true, no_op
));
301 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap3"));
303 ASSERT_EQ(0, m_src_ictx
->operations
->resize(2 * object_size
, true, no_op
));
308 bl
.append(std::string(((1 << m_src_ictx
->order
) * 2) + 1, '1'));
309 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
310 m_src_ictx
->io_work_queue
->write(0 * bl
.length(), bl
.length(),
312 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
313 m_src_ictx
->io_work_queue
->write(2 * bl
.length(), bl
.length(),
315 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
317 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
318 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
320 std::string clone_name
= get_temp_image_name();
321 int order
= m_src_ictx
->order
;
323 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
324 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
325 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
327 close_image(m_src_ictx
);
328 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
331 bl1
.append(std::string(1000, 'X'));
332 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
333 m_src_ictx
->io_work_queue
->write(0 * bl
.length(), bl1
.length(),
334 bufferlist
{bl1
}, 0));
335 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
336 m_src_ictx
->io_work_queue
->discard(bl1
.length() + 10,
337 bl1
.length(), false));
338 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
340 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
341 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
343 clone_name
= get_temp_image_name();
344 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
345 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
347 close_image(m_src_ictx
);
348 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
350 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
351 m_src_ictx
->io_work_queue
->write(1 * bl
.length(), bl1
.length(),
352 bufferlist
{bl1
}, 0));
353 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
354 m_src_ictx
->io_work_queue
->discard(2 * bl1
.length() + 10,
355 bl1
.length(), false));
359 uint64_t initial_size
, size
;
361 std::shared_lock src_locker
{m_src_ictx
->image_lock
};
362 size
= initial_size
= m_src_ictx
->get_image_size(CEPH_NOSNAP
);
366 const char *c
= getenv("TEST_RBD_DEEPCOPY_STRESS_NSNAPS");
368 std::stringstream
ss(c
);
369 ASSERT_TRUE(ss
>> nsnaps
);
373 c
= getenv("TEST_RBD_DEEPCOPY_STRESS_NWRITES");
375 std::stringstream
ss(c
);
376 ASSERT_TRUE(ss
>> nwrites
);
379 for (int i
= 0; i
< nsnaps
; i
++) {
380 for (int j
= 0; j
< nwrites
; j
++) {
381 size_t len
= rand() % ((1 << m_src_ictx
->order
) * 2);
382 ASSERT_GT(size
, len
);
384 bl
.append(std::string(len
, static_cast<char>('A' + i
)));
385 uint64_t off
= std::min(static_cast<uint64_t>(rand() % size
),
386 static_cast<uint64_t>(size
- len
));
387 std::cout
<< "write: " << static_cast<char>('A' + i
) << " " << off
388 << "~" << len
<< std::endl
;
389 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
390 m_src_ictx
->io_work_queue
->write(off
, bl
.length(),
392 len
= rand() % ((1 << m_src_ictx
->order
) * 2);
393 ASSERT_GT(size
, len
);
394 off
= std::min(static_cast<uint64_t>(rand() % size
),
395 static_cast<uint64_t>(size
- len
));
396 std::cout
<< "discard: " << off
<< "~" << len
<< std::endl
;
397 ASSERT_EQ(static_cast<ssize_t
>(len
),
398 m_src_ictx
->io_work_queue
->discard(off
, len
, false));
401 ASSERT_EQ(0, m_src_ictx
->io_work_queue
->flush());
403 std::string snap_name
= "snap" + stringify(i
);
404 std::cout
<< "snap: " << snap_name
<< std::endl
;
405 ASSERT_EQ(0, snap_create(*m_src_ictx
, snap_name
.c_str()));
407 if (m_src_ictx
->test_features(RBD_FEATURE_LAYERING
) && rand() % 4) {
408 ASSERT_EQ(0, snap_protect(*m_src_ictx
, snap_name
.c_str()));
410 std::string clone_name
= get_temp_image_name();
411 int order
= m_src_ictx
->order
;
413 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
414 features
&= ~RBD_FEATURES_IMPLICIT_ENABLE
;
416 std::cout
<< "clone " << m_src_ictx
->name
<< " -> " << clone_name
418 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(),
419 snap_name
.c_str(), m_ioctx
,
420 clone_name
.c_str(), features
, &order
,
421 m_src_ictx
->stripe_unit
,
422 m_src_ictx
->stripe_count
));
423 close_image(m_src_ictx
);
424 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
428 librbd::NoOpProgressContext no_op
;
429 uint64_t new_size
= initial_size
+ rand() % size
;
430 std::cout
<< "resize: " << new_size
<< std::endl
;
431 ASSERT_EQ(0, m_src_ictx
->operations
->resize(new_size
, true, no_op
));
433 std::shared_lock src_locker
{m_src_ictx
->image_lock
};
434 size
= m_src_ictx
->get_image_size(CEPH_NOSNAP
);
436 ASSERT_EQ(new_size
, size
);
441 librbd::ImageCtx
*m_src_ictx
= nullptr;
442 librbd::ImageCtx
*m_dst_ictx
= nullptr;
443 librbd::ImageOptions m_opts
;
446 TEST_F(TestDeepCopy
, Empty
)
450 TEST_F(TestDeepCopy
, NoSnaps
)
455 TEST_F(TestDeepCopy
, Snaps
)
460 TEST_F(TestDeepCopy
, SnapDiscard
)
465 TEST_F(TestDeepCopy
, CloneDiscard
)
467 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
469 test_clone_discard();
472 TEST_F(TestDeepCopy
, CloneShrink
)
474 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
479 TEST_F(TestDeepCopy
, CloneExpand
)
481 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
486 TEST_F(TestDeepCopy
, CloneHideParent
)
488 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
490 test_clone_hide_parent();
493 TEST_F(TestDeepCopy
, Clone
)
495 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
500 TEST_F(TestDeepCopy
, CloneFlatten
)
502 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
504 uint64_t flatten
= 1;
505 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
510 TEST_F(TestDeepCopy
, Stress
)
515 TEST_F(TestDeepCopy
, NoSnaps_LargerDstObjSize
)
517 uint64_t order
= m_src_ictx
->order
+ 1;
518 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
523 TEST_F(TestDeepCopy
, Snaps_LargerDstObjSize
)
525 uint64_t order
= m_src_ictx
->order
+ 1;
526 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
531 TEST_F(TestDeepCopy
, Clone_LargerDstObjSize
)
533 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
535 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
536 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
541 TEST_F(TestDeepCopy
, CloneFlatten_LargerDstObjSize
)
543 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
545 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
546 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
547 uint64_t flatten
= 1;
548 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
553 TEST_F(TestDeepCopy
, Stress_LargerDstObjSize
)
555 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
556 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
561 TEST_F(TestDeepCopy
, NoSnaps_SmallerDstObjSize
)
563 uint64_t order
= m_src_ictx
->order
- 1;
564 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
565 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 1;
566 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
571 TEST_F(TestDeepCopy
, Snaps_SmallerDstObjSize
)
573 uint64_t order
= m_src_ictx
->order
- 1;
574 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
575 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 1;
576 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
581 TEST_F(TestDeepCopy
, Clone_SmallerDstObjSize
)
583 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
585 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
586 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
587 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 2;
588 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
593 TEST_F(TestDeepCopy
, CloneFlatten_SmallerDstObjSize
)
595 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
597 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
598 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
599 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 2;
600 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
601 uint64_t flatten
= 1;
602 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
607 TEST_F(TestDeepCopy
, Stress_SmallerDstObjSize
)
609 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
610 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
611 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 2;
612 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
617 TEST_F(TestDeepCopy
, NoSnaps_StrippingLargerDstObjSize
)
619 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
621 uint64_t order
= m_src_ictx
->order
+ 1;
622 uint64_t stripe_unit
= 1 << (order
- 2);
623 uint64_t stripe_count
= 4;
624 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
625 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
626 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
631 TEST_F(TestDeepCopy
, Snaps_StrippingLargerDstObjSize
)
633 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
635 uint64_t order
= m_src_ictx
->order
+ 1;
636 uint64_t stripe_unit
= 1 << (order
- 2);
637 uint64_t stripe_count
= 4;
638 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
639 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
640 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
645 TEST_F(TestDeepCopy
, Clone_StrippingLargerDstObjSize
)
647 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
649 uint64_t order
= m_src_ictx
->order
+ 1;
650 uint64_t stripe_unit
= 1 << (order
- 2);
651 uint64_t stripe_count
= 4;
652 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
653 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
654 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
659 TEST_F(TestDeepCopy
, CloneFlatten_StrippingLargerDstObjSize
)
661 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
663 uint64_t order
= m_src_ictx
->order
+ 1;
664 uint64_t stripe_unit
= 1 << (order
- 2);
665 uint64_t stripe_count
= 4;
666 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
667 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
668 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
669 uint64_t flatten
= 1;
670 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
675 TEST_F(TestDeepCopy
, Stress_StrippingLargerDstObjSize
)
677 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
679 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
680 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
681 uint64_t stripe_count
= 2 + rand() % 14;
682 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
683 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
684 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
689 TEST_F(TestDeepCopy
, NoSnaps_StrippingSmallerDstObjSize
)
691 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
693 uint64_t order
= m_src_ictx
->order
- 1;
694 uint64_t stripe_unit
= 1 << (order
- 2);
695 uint64_t stripe_count
= 4;
696 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
697 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
698 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
703 TEST_F(TestDeepCopy
, Snaps_StrippingSmallerDstObjSize
)
705 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
707 uint64_t order
= m_src_ictx
->order
- 1;
708 uint64_t stripe_unit
= 1 << (order
- 2);
709 uint64_t stripe_count
= 4;
710 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
711 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
712 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
717 TEST_F(TestDeepCopy
, Clone_StrippingSmallerDstObjSize
)
719 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
721 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
722 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
723 uint64_t stripe_count
= 2 + rand() % 14;
724 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
725 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
726 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
731 TEST_F(TestDeepCopy
, CloneFlatten_StrippingSmallerDstObjSize
)
733 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
735 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
736 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
737 uint64_t stripe_count
= 2 + rand() % 14;
738 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
739 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
740 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
741 uint64_t flatten
= 1;
742 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
747 TEST_F(TestDeepCopy
, Stress_StrippingSmallerDstObjSize
)
749 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
751 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
752 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
753 uint64_t stripe_count
= 2 + rand() % 14;
754 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
755 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
756 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));