]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/test_DeepCopy.cc
6bdb82c1cd9cc8bdaf817387538f912636a46a0a
[ceph.git] / ceph / src / test / librbd / test_DeepCopy.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
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"
12
13 void register_test_deep_copy() {
14 }
15
16 struct TestDeepCopy : public TestFixture {
17 void SetUp() override {
18 TestFixture::SetUp();
19
20 std::string image_name = get_temp_image_name();
21 int order = 22;
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));
28
29 if (old_format) {
30 // The destination should always be in the new format.
31 uint64_t format = 2;
32 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_FORMAT, format));
33 }
34 }
35
36 void TearDown() override {
37 if (m_src_ictx != nullptr) {
38 deep_copy();
39 if (m_dst_ictx != nullptr) {
40 compare();
41 close_image(m_dst_ictx);
42 }
43 close_image(m_src_ictx);
44 }
45
46 TestFixture::TearDown();
47 }
48
49 void deep_copy() {
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,
55 no_op));
56 EXPECT_EQ(0, open_image(dst_name, &m_dst_ictx));
57 }
58
59 void compare() {
60 vector<librbd::snap_info_t> src_snaps, dst_snaps;
61
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();
73 }
74 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
75 m_src_ictx, cls::rbd::UserSnapshotNamespace(),
76 src_snap_name));
77 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
78 m_dst_ictx, cls::rbd::UserSnapshotNamespace(),
79 dst_snap_name));
80 uint64_t src_size, dst_size;
81 {
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);
86 }
87 EXPECT_EQ(src_size, dst_size);
88
89 if (m_dst_ictx->test_features(RBD_FEATURE_LAYERING)) {
90 bool flags_set;
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);
96 }
97
98 ssize_t read_size = 1 << m_src_ictx->order;
99 uint64_t offset = 0;
100 while (offset < src_size) {
101 read_size = std::min(read_size, static_cast<ssize_t>(src_size - offset));
102
103 bufferptr src_ptr(read_size);
104 bufferlist src_bl;
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));
109
110 bufferptr dst_ptr(read_size);
111 bufferlist dst_bl;
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));
116
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"
120 << std::endl;
121 // std::cout << "src block: " << std::endl; src_bl.hexdump(std::cout);
122 // std::cout << "dst block: " << std::endl; dst_bl.hexdump(std::cout);
123 }
124 EXPECT_TRUE(src_bl.contents_equal(dst_bl));
125 offset += read_size;
126 }
127 }
128 }
129
130 void test_no_snaps() {
131 bufferlist bl;
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(),
135 bufferlist{bl}, 0));
136 ASSERT_EQ(static_cast<ssize_t>(bl.length()),
137 m_src_ictx->io_work_queue->write(2 * bl.length(), bl.length(),
138 bufferlist{bl}, 0));
139 }
140
141 void test_snaps() {
142 bufferlist bl;
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(),
146 bufferlist{bl}, 0));
147 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
148
149 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap1"));
150
151 ASSERT_EQ(static_cast<ssize_t>(bl.length()),
152 m_src_ictx->io_work_queue->write(1 * bl.length(), bl.length(),
153 bufferlist{bl}, 0));
154 bufferlist bl1;
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));
162
163 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
164
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));
172 }
173
174 void test_snap_discard() {
175 bufferlist bl;
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},
179 0));
180 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
181
182 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
183
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));
187 }
188
189 void test_clone_discard() {
190 bufferlist bl;
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},
194 0));
195 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
196
197 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
198 ASSERT_EQ(0, snap_protect(*m_src_ictx, "snap"));
199
200 std::string clone_name = get_temp_image_name();
201 int order = m_src_ictx->order;
202 uint64_t features;
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,
206 0));
207 close_image(m_src_ictx);
208 ASSERT_EQ(0, open_image(clone_name, &m_src_ictx));
209
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));
213 }
214
215 void test_clone_shrink() {
216 bufferlist bl;
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},
220 0));
221 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
222
223 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
224 ASSERT_EQ(0, snap_protect(*m_src_ictx, "snap"));
225
226 std::string clone_name = get_temp_image_name();
227 int order = m_src_ictx->order;
228 uint64_t features;
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,
232 0));
233 close_image(m_src_ictx);
234 ASSERT_EQ(0, open_image(clone_name, &m_src_ictx));
235
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));
239 }
240
241 void test_clone_expand() {
242 bufferlist bl;
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},
246 0));
247 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
248
249 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
250 ASSERT_EQ(0, snap_protect(*m_src_ictx, "snap"));
251
252 std::string clone_name = get_temp_image_name();
253 int order = m_src_ictx->order;
254 uint64_t features;
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,
258 0));
259 close_image(m_src_ictx);
260 ASSERT_EQ(0, open_image(clone_name, &m_src_ictx));
261
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));
265 }
266
267 void test_clone_hide_parent() {
268 uint64_t object_size = 1 << m_src_ictx->order;
269 bufferlist bl;
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(),
273 bufferlist{bl}, 0));
274 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
275
276 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
277 ASSERT_EQ(0, snap_protect(*m_src_ictx, "snap"));
278
279 std::string clone_name = get_temp_image_name();
280 int order = m_src_ictx->order;
281 uint64_t features;
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,
285 0));
286 close_image(m_src_ictx);
287 ASSERT_EQ(0, open_image(clone_name, &m_src_ictx));
288
289 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap1"));
290
291 ASSERT_EQ(static_cast<ssize_t>(bl.length()),
292 m_src_ictx->io_work_queue->discard(object_size, bl.length(),
293 false));
294 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
295
296 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap2"));
297
298 librbd::NoOpProgressContext no_op;
299 ASSERT_EQ(0, m_src_ictx->operations->resize(object_size, true, no_op));
300
301 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap3"));
302
303 ASSERT_EQ(0, m_src_ictx->operations->resize(2 * object_size, true, no_op));
304 }
305
306 void test_clone() {
307 bufferlist bl;
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(),
311 bufferlist{bl}, 0));
312 ASSERT_EQ(static_cast<ssize_t>(bl.length()),
313 m_src_ictx->io_work_queue->write(2 * bl.length(), bl.length(),
314 bufferlist{bl}, 0));
315 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
316
317 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
318 ASSERT_EQ(0, snap_protect(*m_src_ictx, "snap"));
319
320 std::string clone_name = get_temp_image_name();
321 int order = m_src_ictx->order;
322 uint64_t features;
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,
326 0));
327 close_image(m_src_ictx);
328 ASSERT_EQ(0, open_image(clone_name, &m_src_ictx));
329
330 bufferlist bl1;
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());
339
340 ASSERT_EQ(0, snap_create(*m_src_ictx, "snap"));
341 ASSERT_EQ(0, snap_protect(*m_src_ictx, "snap"));
342
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,
346 0));
347 close_image(m_src_ictx);
348 ASSERT_EQ(0, open_image(clone_name, &m_src_ictx));
349
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));
356 }
357
358 void test_stress() {
359 uint64_t initial_size, size;
360 {
361 std::shared_lock src_locker{m_src_ictx->image_lock};
362 size = initial_size = m_src_ictx->get_image_size(CEPH_NOSNAP);
363 }
364
365 int nsnaps = 4;
366 const char *c = getenv("TEST_RBD_DEEPCOPY_STRESS_NSNAPS");
367 if (c != NULL) {
368 std::stringstream ss(c);
369 ASSERT_TRUE(ss >> nsnaps);
370 }
371
372 int nwrites = 4;
373 c = getenv("TEST_RBD_DEEPCOPY_STRESS_NWRITES");
374 if (c != NULL) {
375 std::stringstream ss(c);
376 ASSERT_TRUE(ss >> nwrites);
377 }
378
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);
383 bufferlist bl;
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(),
391 bufferlist{bl}, 0));
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));
399 }
400
401 ASSERT_EQ(0, m_src_ictx->io_work_queue->flush());
402
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()));
406
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()));
409
410 std::string clone_name = get_temp_image_name();
411 int order = m_src_ictx->order;
412 uint64_t features;
413 ASSERT_EQ(0, librbd::get_features(m_src_ictx, &features));
414 features &= ~RBD_FEATURES_IMPLICIT_ENABLE;
415
416 std::cout << "clone " << m_src_ictx->name << " -> " << clone_name
417 << std::endl;
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));
425 }
426
427 if (rand() % 2) {
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));
432 {
433 std::shared_lock src_locker{m_src_ictx->image_lock};
434 size = m_src_ictx->get_image_size(CEPH_NOSNAP);
435 }
436 ASSERT_EQ(new_size, size);
437 }
438 }
439 }
440
441 librbd::ImageCtx *m_src_ictx = nullptr;
442 librbd::ImageCtx *m_dst_ictx = nullptr;
443 librbd::ImageOptions m_opts;
444 };
445
446 TEST_F(TestDeepCopy, Empty)
447 {
448 }
449
450 TEST_F(TestDeepCopy, NoSnaps)
451 {
452 test_no_snaps();
453 }
454
455 TEST_F(TestDeepCopy, Snaps)
456 {
457 test_snaps();
458 }
459
460 TEST_F(TestDeepCopy, SnapDiscard)
461 {
462 test_snap_discard();
463 }
464
465 TEST_F(TestDeepCopy, CloneDiscard)
466 {
467 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
468
469 test_clone_discard();
470 }
471
472 TEST_F(TestDeepCopy, CloneShrink)
473 {
474 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
475
476 test_clone_shrink();
477 }
478
479 TEST_F(TestDeepCopy, CloneExpand)
480 {
481 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
482
483 test_clone_expand();
484 }
485
486 TEST_F(TestDeepCopy, CloneHideParent)
487 {
488 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
489
490 test_clone_hide_parent();
491 }
492
493 TEST_F(TestDeepCopy, Clone)
494 {
495 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
496
497 test_clone();
498 }
499
500 TEST_F(TestDeepCopy, CloneFlatten)
501 {
502 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
503
504 uint64_t flatten = 1;
505 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_FLATTEN, flatten));
506
507 test_clone();
508 }
509
510 TEST_F(TestDeepCopy, Stress)
511 {
512 test_stress();
513 }
514
515 TEST_F(TestDeepCopy, NoSnaps_LargerDstObjSize)
516 {
517 uint64_t order = m_src_ictx->order + 1;
518 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_ORDER, order));
519
520 test_no_snaps();
521 }
522
523 TEST_F(TestDeepCopy, Snaps_LargerDstObjSize)
524 {
525 uint64_t order = m_src_ictx->order + 1;
526 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_ORDER, order));
527
528 test_snaps();
529 }
530
531 TEST_F(TestDeepCopy, Clone_LargerDstObjSize)
532 {
533 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
534
535 uint64_t order = m_src_ictx->order + 1 + rand() % 2;
536 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_ORDER, order));
537
538 test_clone();
539 }
540
541 TEST_F(TestDeepCopy, CloneFlatten_LargerDstObjSize)
542 {
543 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
544
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));
549
550 test_clone();
551 }
552
553 TEST_F(TestDeepCopy, Stress_LargerDstObjSize)
554 {
555 uint64_t order = m_src_ictx->order + 1 + rand() % 2;
556 ASSERT_EQ(0, m_opts.set(RBD_IMAGE_OPTION_ORDER, order));
557
558 test_stress();
559 }
560
561 TEST_F(TestDeepCopy, NoSnaps_SmallerDstObjSize)
562 {
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));
567
568 test_no_snaps();
569 }
570
571 TEST_F(TestDeepCopy, Snaps_SmallerDstObjSize)
572 {
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));
577
578 test_snaps();
579 }
580
581 TEST_F(TestDeepCopy, Clone_SmallerDstObjSize)
582 {
583 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
584
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));
589
590 test_clone();
591 }
592
593 TEST_F(TestDeepCopy, CloneFlatten_SmallerDstObjSize)
594 {
595 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
596
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));
603
604 test_clone();
605 }
606
607 TEST_F(TestDeepCopy, Stress_SmallerDstObjSize)
608 {
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));
613
614 test_stress();
615 }
616
617 TEST_F(TestDeepCopy, NoSnaps_StrippingLargerDstObjSize)
618 {
619 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2);
620
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));
627
628 test_no_snaps();
629 }
630
631 TEST_F(TestDeepCopy, Snaps_StrippingLargerDstObjSize)
632 {
633 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2);
634
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));
641
642 test_snaps();
643 }
644
645 TEST_F(TestDeepCopy, Clone_StrippingLargerDstObjSize)
646 {
647 REQUIRE_FEATURE(RBD_FEATURE_LAYERING | RBD_FEATURE_STRIPINGV2);
648
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));
655
656 test_clone();
657 }
658
659 TEST_F(TestDeepCopy, CloneFlatten_StrippingLargerDstObjSize)
660 {
661 REQUIRE_FEATURE(RBD_FEATURE_LAYERING | RBD_FEATURE_STRIPINGV2);
662
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));
671
672 test_clone();
673 }
674
675 TEST_F(TestDeepCopy, Stress_StrippingLargerDstObjSize)
676 {
677 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2);
678
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));
685
686 test_stress();
687 }
688
689 TEST_F(TestDeepCopy, NoSnaps_StrippingSmallerDstObjSize)
690 {
691 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2);
692
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));
699
700 test_no_snaps();
701 }
702
703 TEST_F(TestDeepCopy, Snaps_StrippingSmallerDstObjSize)
704 {
705 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2);
706
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));
713
714 test_snaps();
715 }
716
717 TEST_F(TestDeepCopy, Clone_StrippingSmallerDstObjSize)
718 {
719 REQUIRE_FEATURE(RBD_FEATURE_LAYERING | RBD_FEATURE_STRIPINGV2);
720
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));
727
728 test_clone();
729 }
730
731 TEST_F(TestDeepCopy, CloneFlatten_StrippingSmallerDstObjSize)
732 {
733 REQUIRE_FEATURE(RBD_FEATURE_LAYERING | RBD_FEATURE_STRIPINGV2);
734
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));
743
744 test_clone();
745 }
746
747 TEST_F(TestDeepCopy, Stress_StrippingSmallerDstObjSize)
748 {
749 REQUIRE_FEATURE(RBD_FEATURE_STRIPINGV2);
750
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));
757
758 test_stress();
759 }