]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/snapshots.cc
update sources to v12.1.0
[ceph.git] / ceph / src / test / librados / snapshots.cc
1 #include "include/rados/librados.hpp"
2 #include "test/librados/test.h"
3 #include "test/librados/TestCase.h"
4
5 #include <algorithm>
6 #include <errno.h>
7 #include "gtest/gtest.h"
8 #include <string>
9
10 using namespace librados;
11 using std::string;
12
13 typedef RadosTest LibRadosSnapshots;
14 typedef RadosTest LibRadosSnapshotsSelfManaged;
15 typedef RadosTestPP LibRadosSnapshotsPP;
16 typedef RadosTestPP LibRadosSnapshotsSelfManagedPP;
17 typedef RadosTestEC LibRadosSnapshotsEC;
18 typedef RadosTestEC LibRadosSnapshotsSelfManagedEC;
19 typedef RadosTestECPP LibRadosSnapshotsECPP;
20 typedef RadosTestECPP LibRadosSnapshotsSelfManagedECPP;
21
22 const int bufsize = 128;
23
24 TEST_F(LibRadosSnapshots, SnapList) {
25 char buf[bufsize];
26 memset(buf, 0xcc, sizeof(buf));
27 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
28 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
29 rados_snap_t snaps[10];
30 EXPECT_EQ(1, rados_ioctx_snap_list(ioctx, snaps,
31 sizeof(snaps) / sizeof(snaps[0])));
32 rados_snap_t rid;
33 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
34 EXPECT_EQ(rid, snaps[0]);
35 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
36 }
37
38 TEST_F(LibRadosSnapshotsPP, SnapListPP) {
39 char buf[bufsize];
40 memset(buf, 0xcc, sizeof(buf));
41 bufferlist bl1;
42 bl1.append(buf, sizeof(buf));
43 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
44 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
45 ASSERT_EQ(0, ioctx.snap_create("snap1"));
46 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
47 std::vector<snap_t> snaps;
48 EXPECT_EQ(0, ioctx.snap_list(&snaps));
49 EXPECT_EQ(1U, snaps.size());
50 snap_t rid;
51 EXPECT_EQ(0, ioctx.snap_lookup("snap1", &rid));
52 EXPECT_EQ(rid, snaps[0]);
53 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
54 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
55 }
56
57 TEST_F(LibRadosSnapshots, SnapRemove) {
58 char buf[bufsize];
59 memset(buf, 0xcc, sizeof(buf));
60 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
61 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
62 rados_snap_t rid;
63 ASSERT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
64 ASSERT_EQ(-EEXIST, rados_ioctx_snap_create(ioctx, "snap1"));
65 ASSERT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
66 ASSERT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
67 }
68
69 TEST_F(LibRadosSnapshotsPP, SnapRemovePP) {
70 char buf[bufsize];
71 memset(buf, 0xcc, sizeof(buf));
72 bufferlist bl1;
73 bl1.append(buf, sizeof(buf));
74 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
75 ASSERT_EQ(0, ioctx.snap_create("snap1"));
76 rados_snap_t rid;
77 ASSERT_EQ(0, ioctx.snap_lookup("snap1", &rid));
78 ASSERT_EQ(0, ioctx.snap_remove("snap1"));
79 ASSERT_EQ(-ENOENT, ioctx.snap_lookup("snap1", &rid));
80 }
81
82 TEST_F(LibRadosSnapshots, Rollback) {
83 char buf[bufsize];
84 memset(buf, 0xcc, sizeof(buf));
85 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
86 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
87 char buf2[sizeof(buf)];
88 memset(buf2, 0xdd, sizeof(buf2));
89 EXPECT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2)));
90 EXPECT_EQ(0, rados_ioctx_snap_rollback(ioctx, "foo", "snap1"));
91 char buf3[sizeof(buf)];
92 EXPECT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
93 EXPECT_EQ(0, memcmp(buf, buf3, sizeof(buf)));
94 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
95 }
96
97 TEST_F(LibRadosSnapshotsPP, RollbackPP) {
98 char buf[bufsize];
99 memset(buf, 0xcc, sizeof(buf));
100 bufferlist bl1;
101 bl1.append(buf, sizeof(buf));
102 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
103 ASSERT_EQ(0, ioctx.snap_create("snap1"));
104 char buf2[sizeof(buf)];
105 memset(buf2, 0xdd, sizeof(buf2));
106 bufferlist bl2;
107 bl2.append(buf2, sizeof(buf2));
108 EXPECT_EQ(0, ioctx.write_full("foo", bl2));
109 EXPECT_EQ(0, ioctx.snap_rollback("foo", "snap1"));
110 bufferlist bl3;
111 EXPECT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
112 EXPECT_EQ(0, memcmp(buf, bl3.c_str(), sizeof(buf)));
113 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
114 }
115
116 TEST_F(LibRadosSnapshots, SnapGetName) {
117 char buf[bufsize];
118 memset(buf, 0xcc, sizeof(buf));
119 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
120 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snapfoo"));
121 rados_snap_t rid;
122 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snapfoo", &rid));
123 EXPECT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snapbar", &rid));
124 char name[128];
125 memset(name, 0, sizeof(name));
126 EXPECT_EQ(0, rados_ioctx_snap_get_name(ioctx, rid, name, sizeof(name)));
127 time_t snaptime;
128 EXPECT_EQ(0, rados_ioctx_snap_get_stamp(ioctx, rid, &snaptime));
129 EXPECT_EQ(0, strcmp(name, "snapfoo"));
130 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snapfoo"));
131 }
132
133 TEST_F(LibRadosSnapshotsPP, SnapGetNamePP) {
134 char buf[bufsize];
135 memset(buf, 0xcc, sizeof(buf));
136 bufferlist bl;
137 bl.append(buf, sizeof(buf));
138 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
139 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
140 rados_snap_t rid;
141 EXPECT_EQ(0, ioctx.snap_lookup("snapfoo", &rid));
142 EXPECT_EQ(-ENOENT, ioctx.snap_lookup("snapbar", &rid));
143 std::string name;
144 EXPECT_EQ(0, ioctx.snap_get_name(rid, &name));
145 time_t snaptime;
146 EXPECT_EQ(0, ioctx.snap_get_stamp(rid, &snaptime));
147 EXPECT_EQ(0, strcmp(name.c_str(), "snapfoo"));
148 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
149 }
150
151 TEST_F(LibRadosSnapshotsPP, SnapCreateRemovePP) {
152 // reproduces http://tracker.ceph.com/issues/10262
153 bufferlist bl;
154 bl.append("foo");
155 ASSERT_EQ(0, ioctx.write("foo", bl, bl.length(), 0));
156 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
157 ASSERT_EQ(0, ioctx.remove("foo"));
158 ASSERT_EQ(0, ioctx.snap_create("snapbar"));
159
160 std::unique_ptr<librados::ObjectWriteOperation> op(new librados::ObjectWriteOperation());
161 op->create(false);
162 op->remove();
163 ASSERT_EQ(0, ioctx.operate("foo", op.get()));
164
165 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
166 EXPECT_EQ(0, ioctx.snap_remove("snapbar"));
167 }
168
169 TEST_F(LibRadosSnapshotsSelfManaged, Snap) {
170 std::vector<uint64_t> my_snaps;
171 my_snaps.push_back(-2);
172 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
173 ::std::reverse(my_snaps.begin(), my_snaps.end());
174 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
175 &my_snaps[0], my_snaps.size()));
176 ::std::reverse(my_snaps.begin(), my_snaps.end());
177 char buf[bufsize];
178 memset(buf, 0xcc, sizeof(buf));
179 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
180
181 my_snaps.push_back(-2);
182 rados_completion_t completion;
183 ASSERT_EQ(0, rados_aio_create_completion(nullptr, nullptr, nullptr,
184 &completion));
185 rados_aio_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back(), completion);
186 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
187 rados_aio_release(completion);
188 ::std::reverse(my_snaps.begin(), my_snaps.end());
189 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
190 &my_snaps[0], my_snaps.size()));
191 ::std::reverse(my_snaps.begin(), my_snaps.end());
192 char buf2[sizeof(buf)];
193 memset(buf2, 0xdd, sizeof(buf2));
194 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0));
195 rados_ioctx_snap_set_read(ioctx, my_snaps[1]-1);
196 char buf3[sizeof(buf)];
197 ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
198
199 rados_ioctx_snap_set_read(ioctx, my_snaps[1]);
200 ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
201 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
202
203 ASSERT_EQ(0, rados_aio_create_completion(nullptr, nullptr, nullptr,
204 &completion));
205 rados_aio_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back(), completion);
206 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
207 rados_aio_release(completion);
208 my_snaps.pop_back();
209 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
210 my_snaps.pop_back();
211 rados_ioctx_snap_set_read(ioctx, LIBRADOS_SNAP_HEAD);
212 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
213 }
214
215 TEST_F(LibRadosSnapshotsSelfManaged, Rollback) {
216 std::vector<uint64_t> my_snaps;
217 my_snaps.push_back(-2);
218 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
219 ::std::reverse(my_snaps.begin(), my_snaps.end());
220 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
221 &my_snaps[0], my_snaps.size()));
222 ::std::reverse(my_snaps.begin(), my_snaps.end());
223 char buf[bufsize];
224 memset(buf, 0xcc, sizeof(buf));
225 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
226
227 my_snaps.push_back(-2);
228 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
229 ::std::reverse(my_snaps.begin(), my_snaps.end());
230 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
231 &my_snaps[0], my_snaps.size()));
232 ::std::reverse(my_snaps.begin(), my_snaps.end());
233 char buf2[sizeof(buf)];
234 memset(buf2, 0xdd, sizeof(buf2));
235 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0));
236 rados_ioctx_selfmanaged_snap_rollback(ioctx, "foo", my_snaps[1]);
237 char buf3[sizeof(buf)];
238 ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
239 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
240
241 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
242 my_snaps.pop_back();
243 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
244 my_snaps.pop_back();
245 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
246 }
247
248 TEST_F(LibRadosSnapshotsSelfManagedPP, SnapPP) {
249 std::vector<uint64_t> my_snaps;
250 my_snaps.push_back(-2);
251 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
252 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
253 ASSERT_TRUE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
254 ::std::reverse(my_snaps.begin(), my_snaps.end());
255 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
256 ::std::reverse(my_snaps.begin(), my_snaps.end());
257 char buf[bufsize];
258 memset(buf, 0xcc, sizeof(buf));
259 bufferlist bl1;
260 bl1.append(buf, sizeof(buf));
261 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
262
263 my_snaps.push_back(-2);
264 librados::AioCompletion *completion = cluster.aio_create_completion();
265 ioctx.aio_selfmanaged_snap_create(&my_snaps.back(), completion);
266 ASSERT_EQ(0, completion->wait_for_complete());
267 completion->release();
268 ::std::reverse(my_snaps.begin(), my_snaps.end());
269 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
270 ::std::reverse(my_snaps.begin(), my_snaps.end());
271 char buf2[sizeof(buf)];
272 memset(buf2, 0xdd, sizeof(buf2));
273 bufferlist bl2;
274 bl2.append(buf2, sizeof(buf2));
275 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), 0));
276
277 ioctx.snap_set_read(my_snaps[1]);
278 bufferlist bl3;
279 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
280 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
281
282 completion = cluster.aio_create_completion();
283 ioctx.aio_selfmanaged_snap_remove(my_snaps.back(), completion);
284 ASSERT_EQ(0, completion->wait_for_complete());
285 completion->release();
286 my_snaps.pop_back();
287 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
288 my_snaps.pop_back();
289 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
290 ASSERT_TRUE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
291 ASSERT_EQ(0, ioctx.remove("foo"));
292 }
293
294 TEST_F(LibRadosSnapshotsSelfManagedPP, RollbackPP) {
295 std::vector<uint64_t> my_snaps;
296 IoCtx readioctx;
297 ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), readioctx));
298 readioctx.set_namespace(nspace);
299 readioctx.snap_set_read(LIBRADOS_SNAP_DIR);
300
301 my_snaps.push_back(-2);
302 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
303 ::std::reverse(my_snaps.begin(), my_snaps.end());
304 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
305 ::std::reverse(my_snaps.begin(), my_snaps.end());
306 char buf[bufsize];
307 memset(buf, 0xcc, sizeof(buf));
308 bufferlist bl1;
309 bl1.append(buf, sizeof(buf));
310 //Write 3 consecutive buffers
311 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
312 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize));
313 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*2));
314
315 snap_set_t ss;
316
317 snap_t head = SNAP_HEAD;
318 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
319 ASSERT_EQ(1u, ss.clones.size());
320 ASSERT_EQ(head, ss.clones[0].cloneid);
321 ASSERT_EQ(0u, ss.clones[0].snaps.size());
322 ASSERT_EQ(0u, ss.clones[0].overlap.size());
323 ASSERT_EQ(384u, ss.clones[0].size);
324
325 my_snaps.push_back(-2);
326 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
327 ::std::reverse(my_snaps.begin(), my_snaps.end());
328 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
329 ::std::reverse(my_snaps.begin(), my_snaps.end());
330 char buf2[sizeof(buf)];
331 memset(buf2, 0xdd, sizeof(buf2));
332 bufferlist bl2;
333 bl2.append(buf2, sizeof(buf2));
334 //Change the middle buffer
335 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize));
336 //Add another after
337 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*3));
338
339 ASSERT_EQ(-EINVAL, ioctx.list_snaps("foo", &ss));
340 ObjectReadOperation o;
341 o.list_snaps(&ss, NULL);
342 ASSERT_EQ(-EINVAL, ioctx.operate("foo", &o, NULL));
343
344 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
345 ASSERT_EQ(2u, ss.clones.size());
346 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
347 ASSERT_EQ(1u, ss.clones[0].snaps.size());
348 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
349 ASSERT_EQ(2u, ss.clones[0].overlap.size());
350 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
351 ASSERT_EQ(128u, ss.clones[0].overlap[0].second);
352 ASSERT_EQ(256u, ss.clones[0].overlap[1].first);
353 ASSERT_EQ(128u, ss.clones[0].overlap[1].second);
354 ASSERT_EQ(384u, ss.clones[0].size);
355 ASSERT_EQ(head, ss.clones[1].cloneid);
356 ASSERT_EQ(0u, ss.clones[1].snaps.size());
357 ASSERT_EQ(0u, ss.clones[1].overlap.size());
358 ASSERT_EQ(512u, ss.clones[1].size);
359
360 ioctx.selfmanaged_snap_rollback("foo", my_snaps[1]);
361
362 bufferlist bl3;
363 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
364 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
365 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), bufsize));
366 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
367 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), bufsize*2));
368 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
369 ASSERT_EQ((int)0, ioctx.read("foo", bl3, sizeof(buf), bufsize*3));
370
371 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
372 my_snaps.pop_back();
373 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
374 my_snaps.pop_back();
375 readioctx.close();
376 }
377
378 TEST_F(LibRadosSnapshotsSelfManagedPP, SnapOverlapPP) {
379 std::vector<uint64_t> my_snaps;
380 IoCtx readioctx;
381 ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), readioctx));
382 readioctx.set_namespace(nspace);
383 readioctx.snap_set_read(LIBRADOS_SNAP_DIR);
384
385 my_snaps.push_back(-2);
386 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
387 ::std::reverse(my_snaps.begin(), my_snaps.end());
388 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
389 ::std::reverse(my_snaps.begin(), my_snaps.end());
390 char buf[bufsize];
391 memset(buf, 0xcc, sizeof(buf));
392 bufferlist bl1;
393 bl1.append(buf, sizeof(buf));
394 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
395 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*2));
396 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*4));
397 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*6));
398 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*8));
399
400 snap_set_t ss;
401 snap_t head = SNAP_HEAD;
402 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
403 ASSERT_EQ(1u, ss.clones.size());
404 ASSERT_EQ(head, ss.clones[0].cloneid);
405 ASSERT_EQ(0u, ss.clones[0].snaps.size());
406 ASSERT_EQ(0u, ss.clones[0].overlap.size());
407 ASSERT_EQ(1152u, ss.clones[0].size);
408
409 my_snaps.push_back(-2);
410 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
411 ::std::reverse(my_snaps.begin(), my_snaps.end());
412 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
413 ::std::reverse(my_snaps.begin(), my_snaps.end());
414 char buf2[sizeof(buf)];
415 memset(buf2, 0xdd, sizeof(buf2));
416 bufferlist bl2;
417 bl2.append(buf2, sizeof(buf2));
418 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*1));
419 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*3));
420 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*5));
421 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*7));
422 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*9));
423
424 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
425 ASSERT_EQ(2u, ss.clones.size());
426 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
427 ASSERT_EQ(1u, ss.clones[0].snaps.size());
428 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
429 ASSERT_EQ(5u, ss.clones[0].overlap.size());
430 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
431 ASSERT_EQ(128u, ss.clones[0].overlap[0].second);
432 ASSERT_EQ(256u, ss.clones[0].overlap[1].first);
433 ASSERT_EQ(128u, ss.clones[0].overlap[1].second);
434 ASSERT_EQ(512u, ss.clones[0].overlap[2].first);
435 ASSERT_EQ(128u, ss.clones[0].overlap[2].second);
436 ASSERT_EQ(768u, ss.clones[0].overlap[3].first);
437 ASSERT_EQ(128u, ss.clones[0].overlap[3].second);
438 ASSERT_EQ(1024u, ss.clones[0].overlap[4].first);
439 ASSERT_EQ(128u, ss.clones[0].overlap[4].second);
440 ASSERT_EQ(1152u, ss.clones[0].size);
441 ASSERT_EQ(head, ss.clones[1].cloneid);
442 ASSERT_EQ(0u, ss.clones[1].snaps.size());
443 ASSERT_EQ(0u, ss.clones[1].overlap.size());
444 ASSERT_EQ(1280u, ss.clones[1].size);
445
446 my_snaps.push_back(-2);
447 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
448 ::std::reverse(my_snaps.begin(), my_snaps.end());
449 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
450 ::std::reverse(my_snaps.begin(), my_snaps.end());
451
452 char buf3[sizeof(buf)];
453 memset(buf3, 0xee, sizeof(buf3));
454 bufferlist bl4;
455 bl4.append(buf3, sizeof(buf3));
456 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*1));
457 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*4));
458 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*5));
459 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*8));
460
461 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
462 ASSERT_EQ(3u, ss.clones.size());
463 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
464 ASSERT_EQ(1u, ss.clones[0].snaps.size());
465 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
466 ASSERT_EQ(5u, ss.clones[0].overlap.size());
467 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
468 ASSERT_EQ(128u, ss.clones[0].overlap[0].second);
469 ASSERT_EQ(256u, ss.clones[0].overlap[1].first);
470 ASSERT_EQ(128u, ss.clones[0].overlap[1].second);
471 ASSERT_EQ(512u, ss.clones[0].overlap[2].first);
472 ASSERT_EQ(128u, ss.clones[0].overlap[2].second);
473 ASSERT_EQ(768u, ss.clones[0].overlap[3].first);
474 ASSERT_EQ(128u, ss.clones[0].overlap[3].second);
475 ASSERT_EQ(1024u, ss.clones[0].overlap[4].first);
476 ASSERT_EQ(128u, ss.clones[0].overlap[4].second);
477 ASSERT_EQ(1152u, ss.clones[0].size);
478
479 ASSERT_EQ(my_snaps[2], ss.clones[1].cloneid);
480 ASSERT_EQ(1u, ss.clones[1].snaps.size());
481 ASSERT_EQ(my_snaps[2], ss.clones[1].snaps[0]);
482 ASSERT_EQ(4u, ss.clones[1].overlap.size());
483 ASSERT_EQ(0u, ss.clones[1].overlap[0].first);
484 ASSERT_EQ(128u, ss.clones[1].overlap[0].second);
485 ASSERT_EQ(256u, ss.clones[1].overlap[1].first);
486 ASSERT_EQ(256u, ss.clones[1].overlap[1].second);
487 ASSERT_EQ(768u, ss.clones[1].overlap[2].first);
488 ASSERT_EQ(256u, ss.clones[1].overlap[2].second);
489 ASSERT_EQ(1152u, ss.clones[1].overlap[3].first);
490 ASSERT_EQ(128u, ss.clones[1].overlap[3].second);
491 ASSERT_EQ(1280u, ss.clones[1].size);
492
493 ASSERT_EQ(head, ss.clones[2].cloneid);
494 ASSERT_EQ(0u, ss.clones[2].snaps.size());
495 ASSERT_EQ(0u, ss.clones[2].overlap.size());
496 ASSERT_EQ(1280u, ss.clones[2].size);
497
498 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
499 my_snaps.pop_back();
500 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
501 my_snaps.pop_back();
502 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
503 my_snaps.pop_back();
504 readioctx.close();
505 }
506
507 TEST_F(LibRadosSnapshotsSelfManagedPP, Bug11677) {
508 std::vector<uint64_t> my_snaps;
509 my_snaps.push_back(-2);
510 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
511 ::std::reverse(my_snaps.begin(), my_snaps.end());
512 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
513 ::std::reverse(my_snaps.begin(), my_snaps.end());
514
515 int bsize = 1<<20;
516 char *buf = (char *)new char[bsize];
517 memset(buf, 0xcc, bsize);
518 bufferlist bl1;
519 bl1.append(buf, bsize);
520 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
521
522 my_snaps.push_back(-2);
523 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
524 ::std::reverse(my_snaps.begin(), my_snaps.end());
525 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
526 ::std::reverse(my_snaps.begin(), my_snaps.end());
527
528 std::unique_ptr<librados::ObjectWriteOperation> op(new librados::ObjectWriteOperation());
529 op->assert_exists();
530 op->remove();
531 ASSERT_EQ(0, ioctx.operate("foo", op.get()));
532
533 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
534 my_snaps.pop_back();
535 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
536 my_snaps.pop_back();
537 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
538 delete[] buf;
539 }
540
541 // EC testing
542 TEST_F(LibRadosSnapshotsEC, SnapList) {
543 char buf[bufsize];
544 memset(buf, 0xcc, sizeof(buf));
545 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
546 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
547 rados_snap_t snaps[10];
548 EXPECT_EQ(1, rados_ioctx_snap_list(ioctx, snaps,
549 sizeof(snaps) / sizeof(snaps[0])));
550 rados_snap_t rid;
551 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
552 EXPECT_EQ(rid, snaps[0]);
553 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
554 }
555
556 TEST_F(LibRadosSnapshotsECPP, SnapListPP) {
557 char buf[bufsize];
558 memset(buf, 0xcc, sizeof(buf));
559 bufferlist bl1;
560 bl1.append(buf, sizeof(buf));
561 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
562 ASSERT_EQ(0, ioctx.snap_create("snap1"));
563 std::vector<snap_t> snaps;
564 EXPECT_EQ(0, ioctx.snap_list(&snaps));
565 EXPECT_EQ(1U, snaps.size());
566 snap_t rid;
567 EXPECT_EQ(0, ioctx.snap_lookup("snap1", &rid));
568 EXPECT_EQ(rid, snaps[0]);
569 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
570 }
571
572 TEST_F(LibRadosSnapshotsEC, SnapRemove) {
573 char buf[bufsize];
574 memset(buf, 0xcc, sizeof(buf));
575 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
576 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
577 rados_snap_t rid;
578 ASSERT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
579 ASSERT_EQ(-EEXIST, rados_ioctx_snap_create(ioctx, "snap1"));
580 ASSERT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
581 ASSERT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
582 }
583
584 TEST_F(LibRadosSnapshotsECPP, SnapRemovePP) {
585 char buf[bufsize];
586 memset(buf, 0xcc, sizeof(buf));
587 bufferlist bl1;
588 bl1.append(buf, sizeof(buf));
589 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
590 ASSERT_EQ(0, ioctx.snap_create("snap1"));
591 rados_snap_t rid;
592 ASSERT_EQ(0, ioctx.snap_lookup("snap1", &rid));
593 ASSERT_EQ(0, ioctx.snap_remove("snap1"));
594 ASSERT_EQ(-ENOENT, ioctx.snap_lookup("snap1", &rid));
595 }
596
597 TEST_F(LibRadosSnapshotsEC, Rollback) {
598 char buf[bufsize];
599 memset(buf, 0xcc, sizeof(buf));
600 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
601 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
602 char buf2[sizeof(buf)];
603 memset(buf2, 0xdd, sizeof(buf2));
604 EXPECT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2)));
605 EXPECT_EQ(0, rados_ioctx_snap_rollback(ioctx, "foo", "snap1"));
606 char buf3[sizeof(buf)];
607 EXPECT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
608 EXPECT_EQ(0, memcmp(buf, buf3, sizeof(buf)));
609 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
610 }
611
612 TEST_F(LibRadosSnapshotsECPP, RollbackPP) {
613 char buf[bufsize];
614 memset(buf, 0xcc, sizeof(buf));
615 bufferlist bl1;
616 bl1.append(buf, sizeof(buf));
617 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
618 ASSERT_EQ(0, ioctx.snap_create("snap1"));
619 char buf2[sizeof(buf)];
620 memset(buf2, 0xdd, sizeof(buf2));
621 bufferlist bl2;
622 bl2.append(buf2, sizeof(buf2));
623 EXPECT_EQ(0, ioctx.write_full("foo", bl2));
624 EXPECT_EQ(0, ioctx.snap_rollback("foo", "snap1"));
625 bufferlist bl3;
626 EXPECT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
627 EXPECT_EQ(0, memcmp(buf, bl3.c_str(), sizeof(buf)));
628 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
629 }
630
631 TEST_F(LibRadosSnapshotsEC, SnapGetName) {
632 char buf[bufsize];
633 memset(buf, 0xcc, sizeof(buf));
634 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
635 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snapfoo"));
636 rados_snap_t rid;
637 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snapfoo", &rid));
638 EXPECT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snapbar", &rid));
639 char name[128];
640 memset(name, 0, sizeof(name));
641 EXPECT_EQ(0, rados_ioctx_snap_get_name(ioctx, rid, name, sizeof(name)));
642 time_t snaptime;
643 EXPECT_EQ(0, rados_ioctx_snap_get_stamp(ioctx, rid, &snaptime));
644 EXPECT_EQ(0, strcmp(name, "snapfoo"));
645 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snapfoo"));
646 }
647
648 TEST_F(LibRadosSnapshotsECPP, SnapGetNamePP) {
649 char buf[bufsize];
650 memset(buf, 0xcc, sizeof(buf));
651 bufferlist bl;
652 bl.append(buf, sizeof(buf));
653 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
654 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
655 rados_snap_t rid;
656 EXPECT_EQ(0, ioctx.snap_lookup("snapfoo", &rid));
657 EXPECT_EQ(-ENOENT, ioctx.snap_lookup("snapbar", &rid));
658 std::string name;
659 EXPECT_EQ(0, ioctx.snap_get_name(rid, &name));
660 time_t snaptime;
661 EXPECT_EQ(0, ioctx.snap_get_stamp(rid, &snaptime));
662 EXPECT_EQ(0, strcmp(name.c_str(), "snapfoo"));
663 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
664 }
665
666 TEST_F(LibRadosSnapshotsSelfManagedEC, Snap) {
667 std::vector<uint64_t> my_snaps;
668 my_snaps.push_back(-2);
669 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
670 ::std::reverse(my_snaps.begin(), my_snaps.end());
671 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
672 &my_snaps[0], my_snaps.size()));
673 ::std::reverse(my_snaps.begin(), my_snaps.end());
674 int bsize = alignment;
675 char *buf = (char *)new char[bsize];
676 memset(buf, 0xcc, bsize);
677 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, bsize, 0));
678
679 my_snaps.push_back(-2);
680 rados_completion_t completion;
681 ASSERT_EQ(0, rados_aio_create_completion(nullptr, nullptr, nullptr,
682 &completion));
683 rados_aio_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back(), completion);
684 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
685 rados_aio_release(completion);
686 ::std::reverse(my_snaps.begin(), my_snaps.end());
687 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
688 &my_snaps[0], my_snaps.size()));
689 ::std::reverse(my_snaps.begin(), my_snaps.end());
690 char *buf2 = (char *)new char[bsize];
691 memset(buf2, 0xdd, bsize);
692 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, bsize, bsize));
693 rados_ioctx_snap_set_read(ioctx, my_snaps[1]-1);
694 char *buf3 = (char *)new char[bsize*2];
695 ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf3, bsize*2, 0));
696
697 rados_ioctx_snap_set_read(ioctx, my_snaps[1]);
698 ASSERT_EQ(bsize, rados_read(ioctx, "foo", buf3, bsize*2, 0));
699 ASSERT_EQ(0, memcmp(buf3, buf, bsize));
700
701 ASSERT_EQ(0, rados_aio_create_completion(nullptr, nullptr, nullptr,
702 &completion));
703 rados_aio_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back(), completion);
704 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
705 rados_aio_release(completion);
706 my_snaps.pop_back();
707 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
708 my_snaps.pop_back();
709 rados_ioctx_snap_set_read(ioctx, LIBRADOS_SNAP_HEAD);
710 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
711 delete[] buf;
712 delete[] buf2;
713 delete[] buf3;
714 }
715
716 TEST_F(LibRadosSnapshotsSelfManagedEC, Rollback) {
717 std::vector<uint64_t> my_snaps;
718 my_snaps.push_back(-2);
719 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
720 ::std::reverse(my_snaps.begin(), my_snaps.end());
721 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
722 &my_snaps[0], my_snaps.size()));
723 ::std::reverse(my_snaps.begin(), my_snaps.end());
724 int bsize = alignment;
725 char *buf = (char *)new char[bsize];
726 memset(buf, 0xcc, bsize);
727 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, bsize, 0));
728
729 my_snaps.push_back(-2);
730 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
731 ::std::reverse(my_snaps.begin(), my_snaps.end());
732 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
733 &my_snaps[0], my_snaps.size()));
734 ::std::reverse(my_snaps.begin(), my_snaps.end());
735 char *buf2 = (char *)new char[bsize];
736 memset(buf2, 0xdd, bsize);
737
738 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, bsize, bsize));
739 rados_ioctx_selfmanaged_snap_rollback(ioctx, "foo", my_snaps[1]);
740 char *buf3 = (char *)new char[bsize*2];
741 ASSERT_EQ(bsize, rados_read(ioctx, "foo", buf3, bsize*2, 0));
742 ASSERT_EQ(0, memcmp(buf3, buf, bsize));
743
744 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
745 my_snaps.pop_back();
746 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
747 my_snaps.pop_back();
748 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
749 delete[] buf;
750 delete[] buf2;
751 delete[] buf3;
752 }
753
754 TEST_F(LibRadosSnapshotsSelfManagedECPP, SnapPP) {
755 std::vector<uint64_t> my_snaps;
756 my_snaps.push_back(-2);
757 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
758 ::std::reverse(my_snaps.begin(), my_snaps.end());
759 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
760 ::std::reverse(my_snaps.begin(), my_snaps.end());
761 int bsize = alignment;
762 char *buf = (char *)new char[bsize];
763 memset(buf, 0xcc, bsize);
764 bufferlist bl1;
765 bl1.append(buf, bsize);
766 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
767
768 my_snaps.push_back(-2);
769 librados::AioCompletion *completion = cluster.aio_create_completion();
770 ioctx.aio_selfmanaged_snap_create(&my_snaps.back(), completion);
771 ASSERT_EQ(0, completion->wait_for_complete());
772 completion->release();
773 ::std::reverse(my_snaps.begin(), my_snaps.end());
774 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
775 ::std::reverse(my_snaps.begin(), my_snaps.end());
776 char *buf2 = (char *)new char[bsize];
777 memset(buf2, 0xdd, bsize);
778 bufferlist bl2;
779 bl2.append(buf2, bsize);
780 // Add another aligned buffer
781 ASSERT_EQ(0, ioctx.write("foo", bl2, bsize, bsize));
782
783 ioctx.snap_set_read(my_snaps[1]);
784 bufferlist bl3;
785 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize*3, 0));
786 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
787
788 completion = cluster.aio_create_completion();
789 ioctx.aio_selfmanaged_snap_remove(my_snaps.back(), completion);
790 ASSERT_EQ(0, completion->wait_for_complete());
791 completion->release();
792 my_snaps.pop_back();
793 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
794 my_snaps.pop_back();
795 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
796 ASSERT_EQ(0, ioctx.remove("foo"));
797 delete[] buf;
798 delete[] buf2;
799 }
800
801 TEST_F(LibRadosSnapshotsSelfManagedECPP, RollbackPP) {
802 std::vector<uint64_t> my_snaps;
803 IoCtx readioctx;
804 ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), readioctx));
805 readioctx.set_namespace(nspace);
806 readioctx.snap_set_read(LIBRADOS_SNAP_DIR);
807
808 my_snaps.push_back(-2);
809 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
810 ::std::reverse(my_snaps.begin(), my_snaps.end());
811 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
812 ::std::reverse(my_snaps.begin(), my_snaps.end());
813 int bsize = alignment;
814 char *buf = (char *)new char[bsize];
815 memset(buf, 0xcc, bsize);
816 bufferlist bl1;
817 bl1.append(buf, bsize);
818 //Write 3 consecutive buffers
819 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
820 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, bsize));
821 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, bsize*2));
822
823 snap_set_t ss;
824
825 snap_t head = SNAP_HEAD;
826 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
827 ASSERT_EQ(1u, ss.clones.size());
828 ASSERT_EQ(head, ss.clones[0].cloneid);
829 ASSERT_EQ(0u, ss.clones[0].snaps.size());
830 ASSERT_EQ(0u, ss.clones[0].overlap.size());
831 ASSERT_EQ((unsigned)(bsize*3), ss.clones[0].size);
832
833 my_snaps.push_back(-2);
834 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
835 ::std::reverse(my_snaps.begin(), my_snaps.end());
836 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
837 ::std::reverse(my_snaps.begin(), my_snaps.end());
838 char *buf2 = (char *)new char[bsize];
839 memset(buf2, 0xdd, bsize);
840 bufferlist bl2;
841 bl2.append(buf2, bsize);
842 //Change the middle buffer
843 //ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize));
844 //Add another after
845 ASSERT_EQ(0, ioctx.write("foo", bl2, bsize, bsize*3));
846
847 ASSERT_EQ(-EINVAL, ioctx.list_snaps("foo", &ss));
848 ObjectReadOperation o;
849 o.list_snaps(&ss, NULL);
850 ASSERT_EQ(-EINVAL, ioctx.operate("foo", &o, NULL));
851
852 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
853 ASSERT_EQ(2u, ss.clones.size());
854 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
855 ASSERT_EQ(1u, ss.clones[0].snaps.size());
856 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
857 ASSERT_EQ(1u, ss.clones[0].overlap.size());
858 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
859 ASSERT_EQ((unsigned)bsize*3, ss.clones[0].overlap[0].second);
860 ASSERT_EQ((unsigned)bsize*3, ss.clones[0].size);
861 ASSERT_EQ(head, ss.clones[1].cloneid);
862 ASSERT_EQ(0u, ss.clones[1].snaps.size());
863 ASSERT_EQ(0u, ss.clones[1].overlap.size());
864 ASSERT_EQ((unsigned)bsize*4, ss.clones[1].size);
865
866 ioctx.selfmanaged_snap_rollback("foo", my_snaps[1]);
867
868 bufferlist bl3;
869 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize, 0));
870 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
871 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize, bsize));
872 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
873 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize, bsize*2));
874 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
875 ASSERT_EQ(0, ioctx.read("foo", bl3, bsize, bsize*3));
876
877 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
878 my_snaps.pop_back();
879 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
880 my_snaps.pop_back();
881 readioctx.close();
882
883 delete[] buf;
884 delete[] buf2;
885 }
886
887 TEST_F(LibRadosSnapshotsSelfManagedECPP, Bug11677) {
888 std::vector<uint64_t> my_snaps;
889 my_snaps.push_back(-2);
890 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
891 ::std::reverse(my_snaps.begin(), my_snaps.end());
892 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
893 ::std::reverse(my_snaps.begin(), my_snaps.end());
894
895 int bsize = alignment;
896 char *buf = (char *)new char[bsize];
897 memset(buf, 0xcc, bsize);
898 bufferlist bl1;
899 bl1.append(buf, bsize);
900 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
901
902 my_snaps.push_back(-2);
903 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
904 ::std::reverse(my_snaps.begin(), my_snaps.end());
905 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
906 ::std::reverse(my_snaps.begin(), my_snaps.end());
907
908 std::unique_ptr<librados::ObjectWriteOperation> op(new librados::ObjectWriteOperation());
909 op->assert_exists();
910 op->remove();
911 ASSERT_EQ(0, ioctx.operate("foo", op.get()));
912
913 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
914 my_snaps.pop_back();
915 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
916 my_snaps.pop_back();
917 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
918 delete[] buf;
919 }
920