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/Io.h"
8 #include "librbd/api/Image.h"
9 #include "librbd/api/Snapshot.h"
10 #include "librbd/internal.h"
11 #include "librbd/io/ReadResult.h"
13 void register_test_deep_copy() {
18 struct TestDeepCopy
: public TestFixture
{
19 void SetUp() override
{
22 std::string image_name
= get_temp_image_name();
24 uint64_t size
= (1 << order
) * 20;
25 uint64_t features
= 0;
26 bool old_format
= !::get_features(&features
);
27 EXPECT_EQ(0, create_image_full_pp(m_rbd
, m_ioctx
, image_name
, size
,
28 features
, old_format
, &order
));
29 ASSERT_EQ(0, open_image(image_name
, &m_src_ictx
));
32 // The destination should always be in the new format.
34 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FORMAT
, format
));
38 void TearDown() override
{
39 if (m_src_ictx
!= nullptr) {
41 if (m_dst_ictx
!= nullptr) {
43 close_image(m_dst_ictx
);
45 close_image(m_src_ictx
);
48 TestFixture::TearDown();
52 std::string dst_name
= get_temp_image_name();
53 librbd::NoOpProgressContext no_op
;
54 EXPECT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
55 EXPECT_EQ(0, librbd::api::Image
<>::deep_copy(m_src_ictx
, m_src_ictx
->md_ctx
,
56 dst_name
.c_str(), m_opts
,
58 EXPECT_EQ(0, open_image(dst_name
, &m_dst_ictx
));
62 std::vector
<librbd::snap_info_t
> src_snaps
, dst_snaps
;
64 EXPECT_EQ(m_src_ictx
->size
, m_dst_ictx
->size
);
65 EXPECT_EQ(0, librbd::api::Snapshot
<>::list(m_src_ictx
, src_snaps
));
66 EXPECT_EQ(0, librbd::api::Snapshot
<>::list(m_dst_ictx
, dst_snaps
));
67 EXPECT_EQ(src_snaps
.size(), dst_snaps
.size());
68 for (size_t i
= 0; i
<= src_snaps
.size(); i
++) {
69 const char *src_snap_name
= nullptr;
70 const char *dst_snap_name
= nullptr;
71 if (i
< src_snaps
.size()) {
72 EXPECT_EQ(src_snaps
[i
].name
, dst_snaps
[i
].name
);
73 src_snap_name
= src_snaps
[i
].name
.c_str();
74 dst_snap_name
= dst_snaps
[i
].name
.c_str();
76 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
77 m_src_ictx
, cls::rbd::UserSnapshotNamespace(),
79 EXPECT_EQ(0, librbd::api::Image
<>::snap_set(
80 m_dst_ictx
, cls::rbd::UserSnapshotNamespace(),
82 uint64_t src_size
, dst_size
;
84 std::shared_lock src_locker
{m_src_ictx
->image_lock
};
85 std::shared_lock dst_locker
{m_dst_ictx
->image_lock
};
86 src_size
= m_src_ictx
->get_image_size(m_src_ictx
->snap_id
);
87 dst_size
= m_dst_ictx
->get_image_size(m_dst_ictx
->snap_id
);
89 EXPECT_EQ(src_size
, dst_size
);
91 if (m_dst_ictx
->test_features(RBD_FEATURE_LAYERING
)) {
93 std::shared_lock dst_locker
{m_dst_ictx
->image_lock
};
94 EXPECT_EQ(0, m_dst_ictx
->test_flags(m_dst_ictx
->snap_id
,
95 RBD_FLAG_OBJECT_MAP_INVALID
,
96 m_dst_ictx
->image_lock
, &flags_set
));
97 EXPECT_FALSE(flags_set
);
100 ssize_t read_size
= 1 << m_src_ictx
->order
;
102 while (offset
< src_size
) {
103 read_size
= std::min(read_size
, static_cast<ssize_t
>(src_size
- offset
));
105 bufferptr
src_ptr(read_size
);
107 src_bl
.push_back(src_ptr
);
108 librbd::io::ReadResult src_result
{&src_bl
};
109 EXPECT_EQ(read_size
, api::Io
<>::read(
110 *m_src_ictx
, offset
, read_size
,
111 librbd::io::ReadResult
{src_result
}, 0));
113 bufferptr
dst_ptr(read_size
);
115 dst_bl
.push_back(dst_ptr
);
116 librbd::io::ReadResult dst_result
{&dst_bl
};
117 EXPECT_EQ(read_size
, api::Io
<>::read(
118 *m_dst_ictx
, offset
, read_size
,
119 librbd::io::ReadResult
{dst_result
}, 0));
121 if (!src_bl
.contents_equal(dst_bl
)) {
122 std::cout
<< "snap: " << (src_snap_name
? src_snap_name
: "null")
123 << ", block " << offset
<< "~" << read_size
<< " differs"
125 std::cout
<< "src block: " << std::endl
; src_bl
.hexdump(std::cout
);
126 std::cout
<< "dst block: " << std::endl
; dst_bl
.hexdump(std::cout
);
128 EXPECT_TRUE(src_bl
.contents_equal(dst_bl
));
134 void test_no_snaps() {
136 bl
.append(std::string(((1 << m_src_ictx
->order
) * 2) + 1, '1'));
137 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
138 api::Io
<>::write(*m_src_ictx
, 0 * bl
.length(), bl
.length(),
140 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
141 api::Io
<>::write(*m_src_ictx
, 2 * bl
.length(), bl
.length(),
147 bl
.append(std::string(((1 << m_src_ictx
->order
) * 2) + 1, '1'));
148 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
149 api::Io
<>::write(*m_src_ictx
, 0 * bl
.length(), bl
.length(),
151 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
153 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap1"));
155 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
156 api::Io
<>::write(*m_src_ictx
, 1 * bl
.length(), bl
.length(),
159 bl1
.append(std::string(1000, 'X'));
160 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
161 api::Io
<>::write(*m_src_ictx
, 0 * bl
.length(), bl1
.length(),
162 bufferlist
{bl1
}, 0));
163 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
164 api::Io
<>::discard(*m_src_ictx
, bl1
.length() + 10,
165 bl1
.length(), false));
167 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
169 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap2"));
170 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
171 api::Io
<>::write(*m_src_ictx
, 1 * bl
.length(), bl1
.length(),
172 bufferlist
{bl1
}, 0));
173 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
174 api::Io
<>::discard(*m_src_ictx
, 2 * bl1
.length() + 10,
175 bl1
.length(), false));
178 void test_snap_discard() {
180 bl
.append(std::string(100, '1'));
181 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
182 api::Io
<>::write(*m_src_ictx
, 0, bl
.length(), bufferlist
{bl
}, 0));
183 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
185 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
187 size_t len
= (1 << m_src_ictx
->order
) * 2;
188 ASSERT_EQ(static_cast<ssize_t
>(len
),
189 api::Io
<>::discard(*m_src_ictx
, 0, len
, false));
192 void test_clone_discard() {
194 bl
.append(std::string(100, '1'));
195 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
196 api::Io
<>::write(*m_src_ictx
, 0, bl
.length(), bufferlist
{bl
}, 0));
197 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
199 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
200 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
202 std::string clone_name
= get_temp_image_name();
203 int order
= m_src_ictx
->order
;
205 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
206 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
207 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
209 close_image(m_src_ictx
);
210 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
212 size_t len
= (1 << m_src_ictx
->order
) * 2;
213 ASSERT_EQ(static_cast<ssize_t
>(len
),
214 api::Io
<>::discard(*m_src_ictx
, 0, len
, false));
217 void test_clone_shrink() {
219 bl
.append(std::string(100, '1'));
220 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
221 api::Io
<>::write(*m_src_ictx
, 0, bl
.length(), bufferlist
{bl
}, 0));
222 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
224 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
225 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
227 std::string clone_name
= get_temp_image_name();
228 int order
= m_src_ictx
->order
;
230 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
231 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
232 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
234 close_image(m_src_ictx
);
235 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
237 librbd::NoOpProgressContext no_op
;
238 auto new_size
= m_src_ictx
->size
>> 1;
239 ASSERT_EQ(0, m_src_ictx
->operations
->resize(new_size
, true, no_op
));
242 void test_clone_expand() {
244 bl
.append(std::string(100, '1'));
245 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
246 api::Io
<>::write(*m_src_ictx
, 0, bl
.length(), bufferlist
{bl
}, 0));
247 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
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 api::Io
<>::write(*m_src_ictx
, object_size
, bl
.length(),
274 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
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 api::Io
<>::discard(*m_src_ictx
, object_size
, bl
.length(), false));
293 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
295 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap2"));
297 librbd::NoOpProgressContext no_op
;
298 ASSERT_EQ(0, m_src_ictx
->operations
->resize(object_size
, true, no_op
));
300 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap3"));
302 ASSERT_EQ(0, m_src_ictx
->operations
->resize(2 * object_size
, true, no_op
));
307 bl
.append(std::string(((1 << m_src_ictx
->order
) * 2) + 1, '1'));
308 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
309 api::Io
<>::write(*m_src_ictx
, 0 * bl
.length(), bl
.length(),
311 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
312 api::Io
<>::write(*m_src_ictx
, 2 * bl
.length(), bl
.length(),
314 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
316 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
317 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
319 std::string clone_name
= get_temp_image_name();
320 int order
= m_src_ictx
->order
;
322 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
323 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
324 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
326 close_image(m_src_ictx
);
327 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
330 bl1
.append(std::string(1000, 'X'));
331 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
332 api::Io
<>::write(*m_src_ictx
, 0 * bl
.length(), bl1
.length(),
333 bufferlist
{bl1
}, 0));
334 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
335 api::Io
<>::discard(*m_src_ictx
, bl1
.length() + 10,
336 bl1
.length(), false));
337 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
339 ASSERT_EQ(0, snap_create(*m_src_ictx
, "snap"));
340 ASSERT_EQ(0, snap_protect(*m_src_ictx
, "snap"));
342 clone_name
= get_temp_image_name();
343 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(), "snap",
344 m_ioctx
, clone_name
.c_str(), features
, &order
, 0,
346 close_image(m_src_ictx
);
347 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
349 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
350 api::Io
<>::write(*m_src_ictx
, 1 * bl
.length(), bl1
.length(),
351 bufferlist
{bl1
}, 0));
352 ASSERT_EQ(static_cast<ssize_t
>(bl1
.length()),
353 api::Io
<>::discard(*m_src_ictx
, 2 * bl1
.length() + 10,
354 bl1
.length(), false));
358 uint64_t initial_size
, size
;
360 std::shared_lock src_locker
{m_src_ictx
->image_lock
};
361 size
= initial_size
= m_src_ictx
->get_image_size(CEPH_NOSNAP
);
365 const char *c
= getenv("TEST_RBD_DEEPCOPY_STRESS_NSNAPS");
367 std::stringstream
ss(c
);
368 ASSERT_TRUE(ss
>> nsnaps
);
372 c
= getenv("TEST_RBD_DEEPCOPY_STRESS_NWRITES");
374 std::stringstream
ss(c
);
375 ASSERT_TRUE(ss
>> nwrites
);
378 for (int i
= 0; i
< nsnaps
; i
++) {
379 for (int j
= 0; j
< nwrites
; j
++) {
380 size_t len
= rand() % ((1 << m_src_ictx
->order
) * 2);
381 ASSERT_GT(size
, len
);
383 bl
.append(std::string(len
, static_cast<char>('A' + i
)));
384 uint64_t off
= std::min(static_cast<uint64_t>(rand() % size
),
385 static_cast<uint64_t>(size
- len
));
386 std::cout
<< "write: " << static_cast<char>('A' + i
) << " " << off
387 << "~" << len
<< std::endl
;
388 ASSERT_EQ(static_cast<ssize_t
>(bl
.length()),
389 api::Io
<>::write(*m_src_ictx
, off
, bl
.length(),
391 len
= rand() % ((1 << m_src_ictx
->order
) * 2);
392 ASSERT_GT(size
, len
);
393 off
= std::min(static_cast<uint64_t>(rand() % size
),
394 static_cast<uint64_t>(size
- len
));
395 std::cout
<< "discard: " << off
<< "~" << len
<< std::endl
;
396 ASSERT_EQ(static_cast<ssize_t
>(len
),
397 api::Io
<>::discard(*m_src_ictx
, off
, len
, false));
400 ASSERT_EQ(0, api::Io
<>::flush(*m_src_ictx
));
402 std::string snap_name
= "snap" + stringify(i
);
403 std::cout
<< "snap: " << snap_name
<< std::endl
;
404 ASSERT_EQ(0, snap_create(*m_src_ictx
, snap_name
.c_str()));
406 if (m_src_ictx
->test_features(RBD_FEATURE_LAYERING
) && rand() % 4) {
407 ASSERT_EQ(0, snap_protect(*m_src_ictx
, snap_name
.c_str()));
409 std::string clone_name
= get_temp_image_name();
410 int order
= m_src_ictx
->order
;
412 ASSERT_EQ(0, librbd::get_features(m_src_ictx
, &features
));
414 std::cout
<< "clone " << m_src_ictx
->name
<< " -> " << clone_name
416 ASSERT_EQ(0, librbd::clone(m_ioctx
, m_src_ictx
->name
.c_str(),
417 snap_name
.c_str(), m_ioctx
,
418 clone_name
.c_str(), features
, &order
,
419 m_src_ictx
->stripe_unit
,
420 m_src_ictx
->stripe_count
));
421 close_image(m_src_ictx
);
422 ASSERT_EQ(0, open_image(clone_name
, &m_src_ictx
));
426 librbd::NoOpProgressContext no_op
;
427 uint64_t new_size
= initial_size
+ rand() % size
;
428 std::cout
<< "resize: " << new_size
<< std::endl
;
429 ASSERT_EQ(0, m_src_ictx
->operations
->resize(new_size
, true, no_op
));
431 std::shared_lock src_locker
{m_src_ictx
->image_lock
};
432 size
= m_src_ictx
->get_image_size(CEPH_NOSNAP
);
434 ASSERT_EQ(new_size
, size
);
439 librbd::ImageCtx
*m_src_ictx
= nullptr;
440 librbd::ImageCtx
*m_dst_ictx
= nullptr;
441 librbd::ImageOptions m_opts
;
444 TEST_F(TestDeepCopy
, Empty
)
448 TEST_F(TestDeepCopy
, NoSnaps
)
453 TEST_F(TestDeepCopy
, Snaps
)
458 TEST_F(TestDeepCopy
, SnapDiscard
)
463 TEST_F(TestDeepCopy
, CloneDiscard
)
465 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
467 test_clone_discard();
470 TEST_F(TestDeepCopy
, CloneShrink
)
472 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
477 TEST_F(TestDeepCopy
, CloneExpand
)
479 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
484 TEST_F(TestDeepCopy
, CloneHideParent
)
486 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
488 test_clone_hide_parent();
491 TEST_F(TestDeepCopy
, Clone
)
493 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
498 TEST_F(TestDeepCopy
, CloneFlatten
)
500 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
502 uint64_t flatten
= 1;
503 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
508 TEST_F(TestDeepCopy
, Stress
)
513 TEST_F(TestDeepCopy
, NoSnaps_LargerDstObjSize
)
515 uint64_t order
= m_src_ictx
->order
+ 1;
516 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
521 TEST_F(TestDeepCopy
, Snaps_LargerDstObjSize
)
523 uint64_t order
= m_src_ictx
->order
+ 1;
524 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
529 TEST_F(TestDeepCopy
, Clone_LargerDstObjSize
)
531 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
533 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
534 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
539 TEST_F(TestDeepCopy
, CloneFlatten_LargerDstObjSize
)
541 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
543 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
544 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
545 uint64_t flatten
= 1;
546 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
551 TEST_F(TestDeepCopy
, Stress_LargerDstObjSize
)
553 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
554 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
559 TEST_F(TestDeepCopy
, NoSnaps_SmallerDstObjSize
)
561 uint64_t order
= m_src_ictx
->order
- 1;
562 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
563 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 1;
564 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
569 TEST_F(TestDeepCopy
, Snaps_SmallerDstObjSize
)
571 uint64_t order
= m_src_ictx
->order
- 1;
572 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
573 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 1;
574 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
579 TEST_F(TestDeepCopy
, Clone_SmallerDstObjSize
)
581 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
583 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
584 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
585 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 2;
586 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
591 TEST_F(TestDeepCopy
, CloneFlatten_SmallerDstObjSize
)
593 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
);
595 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
596 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
597 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 2;
598 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
599 uint64_t flatten
= 1;
600 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
605 TEST_F(TestDeepCopy
, Stress_SmallerDstObjSize
)
607 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
608 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
609 uint64_t stripe_unit
= m_src_ictx
->stripe_unit
>> 2;
610 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
615 TEST_F(TestDeepCopy
, NoSnaps_StrippingLargerDstObjSize
)
617 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
619 uint64_t order
= m_src_ictx
->order
+ 1;
620 uint64_t stripe_unit
= 1 << (order
- 2);
621 uint64_t stripe_count
= 4;
622 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
623 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
624 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
629 TEST_F(TestDeepCopy
, Snaps_StrippingLargerDstObjSize
)
631 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
633 uint64_t order
= m_src_ictx
->order
+ 1;
634 uint64_t stripe_unit
= 1 << (order
- 2);
635 uint64_t stripe_count
= 4;
636 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
637 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
638 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
643 TEST_F(TestDeepCopy
, Clone_StrippingLargerDstObjSize
)
645 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
647 uint64_t order
= m_src_ictx
->order
+ 1;
648 uint64_t stripe_unit
= 1 << (order
- 2);
649 uint64_t stripe_count
= 4;
650 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
651 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
652 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
657 TEST_F(TestDeepCopy
, CloneFlatten_StrippingLargerDstObjSize
)
659 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
661 uint64_t order
= m_src_ictx
->order
+ 1;
662 uint64_t stripe_unit
= 1 << (order
- 2);
663 uint64_t stripe_count
= 4;
664 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
665 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
666 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
667 uint64_t flatten
= 1;
668 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
673 TEST_F(TestDeepCopy
, Stress_StrippingLargerDstObjSize
)
675 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
677 uint64_t order
= m_src_ictx
->order
+ 1 + rand() % 2;
678 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
679 uint64_t stripe_count
= 2 + rand() % 14;
680 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
681 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
682 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
687 TEST_F(TestDeepCopy
, NoSnaps_StrippingSmallerDstObjSize
)
689 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
691 uint64_t order
= m_src_ictx
->order
- 1;
692 uint64_t stripe_unit
= 1 << (order
- 2);
693 uint64_t stripe_count
= 4;
694 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
695 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
696 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
701 TEST_F(TestDeepCopy
, Snaps_StrippingSmallerDstObjSize
)
703 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
705 uint64_t order
= m_src_ictx
->order
- 1;
706 uint64_t stripe_unit
= 1 << (order
- 2);
707 uint64_t stripe_count
= 4;
708 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
709 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
710 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
715 TEST_F(TestDeepCopy
, Clone_StrippingSmallerDstObjSize
)
717 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
719 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
720 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
721 uint64_t stripe_count
= 2 + rand() % 14;
722 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
723 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
724 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
729 TEST_F(TestDeepCopy
, CloneFlatten_StrippingSmallerDstObjSize
)
731 REQUIRE_FEATURE(RBD_FEATURE_LAYERING
| RBD_FEATURE_STRIPINGV2
);
733 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
734 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
735 uint64_t stripe_count
= 2 + rand() % 14;
736 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
737 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
738 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
739 uint64_t flatten
= 1;
740 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_FLATTEN
, flatten
));
745 TEST_F(TestDeepCopy
, Stress_StrippingSmallerDstObjSize
)
747 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2
);
749 uint64_t order
= m_src_ictx
->order
- 1 - rand() % 2;
750 uint64_t stripe_unit
= 1 << (order
- rand() % 4);
751 uint64_t stripe_count
= 2 + rand() % 14;
752 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_ORDER
, order
));
753 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_UNIT
, stripe_unit
));
754 ASSERT_EQ(0, m_opts
.set(RBD_IMAGE_OPTION_STRIPE_COUNT
, stripe_count
));
759 } // namespace librbd