1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/ceph_context.h"
5 #include "common/config.h"
6 #include "common/snap_types.h"
7 #include "common/Clock.h"
8 #include "include/encoding.h"
9 #include "include/types.h"
10 #include "include/rados/librados.h"
11 #include "include/rbd/object_map_types.h"
12 #include "include/rbd_types.h"
13 #include "include/stringify.h"
14 #include "cls/rbd/cls_rbd.h"
15 #include "cls/rbd/cls_rbd_client.h"
16 #include "cls/rbd/cls_rbd_types.h"
18 #include "gtest/gtest.h"
19 #include "test/librados/test.h"
26 using namespace librbd::cls_client
;
27 using ::librbd::ParentInfo
;
28 using ::librbd::ParentSpec
;
30 static int snapshot_add(librados::IoCtx
*ioctx
, const std::string
&oid
,
31 uint64_t snap_id
, const std::string
&snap_name
) {
32 librados::ObjectWriteOperation op
;
33 ::librbd::cls_client::snapshot_add(&op
, snap_id
, snap_name
, cls::rbd::UserSnapshotNamespace());
34 return ioctx
->operate(oid
, &op
);
37 static int snapshot_remove(librados::IoCtx
*ioctx
, const std::string
&oid
,
39 librados::ObjectWriteOperation op
;
40 ::librbd::cls_client::snapshot_remove(&op
, snap_id
);
41 return ioctx
->operate(oid
, &op
);
44 static int snapshot_rename(librados::IoCtx
*ioctx
, const std::string
&oid
,
45 uint64_t snap_id
, const std::string
&snap_name
) {
46 librados::ObjectWriteOperation op
;
47 ::librbd::cls_client::snapshot_rename(&op
, snap_id
, snap_name
);
48 return ioctx
->operate(oid
, &op
);
51 static int old_snapshot_add(librados::IoCtx
*ioctx
, const std::string
&oid
,
52 uint64_t snap_id
, const std::string
&snap_name
) {
53 librados::ObjectWriteOperation op
;
54 ::librbd::cls_client::old_snapshot_add(&op
, snap_id
, snap_name
);
55 return ioctx
->operate(oid
, &op
);
58 static char *random_buf(size_t len
)
60 char *b
= new char[len
];
61 for (size_t i
= 0; i
< len
; i
++)
62 b
[i
] = (rand() % (128 - 32)) + 32;
66 class TestClsRbd
: public ::testing::Test
{
69 static void SetUpTestCase() {
70 _pool_name
= get_temp_pool_name();
71 ASSERT_EQ("", create_one_pool_pp(_pool_name
, _rados
));
74 static void TearDownTestCase() {
75 ASSERT_EQ(0, destroy_one_pool_pp(_pool_name
, _rados
));
78 std::string
get_temp_image_name() {
80 return "image" + stringify(_image_number
);
83 static std::string _pool_name
;
84 static librados::Rados _rados
;
85 static uint64_t _image_number
;
89 std::string
TestClsRbd::_pool_name
;
90 librados::Rados
TestClsRbd::_rados
;
91 uint64_t TestClsRbd::_image_number
= 0;
93 TEST_F(TestClsRbd
, get_all_features
)
95 librados::IoCtx ioctx
;
96 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
98 string oid
= get_temp_image_name();
99 ASSERT_EQ(0, ioctx
.create(oid
, false));
101 uint64_t all_features
= 0;
102 ASSERT_EQ(0, get_all_features(&ioctx
, oid
, &all_features
));
103 ASSERT_EQ(RBD_FEATURES_ALL
, all_features
);
108 TEST_F(TestClsRbd
, copyup
)
110 librados::IoCtx ioctx
;
111 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
113 string oid
= get_temp_image_name();
114 bufferlist inbl
, outbl
;
116 // copyup of 0-len nonexistent object should create new 0-len object
118 ASSERT_EQ(0, copyup(&ioctx
, oid
, inbl
));
120 ASSERT_EQ(0, ioctx
.stat(oid
, &size
, NULL
));
123 // create some random data to write
125 char *b
= random_buf(l
);
128 ASSERT_EQ(l
, inbl
.length());
130 // copyup to nonexistent object should create new object
132 ASSERT_EQ(-ENOENT
, ioctx
.remove(oid
));
133 ASSERT_EQ(0, copyup(&ioctx
, oid
, inbl
));
134 // and its contents should match
135 ASSERT_EQ(l
, (size_t)ioctx
.read(oid
, outbl
, l
, 0));
136 ASSERT_TRUE(outbl
.contents_equal(inbl
));
138 // now send different data, but with a preexisting object
143 ASSERT_EQ(l
, inbl2
.length());
145 // should still succeed
146 ASSERT_EQ(0, copyup(&ioctx
, oid
, inbl
));
147 ASSERT_EQ(l
, (size_t)ioctx
.read(oid
, outbl
, l
, 0));
148 // but contents should not have changed
149 ASSERT_FALSE(outbl
.contents_equal(inbl2
));
150 ASSERT_TRUE(outbl
.contents_equal(inbl
));
152 ASSERT_EQ(0, ioctx
.remove(oid
));
156 TEST_F(TestClsRbd
, get_and_set_id
)
158 librados::IoCtx ioctx
;
159 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
161 string oid
= get_temp_image_name();
163 string valid_id
= "0123abcxyzZYXCBA";
164 string invalid_id
= ".abc";
167 ASSERT_EQ(-ENOENT
, get_id(&ioctx
, oid
, &id
));
168 ASSERT_EQ(-ENOENT
, set_id(&ioctx
, oid
, valid_id
));
170 ASSERT_EQ(0, ioctx
.create(oid
, true));
171 ASSERT_EQ(-EINVAL
, set_id(&ioctx
, oid
, invalid_id
));
172 ASSERT_EQ(-EINVAL
, set_id(&ioctx
, oid
, empty_id
));
173 ASSERT_EQ(-ENOENT
, get_id(&ioctx
, oid
, &id
));
175 ASSERT_EQ(0, set_id(&ioctx
, oid
, valid_id
));
176 ASSERT_EQ(-EEXIST
, set_id(&ioctx
, oid
, valid_id
));
177 ASSERT_EQ(-EEXIST
, set_id(&ioctx
, oid
, valid_id
+ valid_id
));
178 ASSERT_EQ(0, get_id(&ioctx
, oid
, &id
));
179 ASSERT_EQ(id
, valid_id
);
184 TEST_F(TestClsRbd
, add_remove_child
)
186 librados::IoCtx ioctx
;
187 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
189 string oid
= get_temp_image_name();
190 ASSERT_EQ(0, ioctx
.create(oid
, true));
192 string snapname
= "parent_snap";
194 string parent_image
= "parent_id";
196 ParentSpec
pspec(ioctx
.get_id(), parent_image
, snapid
);
198 // nonexistent children cannot be listed or removed
199 ASSERT_EQ(-ENOENT
, get_children(&ioctx
, oid
, pspec
, children
));
200 ASSERT_EQ(-ENOENT
, remove_child(&ioctx
, oid
, pspec
, "child1"));
202 // create the parent and snapshot
203 ASSERT_EQ(0, create_image(&ioctx
, parent_image
, 2<<20, 0,
204 RBD_FEATURE_LAYERING
, parent_image
, -1));
205 ASSERT_EQ(0, snapshot_add(&ioctx
, parent_image
, snapid
, snapname
));
207 // add child to it, verify it showed up
208 ASSERT_EQ(0, add_child(&ioctx
, oid
, pspec
, "child1"));
209 ASSERT_EQ(0, get_children(&ioctx
, oid
, pspec
, children
));
210 ASSERT_TRUE(children
.find("child1") != children
.end());
211 // add another child to it, verify it showed up
212 ASSERT_EQ(0, add_child(&ioctx
, oid
, pspec
, "child2"));
213 ASSERT_EQ(0, get_children(&ioctx
, oid
, pspec
, children
));
214 ASSERT_TRUE(children
.find("child2") != children
.end());
215 // add child2 again, expect -EEXIST
216 ASSERT_EQ(-EEXIST
, add_child(&ioctx
, oid
, pspec
, "child2"));
217 // remove first, verify it's gone
218 ASSERT_EQ(0, remove_child(&ioctx
, oid
, pspec
, "child1"));
219 ASSERT_EQ(0, get_children(&ioctx
, oid
, pspec
, children
));
220 ASSERT_FALSE(children
.find("child1") != children
.end());
221 // remove second, verify list empty
222 ASSERT_EQ(0, remove_child(&ioctx
, oid
, pspec
, "child2"));
223 ASSERT_EQ(-ENOENT
, get_children(&ioctx
, oid
, pspec
, children
));
224 // try to remove again, validate -ENOENT to that as well
225 ASSERT_EQ(-ENOENT
, remove_child(&ioctx
, oid
, pspec
, "child2"));
230 TEST_F(TestClsRbd
, directory_methods
)
232 librados::IoCtx ioctx
;
233 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
235 string oid
= get_temp_image_name();
237 string imgname
= get_temp_image_name();
238 string imgname2
= get_temp_image_name();
239 string imgname3
= get_temp_image_name();
240 string valid_id
= "0123abcxyzZYXCBA";
241 string valid_id2
= "5";
242 string invalid_id
= ".abc";
245 ASSERT_EQ(-ENOENT
, dir_get_id(&ioctx
, oid
, imgname
, &id
));
246 ASSERT_EQ(-ENOENT
, dir_get_name(&ioctx
, oid
, valid_id
, &name
));
247 ASSERT_EQ(-ENOENT
, dir_remove_image(&ioctx
, oid
, imgname
, valid_id
));
249 ASSERT_EQ(-EINVAL
, dir_add_image(&ioctx
, oid
, imgname
, invalid_id
));
250 ASSERT_EQ(-EINVAL
, dir_add_image(&ioctx
, oid
, imgname
, empty
));
251 ASSERT_EQ(-EINVAL
, dir_add_image(&ioctx
, oid
, empty
, valid_id
));
253 map
<string
, string
> images
;
254 ASSERT_EQ(-ENOENT
, dir_list(&ioctx
, oid
, "", 30, &images
));
256 ASSERT_EQ(0, ioctx
.create(oid
, true));
257 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 30, &images
));
258 ASSERT_EQ(0u, images
.size());
259 ASSERT_EQ(0, ioctx
.remove(oid
));
261 ASSERT_EQ(0, dir_add_image(&ioctx
, oid
, imgname
, valid_id
));
262 ASSERT_EQ(-EEXIST
, dir_add_image(&ioctx
, oid
, imgname
, valid_id2
));
263 ASSERT_EQ(-EBADF
, dir_add_image(&ioctx
, oid
, imgname2
, valid_id
));
264 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 30, &images
));
265 ASSERT_EQ(1u, images
.size());
266 ASSERT_EQ(valid_id
, images
[imgname
]);
267 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 0, &images
));
268 ASSERT_EQ(0u, images
.size());
269 ASSERT_EQ(0, dir_get_name(&ioctx
, oid
, valid_id
, &name
));
270 ASSERT_EQ(imgname
, name
);
271 ASSERT_EQ(0, dir_get_id(&ioctx
, oid
, imgname
, &id
));
272 ASSERT_EQ(valid_id
, id
);
274 ASSERT_EQ(0, dir_add_image(&ioctx
, oid
, imgname2
, valid_id2
));
275 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 30, &images
));
276 ASSERT_EQ(2u, images
.size());
277 ASSERT_EQ(valid_id
, images
[imgname
]);
278 ASSERT_EQ(valid_id2
, images
[imgname2
]);
279 ASSERT_EQ(0, dir_list(&ioctx
, oid
, imgname
, 0, &images
));
280 ASSERT_EQ(0u, images
.size());
281 ASSERT_EQ(0, dir_list(&ioctx
, oid
, imgname
, 2, &images
));
282 ASSERT_EQ(1u, images
.size());
283 ASSERT_EQ(valid_id2
, images
[imgname2
]);
284 ASSERT_EQ(0, dir_get_name(&ioctx
, oid
, valid_id2
, &name
));
285 ASSERT_EQ(imgname2
, name
);
286 ASSERT_EQ(0, dir_get_id(&ioctx
, oid
, imgname2
, &id
));
287 ASSERT_EQ(valid_id2
, id
);
289 librados::ObjectWriteOperation op1
;
290 dir_rename_image(&op1
, imgname
, imgname2
, valid_id2
);
291 ASSERT_EQ(-ESTALE
, ioctx
.operate(oid
, &op1
));
292 ASSERT_EQ(-ESTALE
, dir_remove_image(&ioctx
, oid
, imgname
, valid_id2
));
293 librados::ObjectWriteOperation op2
;
294 dir_rename_image(&op2
, imgname
, imgname2
, valid_id
);
295 ASSERT_EQ(-EEXIST
, ioctx
.operate(oid
, &op2
));
296 ASSERT_EQ(0, dir_get_id(&ioctx
, oid
, imgname
, &id
));
297 ASSERT_EQ(valid_id
, id
);
298 ASSERT_EQ(0, dir_get_name(&ioctx
, oid
, valid_id2
, &name
));
299 ASSERT_EQ(imgname2
, name
);
301 librados::ObjectWriteOperation op3
;
302 dir_rename_image(&op3
, imgname
, imgname3
, valid_id
);
303 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
304 ASSERT_EQ(0, dir_get_id(&ioctx
, oid
, imgname3
, &id
));
305 ASSERT_EQ(valid_id
, id
);
306 ASSERT_EQ(0, dir_get_name(&ioctx
, oid
, valid_id
, &name
));
307 ASSERT_EQ(imgname3
, name
);
308 librados::ObjectWriteOperation op4
;
309 dir_rename_image(&op4
, imgname3
, imgname
, valid_id
);
310 ASSERT_EQ(0, ioctx
.operate(oid
, &op4
));
312 ASSERT_EQ(0, dir_remove_image(&ioctx
, oid
, imgname
, valid_id
));
313 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 30, &images
));
314 ASSERT_EQ(1u, images
.size());
315 ASSERT_EQ(valid_id2
, images
[imgname2
]);
316 ASSERT_EQ(0, dir_list(&ioctx
, oid
, imgname2
, 30, &images
));
317 ASSERT_EQ(0u, images
.size());
318 ASSERT_EQ(0, dir_get_name(&ioctx
, oid
, valid_id2
, &name
));
319 ASSERT_EQ(imgname2
, name
);
320 ASSERT_EQ(0, dir_get_id(&ioctx
, oid
, imgname2
, &id
));
321 ASSERT_EQ(valid_id2
, id
);
322 ASSERT_EQ(-ENOENT
, dir_get_name(&ioctx
, oid
, valid_id
, &name
));
323 ASSERT_EQ(-ENOENT
, dir_get_id(&ioctx
, oid
, imgname
, &id
));
325 ASSERT_EQ(0, dir_add_image(&ioctx
, oid
, imgname
, valid_id
));
326 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 30, &images
));
327 ASSERT_EQ(2u, images
.size());
328 ASSERT_EQ(valid_id
, images
[imgname
]);
329 ASSERT_EQ(valid_id2
, images
[imgname2
]);
330 ASSERT_EQ(0, dir_remove_image(&ioctx
, oid
, imgname
, valid_id
));
331 ASSERT_EQ(-ENOENT
, dir_remove_image(&ioctx
, oid
, imgname
, valid_id
));
332 ASSERT_EQ(0, dir_remove_image(&ioctx
, oid
, imgname2
, valid_id2
));
333 ASSERT_EQ(0, dir_list(&ioctx
, oid
, "", 30, &images
));
334 ASSERT_EQ(0u, images
.size());
339 TEST_F(TestClsRbd
, create
)
341 librados::IoCtx ioctx
;
342 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
344 string oid
= get_temp_image_name();
345 uint64_t size
= 20ULL << 30;
346 uint64_t features
= 0;
348 string object_prefix
= oid
;
350 ASSERT_EQ(0, create_image(&ioctx
, oid
, size
, order
,
351 features
, object_prefix
, -1));
352 ASSERT_EQ(-EEXIST
, create_image(&ioctx
, oid
, size
, order
,
353 features
, object_prefix
, -1));
354 ASSERT_EQ(0, ioctx
.remove(oid
));
356 ASSERT_EQ(-EINVAL
, create_image(&ioctx
, oid
, size
, order
,
358 ASSERT_EQ(-ENOENT
, ioctx
.remove(oid
));
360 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, order
,
361 features
, object_prefix
, -1));
362 ASSERT_EQ(0, ioctx
.remove(oid
));
364 ASSERT_EQ(-ENOSYS
, create_image(&ioctx
, oid
, size
, order
,
365 -1, object_prefix
, -1));
366 ASSERT_EQ(-ENOENT
, ioctx
.remove(oid
));
368 ASSERT_EQ(0, create_image(&ioctx
, oid
, size
, order
, RBD_FEATURE_DATA_POOL
,
369 object_prefix
, 123));
370 ASSERT_EQ(0, ioctx
.remove(oid
));
371 ASSERT_EQ(-EINVAL
, create_image(&ioctx
, oid
, size
, order
,
372 RBD_FEATURE_DATA_POOL
, object_prefix
, -1));
373 ASSERT_EQ(-EINVAL
, create_image(&ioctx
, oid
, size
, order
, 0, object_prefix
,
376 bufferlist inbl
, outbl
;
377 ASSERT_EQ(-EINVAL
, ioctx
.exec(oid
, "rbd", "create", inbl
, outbl
));
382 TEST_F(TestClsRbd
, get_features
)
384 librados::IoCtx ioctx
;
385 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
387 string oid
= get_temp_image_name();
390 ASSERT_EQ(-ENOENT
, get_features(&ioctx
, oid
, CEPH_NOSNAP
, &features
));
392 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
393 ASSERT_EQ(0, get_features(&ioctx
, oid
, CEPH_NOSNAP
, &features
));
394 ASSERT_EQ(0u, features
);
396 int r
= get_features(&ioctx
, oid
, 1, &features
);
398 ASSERT_EQ(0u, features
);
400 // deprecated snapshot handling
401 ASSERT_EQ(-ENOENT
, r
);
407 TEST_F(TestClsRbd
, get_object_prefix
)
409 librados::IoCtx ioctx
;
410 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
412 string oid
= get_temp_image_name();
414 string object_prefix
;
415 ASSERT_EQ(-ENOENT
, get_object_prefix(&ioctx
, oid
, &object_prefix
));
417 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
418 ASSERT_EQ(0, get_object_prefix(&ioctx
, oid
, &object_prefix
));
419 ASSERT_EQ(oid
, object_prefix
);
424 TEST_F(TestClsRbd
, get_create_timestamp
)
426 librados::IoCtx ioctx
;
427 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
429 string oid
= get_temp_image_name();
430 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
433 ASSERT_EQ(0, get_create_timestamp(&ioctx
, oid
, ×tamp
));
434 ASSERT_LT(0U, timestamp
.tv
.tv_sec
);
439 TEST_F(TestClsRbd
, get_data_pool
)
441 librados::IoCtx ioctx
;
442 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
444 string oid
= get_temp_image_name();
446 int64_t data_pool_id
;
447 ASSERT_EQ(0, ioctx
.create(oid
, true));
448 ASSERT_EQ(0, get_data_pool(&ioctx
, oid
, &data_pool_id
));
449 ASSERT_EQ(-1, data_pool_id
);
450 ASSERT_EQ(0, ioctx
.remove(oid
));
452 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, RBD_FEATURE_DATA_POOL
, oid
,
454 ASSERT_EQ(0, get_data_pool(&ioctx
, oid
, &data_pool_id
));
455 ASSERT_EQ(12, data_pool_id
);
458 TEST_F(TestClsRbd
, get_size
)
460 librados::IoCtx ioctx
;
461 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
463 string oid
= get_temp_image_name();
466 ASSERT_EQ(-ENOENT
, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
468 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
469 ASSERT_EQ(0, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
471 ASSERT_EQ(22, order
);
472 ASSERT_EQ(0, ioctx
.remove(oid
));
474 ASSERT_EQ(0, create_image(&ioctx
, oid
, 2 << 22, 0, 0, oid
, -1));
475 ASSERT_EQ(0, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
476 ASSERT_EQ(2u << 22, size
);
479 ASSERT_EQ(-ENOENT
, get_size(&ioctx
, oid
, 1, &size
, &order
));
484 TEST_F(TestClsRbd
, set_size
)
486 librados::IoCtx ioctx
;
487 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
489 string oid
= get_temp_image_name();
490 ASSERT_EQ(-ENOENT
, set_size(&ioctx
, oid
, 5));
494 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
495 ASSERT_EQ(0, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
497 ASSERT_EQ(22, order
);
499 ASSERT_EQ(0, set_size(&ioctx
, oid
, 0));
500 ASSERT_EQ(0, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
502 ASSERT_EQ(22, order
);
504 ASSERT_EQ(0, set_size(&ioctx
, oid
, 3 << 22));
505 ASSERT_EQ(0, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
506 ASSERT_EQ(3u << 22, size
);
507 ASSERT_EQ(22, order
);
512 TEST_F(TestClsRbd
, protection_status
)
514 librados::IoCtx ioctx
;
515 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
517 string oid
= get_temp_image_name();
518 string oid2
= get_temp_image_name();
519 uint8_t status
= RBD_PROTECTION_STATUS_UNPROTECTED
;
520 ASSERT_EQ(-ENOENT
, get_protection_status(&ioctx
, oid
,
521 CEPH_NOSNAP
, &status
));
522 ASSERT_EQ(-ENOENT
, set_protection_status(&ioctx
, oid
,
523 CEPH_NOSNAP
, status
));
525 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, RBD_FEATURE_LAYERING
, oid
, -1));
526 ASSERT_EQ(0, create_image(&ioctx
, oid2
, 0, 22, 0, oid
, -1));
527 ASSERT_EQ(-EINVAL
, get_protection_status(&ioctx
, oid2
,
528 CEPH_NOSNAP
, &status
));
529 ASSERT_EQ(-ENOEXEC
, set_protection_status(&ioctx
, oid2
,
530 CEPH_NOSNAP
, status
));
531 ASSERT_EQ(-EINVAL
, get_protection_status(&ioctx
, oid
,
532 CEPH_NOSNAP
, &status
));
533 ASSERT_EQ(-EINVAL
, set_protection_status(&ioctx
, oid
,
534 CEPH_NOSNAP
, status
));
535 ASSERT_EQ(-ENOENT
, get_protection_status(&ioctx
, oid
,
537 ASSERT_EQ(-ENOENT
, set_protection_status(&ioctx
, oid
,
540 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 10, "snap1"));
541 ASSERT_EQ(0, get_protection_status(&ioctx
, oid
,
543 ASSERT_EQ(+RBD_PROTECTION_STATUS_UNPROTECTED
, status
);
545 ASSERT_EQ(0, set_protection_status(&ioctx
, oid
,
546 10, RBD_PROTECTION_STATUS_PROTECTED
));
547 ASSERT_EQ(0, get_protection_status(&ioctx
, oid
,
549 ASSERT_EQ(+RBD_PROTECTION_STATUS_PROTECTED
, status
);
550 ASSERT_EQ(-EBUSY
, snapshot_remove(&ioctx
, oid
, 10));
552 ASSERT_EQ(0, set_protection_status(&ioctx
, oid
,
553 10, RBD_PROTECTION_STATUS_UNPROTECTING
));
554 ASSERT_EQ(0, get_protection_status(&ioctx
, oid
,
556 ASSERT_EQ(+RBD_PROTECTION_STATUS_UNPROTECTING
, status
);
557 ASSERT_EQ(-EBUSY
, snapshot_remove(&ioctx
, oid
, 10));
559 ASSERT_EQ(-EINVAL
, set_protection_status(&ioctx
, oid
,
560 10, RBD_PROTECTION_STATUS_LAST
));
561 ASSERT_EQ(0, get_protection_status(&ioctx
, oid
,
563 ASSERT_EQ(+RBD_PROTECTION_STATUS_UNPROTECTING
, status
);
565 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 20, "snap2"));
566 ASSERT_EQ(0, get_protection_status(&ioctx
, oid
,
568 ASSERT_EQ(+RBD_PROTECTION_STATUS_UNPROTECTED
, status
);
569 ASSERT_EQ(0, set_protection_status(&ioctx
, oid
,
570 10, RBD_PROTECTION_STATUS_UNPROTECTED
));
571 ASSERT_EQ(0, get_protection_status(&ioctx
, oid
,
573 ASSERT_EQ(+RBD_PROTECTION_STATUS_UNPROTECTED
, status
);
575 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, 10));
576 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, 20));
581 TEST_F(TestClsRbd
, snapshot_limits
)
583 librados::IoCtx ioctx
;
584 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
586 librados::ObjectWriteOperation op
;
587 string oid
= get_temp_image_name();
590 ASSERT_EQ(-ENOENT
, snapshot_get_limit(&ioctx
, oid
, &limit
));
592 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, RBD_FEATURE_LAYERING
, oid
, -1));
594 snapshot_set_limit(&op
, 2);
596 ASSERT_EQ(0, ioctx
.operate(oid
, &op
));
598 ASSERT_EQ(0, snapshot_get_limit(&ioctx
, oid
, &limit
));
599 ASSERT_EQ(2U, limit
);
601 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 10, "snap1"));
602 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 20, "snap2"));
603 ASSERT_EQ(-EDQUOT
, snapshot_add(&ioctx
, oid
, 30, "snap3"));
605 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, 10));
606 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, 20));
611 TEST_F(TestClsRbd
, parents
)
613 librados::IoCtx ioctx
;
614 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
616 string oid
= get_temp_image_name();
620 ASSERT_EQ(-ENOENT
, get_parent(&ioctx
, "doesnotexist", CEPH_NOSNAP
, &pspec
, &size
));
622 // old image should fail
623 ASSERT_EQ(0, create_image(&ioctx
, "old", 33<<20, 22, 0, "old_blk.", -1));
624 // get nonexistent parent: succeed, return (-1, "", CEPH_NOSNAP), overlap 0
625 ASSERT_EQ(0, get_parent(&ioctx
, "old", CEPH_NOSNAP
, &pspec
, &size
));
626 ASSERT_EQ(pspec
.pool_id
, -1);
627 ASSERT_STREQ("", pspec
.image_id
.c_str());
628 ASSERT_EQ(pspec
.snap_id
, CEPH_NOSNAP
);
629 ASSERT_EQ(size
, 0ULL);
630 pspec
= ParentSpec(-1, "parent", 3);
631 ASSERT_EQ(-ENOEXEC
, set_parent(&ioctx
, "old", ParentSpec(-1, "parent", 3), 10<<20));
632 ASSERT_EQ(-ENOEXEC
, remove_parent(&ioctx
, "old"));
634 // new image will work
635 ASSERT_EQ(0, create_image(&ioctx
, oid
, 33<<20, 22, RBD_FEATURE_LAYERING
,
638 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
639 ASSERT_EQ(-1, pspec
.pool_id
);
640 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 123, &pspec
, &size
));
641 ASSERT_EQ(-1, pspec
.pool_id
);
643 ASSERT_EQ(-EINVAL
, set_parent(&ioctx
, oid
, ParentSpec(-1, "parent", 3), 10<<20));
644 ASSERT_EQ(-EINVAL
, set_parent(&ioctx
, oid
, ParentSpec(1, "", 3), 10<<20));
645 ASSERT_EQ(-EINVAL
, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", CEPH_NOSNAP
), 10<<20));
646 ASSERT_EQ(-EINVAL
, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", 3), 0));
648 pspec
= ParentSpec(1, "parent", 3);
649 ASSERT_EQ(0, set_parent(&ioctx
, oid
, pspec
, 10<<20));
650 ASSERT_EQ(-EEXIST
, set_parent(&ioctx
, oid
, pspec
, 10<<20));
651 ASSERT_EQ(-EEXIST
, set_parent(&ioctx
, oid
, ParentSpec(2, "parent", 34), 10<<20));
653 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
654 ASSERT_EQ(pspec
.pool_id
, 1);
655 ASSERT_EQ(pspec
.image_id
, "parent");
656 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
658 ASSERT_EQ(0, remove_parent(&ioctx
, oid
));
659 ASSERT_EQ(-ENOENT
, remove_parent(&ioctx
, oid
));
660 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
661 ASSERT_EQ(-1, pspec
.pool_id
);
664 ASSERT_EQ(0, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", 3), 10<<20));
665 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 10, "snap1"));
666 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 10, &pspec
, &size
));
667 ASSERT_EQ(pspec
.pool_id
, 1);
668 ASSERT_EQ(pspec
.image_id
, "parent");
669 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
670 ASSERT_EQ(size
, 10ull<<20);
672 ASSERT_EQ(0, remove_parent(&ioctx
, oid
));
673 ASSERT_EQ(0, set_parent(&ioctx
, oid
, ParentSpec(4, "parent2", 6), 5<<20));
674 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 11, "snap2"));
675 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 10, &pspec
, &size
));
676 ASSERT_EQ(pspec
.pool_id
, 1);
677 ASSERT_EQ(pspec
.image_id
, "parent");
678 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
679 ASSERT_EQ(size
, 10ull<<20);
680 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 11, &pspec
, &size
));
681 ASSERT_EQ(pspec
.pool_id
, 4);
682 ASSERT_EQ(pspec
.image_id
, "parent2");
683 ASSERT_EQ(pspec
.snap_id
, snapid_t(6));
684 ASSERT_EQ(size
, 5ull<<20);
686 ASSERT_EQ(0, remove_parent(&ioctx
, oid
));
687 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 12, "snap3"));
688 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 10, &pspec
, &size
));
689 ASSERT_EQ(pspec
.pool_id
, 1);
690 ASSERT_EQ(pspec
.image_id
, "parent");
691 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
692 ASSERT_EQ(size
, 10ull<<20);
693 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 11, &pspec
, &size
));
694 ASSERT_EQ(pspec
.pool_id
, 4);
695 ASSERT_EQ(pspec
.image_id
, "parent2");
696 ASSERT_EQ(pspec
.snap_id
, snapid_t(6));
697 ASSERT_EQ(size
, 5ull<<20);
698 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 12, &pspec
, &size
));
699 ASSERT_EQ(-1, pspec
.pool_id
);
701 // make sure set_parent takes min of our size and parent's size
702 ASSERT_EQ(0, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", 3), 1<<20));
703 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
704 ASSERT_EQ(pspec
.pool_id
, 1);
705 ASSERT_EQ(pspec
.image_id
, "parent");
706 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
707 ASSERT_EQ(size
, 1ull<<20);
708 ASSERT_EQ(0, remove_parent(&ioctx
, oid
));
710 ASSERT_EQ(0, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", 3), 100<<20));
711 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
712 ASSERT_EQ(pspec
.pool_id
, 1);
713 ASSERT_EQ(pspec
.image_id
, "parent");
714 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
715 ASSERT_EQ(size
, 33ull<<20);
716 ASSERT_EQ(0, remove_parent(&ioctx
, oid
));
718 // make sure resize adjust parent overlap
719 ASSERT_EQ(0, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", 3), 10<<20));
721 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 14, "snap4"));
722 ASSERT_EQ(0, set_size(&ioctx
, oid
, 3 << 20));
723 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
724 ASSERT_EQ(pspec
.pool_id
, 1);
725 ASSERT_EQ(pspec
.image_id
, "parent");
726 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
727 ASSERT_EQ(size
, 3ull<<20);
728 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 14, &pspec
, &size
));
729 ASSERT_EQ(pspec
.pool_id
, 1);
730 ASSERT_EQ(pspec
.image_id
, "parent");
731 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
732 ASSERT_EQ(size
, 10ull<<20);
734 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 15, "snap5"));
735 ASSERT_EQ(0, set_size(&ioctx
, oid
, 30 << 20));
736 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
737 ASSERT_EQ(pspec
.pool_id
, 1);
738 ASSERT_EQ(pspec
.image_id
, "parent");
739 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
740 ASSERT_EQ(size
, 3ull<<20);
741 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 14, &pspec
, &size
));
742 ASSERT_EQ(pspec
.pool_id
, 1);
743 ASSERT_EQ(pspec
.image_id
, "parent");
744 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
745 ASSERT_EQ(size
, 10ull<<20);
746 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 15, &pspec
, &size
));
747 ASSERT_EQ(pspec
.pool_id
, 1);
748 ASSERT_EQ(pspec
.image_id
, "parent");
749 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
750 ASSERT_EQ(size
, 3ull<<20);
752 ASSERT_EQ(0, set_size(&ioctx
, oid
, 2 << 20));
753 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
754 ASSERT_EQ(pspec
.pool_id
, 1);
755 ASSERT_EQ(pspec
.image_id
, "parent");
756 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
757 ASSERT_EQ(size
, 2ull<<20);
759 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 16, "snap6"));
760 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 16, &pspec
, &size
));
761 ASSERT_EQ(pspec
.pool_id
, 1);
762 ASSERT_EQ(pspec
.image_id
, "parent");
763 ASSERT_EQ(pspec
.snap_id
, snapid_t(3));
764 ASSERT_EQ(size
, 2ull<<20);
766 ASSERT_EQ(0, ioctx
.remove(oid
));
767 ASSERT_EQ(0, create_image(&ioctx
, oid
, 33<<20, 22,
768 RBD_FEATURE_LAYERING
| RBD_FEATURE_DEEP_FLATTEN
,
770 ASSERT_EQ(0, set_parent(&ioctx
, oid
, ParentSpec(1, "parent", 3), 100<<20));
771 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 1, "snap1"));
772 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 2, "snap2"));
773 ASSERT_EQ(0, remove_parent(&ioctx
, oid
));
775 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 1, &pspec
, &size
));
776 ASSERT_EQ(-1, pspec
.pool_id
);
777 ASSERT_EQ(0, get_parent(&ioctx
, oid
, 2, &pspec
, &size
));
778 ASSERT_EQ(-1, pspec
.pool_id
);
779 ASSERT_EQ(0, get_parent(&ioctx
, oid
, CEPH_NOSNAP
, &pspec
, &size
));
780 ASSERT_EQ(-1, pspec
.pool_id
);
785 TEST_F(TestClsRbd
, snapshots
)
787 cls::rbd::SnapshotNamespace userSnapNamespace
= cls::rbd::UserSnapshotNamespace();
788 librados::IoCtx ioctx
;
789 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
791 string oid
= get_temp_image_name();
792 ASSERT_EQ(-ENOENT
, snapshot_add(&ioctx
, oid
, 0, "snap1"));
794 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, 0, oid
, -1));
796 vector
<string
> snap_names
;
797 vector
<cls::rbd::SnapshotNamespace
> snap_namespaces
;
798 vector
<uint64_t> snap_sizes
;
800 vector
<ParentInfo
> parents
;
801 vector
<uint8_t> protection_status
;
802 vector
<utime_t
> snap_timestamps
;
804 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
805 ASSERT_EQ(0u, snapc
.snaps
.size());
806 ASSERT_EQ(0u, snapc
.seq
);
807 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
808 &snap_sizes
, &parents
, &protection_status
));
809 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
810 ASSERT_EQ(0u, snap_names
.size());
811 ASSERT_EQ(0u, snap_namespaces
.size());
812 ASSERT_EQ(0u, snap_sizes
.size());
813 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
814 ASSERT_EQ(0u, snap_timestamps
.size());
816 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 0, "snap1"));
817 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
818 ASSERT_EQ(1u, snapc
.snaps
.size());
819 ASSERT_EQ(0u, snapc
.snaps
[0]);
820 ASSERT_EQ(0u, snapc
.seq
);
821 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
822 &snap_sizes
, &parents
, &protection_status
));
823 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
824 ASSERT_EQ(1u, snap_names
.size());
825 ASSERT_EQ("snap1", snap_names
[0]);
826 ASSERT_EQ(1u, snap_namespaces
.size());
827 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
828 ASSERT_EQ(10u, snap_sizes
[0]);
829 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
830 ASSERT_EQ(1u, snap_timestamps
.size());
832 // snap with same id and name
833 ASSERT_EQ(-EEXIST
, snapshot_add(&ioctx
, oid
, 0, "snap1"));
834 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
835 ASSERT_EQ(1u, snapc
.snaps
.size());
836 ASSERT_EQ(0u, snapc
.snaps
[0]);
837 ASSERT_EQ(0u, snapc
.seq
);
838 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
839 &snap_sizes
, &parents
, &protection_status
));
840 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
841 ASSERT_EQ(1u, snap_names
.size());
842 ASSERT_EQ("snap1", snap_names
[0]);
843 ASSERT_EQ(1u, snap_namespaces
.size());
844 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
845 ASSERT_EQ(10u, snap_sizes
[0]);
846 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
847 ASSERT_EQ(1u, snap_timestamps
.size());
850 // snap with same id, different name
851 ASSERT_EQ(-EEXIST
, snapshot_add(&ioctx
, oid
, 0, "snap2"));
852 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
853 ASSERT_EQ(1u, snapc
.snaps
.size());
854 ASSERT_EQ(0u, snapc
.snaps
[0]);
855 ASSERT_EQ(0u, snapc
.seq
);
856 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
857 &snap_sizes
, &parents
, &protection_status
));
858 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
859 ASSERT_EQ(1u, snap_names
.size());
860 ASSERT_EQ("snap1", snap_names
[0]);
861 ASSERT_EQ(1u, snap_namespaces
.size());
862 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
863 ASSERT_EQ(10u, snap_sizes
[0]);
864 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
865 ASSERT_EQ(1u, snap_timestamps
.size());
867 // snap with different id, same name
868 ASSERT_EQ(-EEXIST
, snapshot_add(&ioctx
, oid
, 1, "snap1"));
869 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
870 ASSERT_EQ(1u, snapc
.snaps
.size());
871 ASSERT_EQ(0u, snapc
.snaps
[0]);
872 ASSERT_EQ(0u, snapc
.seq
);
873 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
874 &snap_sizes
, &parents
, &protection_status
));
875 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
876 ASSERT_EQ(snap_names
.size(), 1u);
877 ASSERT_EQ(snap_names
[0], "snap1");
878 ASSERT_EQ(1u, snap_namespaces
.size());
879 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
880 ASSERT_EQ(snap_sizes
[0], 10u);
881 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
882 ASSERT_EQ(1u, snap_timestamps
.size());
884 // snap with different id, different name
885 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 1, "snap2"));
886 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
887 ASSERT_EQ(2u, snapc
.snaps
.size());
888 ASSERT_EQ(1u, snapc
.snaps
[0]);
889 ASSERT_EQ(0u, snapc
.snaps
[1]);
890 ASSERT_EQ(1u, snapc
.seq
);
891 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
892 &snap_sizes
, &parents
, &protection_status
));
893 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
894 ASSERT_EQ(2u, snap_names
.size());
895 ASSERT_EQ(2u, snap_namespaces
.size());
896 ASSERT_EQ("snap2", snap_names
[0]);
897 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
898 ASSERT_EQ(10u, snap_sizes
[0]);
899 ASSERT_EQ("snap1", snap_names
[1]);
900 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[1]);
901 ASSERT_EQ(10u, snap_sizes
[1]);
902 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
903 ASSERT_EQ(2u, snap_timestamps
.size());
905 ASSERT_EQ(0, snapshot_rename(&ioctx
, oid
, 0, "snap1-rename"));
906 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
907 &snap_sizes
, &parents
, &protection_status
));
908 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
909 ASSERT_EQ(2u, snap_names
.size());
910 ASSERT_EQ(2u, snap_namespaces
.size());
911 ASSERT_EQ("snap2", snap_names
[0]);
912 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
913 ASSERT_EQ(10u, snap_sizes
[0]);
914 ASSERT_EQ("snap1-rename", snap_names
[1]);
915 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[1]);
916 ASSERT_EQ(10u, snap_sizes
[1]);
917 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
918 ASSERT_EQ(2u, snap_timestamps
.size());
920 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, 0));
921 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
922 ASSERT_EQ(1u, snapc
.snaps
.size());
923 ASSERT_EQ(1u, snapc
.snaps
[0]);
924 ASSERT_EQ(1u, snapc
.seq
);
925 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
926 &snap_sizes
, &parents
, &protection_status
));
927 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
928 ASSERT_EQ(1u, snap_names
.size());
929 ASSERT_EQ(1u, snap_namespaces
.size());
930 ASSERT_EQ("snap2", snap_names
[0]);
931 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
932 ASSERT_EQ(10u, snap_sizes
[0]);
933 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
934 ASSERT_EQ(1u, snap_timestamps
.size());
938 ASSERT_EQ(0, set_size(&ioctx
, oid
, 0));
939 ASSERT_EQ(0, get_size(&ioctx
, oid
, CEPH_NOSNAP
, &size
, &order
));
941 ASSERT_EQ(22u, order
);
943 uint64_t large_snap_id
= 1ull << 63;
944 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, large_snap_id
, "snap3"));
945 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
946 ASSERT_EQ(2u, snapc
.snaps
.size());
947 ASSERT_EQ(large_snap_id
, snapc
.snaps
[0]);
948 ASSERT_EQ(1u, snapc
.snaps
[1]);
949 ASSERT_EQ(large_snap_id
, snapc
.seq
);
950 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
951 &snap_sizes
, &parents
, &protection_status
));
952 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
953 ASSERT_EQ(2u, snap_names
.size());
954 ASSERT_EQ(2u, snap_namespaces
.size());
955 ASSERT_EQ("snap3", snap_names
[0]);
956 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
957 ASSERT_EQ(0u, snap_sizes
[0]);
958 ASSERT_EQ("snap2", snap_names
[1]);
959 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[1]);
960 ASSERT_EQ(10u, snap_sizes
[1]);
961 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
962 ASSERT_EQ(2u, snap_timestamps
.size());
964 ASSERT_EQ(0, get_size(&ioctx
, oid
, large_snap_id
, &size
, &order
));
966 ASSERT_EQ(22u, order
);
968 ASSERT_EQ(0, get_size(&ioctx
, oid
, 1, &size
, &order
));
969 ASSERT_EQ(10u, size
);
970 ASSERT_EQ(22u, order
);
972 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, large_snap_id
));
973 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
974 ASSERT_EQ(1u, snapc
.snaps
.size());
975 ASSERT_EQ(1u, snapc
.snaps
[0]);
976 ASSERT_EQ(large_snap_id
, snapc
.seq
);
977 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
978 &snap_sizes
, &parents
, &protection_status
));
979 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
980 ASSERT_EQ(1u, snap_names
.size());
981 ASSERT_EQ(1u, snap_namespaces
.size());
982 ASSERT_EQ("snap2", snap_names
[0]);
983 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[0]);
984 ASSERT_EQ(10u, snap_sizes
[0]);
985 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
986 ASSERT_EQ(1u, snap_timestamps
.size());
988 ASSERT_EQ(-ENOENT
, snapshot_remove(&ioctx
, oid
, large_snap_id
));
989 ASSERT_EQ(0, snapshot_remove(&ioctx
, oid
, 1));
990 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
991 ASSERT_EQ(0u, snapc
.snaps
.size());
992 ASSERT_EQ(large_snap_id
, snapc
.seq
);
993 ASSERT_EQ(0, snapshot_list(&ioctx
, oid
, snapc
.snaps
, &snap_names
,
994 &snap_sizes
, &parents
, &protection_status
));
995 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
996 ASSERT_EQ(0u, snap_names
.size());
997 ASSERT_EQ(0u, snap_namespaces
.size());
998 ASSERT_EQ(0u, snap_sizes
.size());
999 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
1000 ASSERT_EQ(0u, snap_timestamps
.size());
1005 TEST_F(TestClsRbd
, snapshots_namespaces
)
1007 cls::rbd::SnapshotNamespace groupSnapNamespace
= cls::rbd::GroupSnapshotNamespace(5, "1018643c9869", 3);
1008 cls::rbd::SnapshotNamespace userSnapNamespace
= cls::rbd::UserSnapshotNamespace();
1009 librados::IoCtx ioctx
;
1010 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1012 string oid
= get_temp_image_name();
1014 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, 0, oid
, -1));
1016 vector
<string
> snap_names
;
1017 vector
<cls::rbd::SnapshotNamespace
> snap_namespaces
;
1020 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1021 ASSERT_EQ(0u, snapc
.snaps
.size());
1022 ASSERT_EQ(0u, snapc
.seq
);
1023 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
1024 ASSERT_EQ(0u, snap_namespaces
.size());
1026 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 0, "snap1"));
1028 librados::ObjectWriteOperation op
;
1029 ::librbd::cls_client::snapshot_add(&op
, 1, "snap1", groupSnapNamespace
);
1030 int r
= ioctx
.operate(oid
, &op
);
1033 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1034 ASSERT_EQ(2u, snapc
.snaps
.size());
1035 ASSERT_EQ(1u, snapc
.snaps
[0]);
1036 ASSERT_EQ(0u, snapc
.snaps
[1]);
1037 ASSERT_EQ(1u, snapc
.seq
);
1038 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
1039 ASSERT_EQ(groupSnapNamespace
, snap_namespaces
[0]);
1040 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[1]);
1045 TEST_F(TestClsRbd
, snapshots_timestamps
)
1047 librados::IoCtx ioctx
;
1048 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1050 string oid
= get_temp_image_name();
1052 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, 0, oid
, -1));
1054 vector
<string
> snap_names
;
1055 vector
<utime_t
> snap_timestamps
;
1058 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1059 ASSERT_EQ(0u, snapc
.snaps
.size());
1060 ASSERT_EQ(0u, snapc
.seq
);
1061 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
1062 ASSERT_EQ(0u, snap_timestamps
.size());
1064 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 0, "snap1"));
1066 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1067 ASSERT_EQ(1u, snapc
.snaps
.size());
1068 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
1069 ASSERT_LT(0U, snap_timestamps
[0].tv
.tv_sec
);
1074 TEST_F(TestClsRbd
, snapid_race
)
1076 librados::IoCtx ioctx
;
1077 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1080 buffer::ptr
bp(4096);
1084 string oid
= get_temp_image_name();
1085 ASSERT_EQ(0, ioctx
.write(oid
, bl
, 4096, 0));
1086 ASSERT_EQ(0, old_snapshot_add(&ioctx
, oid
, 1, "test1"));
1087 ASSERT_EQ(0, old_snapshot_add(&ioctx
, oid
, 3, "test3"));
1088 ASSERT_EQ(-ESTALE
, old_snapshot_add(&ioctx
, oid
, 2, "test2"));
1093 TEST_F(TestClsRbd
, stripingv2
)
1095 librados::IoCtx ioctx
;
1096 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1098 string oid
= get_temp_image_name();
1099 string oid2
= get_temp_image_name();
1100 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, 0, oid
, -1));
1102 uint64_t su
= 65536, sc
= 12;
1103 ASSERT_EQ(-ENOEXEC
, get_stripe_unit_count(&ioctx
, oid
, &su
, &sc
));
1104 ASSERT_EQ(-ENOEXEC
, set_stripe_unit_count(&ioctx
, oid
, su
, sc
));
1106 ASSERT_EQ(0, create_image(&ioctx
, oid2
, 10, 22, RBD_FEATURE_STRIPINGV2
,
1108 ASSERT_EQ(0, get_stripe_unit_count(&ioctx
, oid2
, &su
, &sc
));
1109 ASSERT_EQ(1ull << 22, su
);
1110 ASSERT_EQ(1ull, sc
);
1113 ASSERT_EQ(0, set_stripe_unit_count(&ioctx
, oid2
, su
, sc
));
1115 ASSERT_EQ(0, get_stripe_unit_count(&ioctx
, oid2
, &su
, &sc
));
1116 ASSERT_EQ(8192ull, su
);
1117 ASSERT_EQ(456ull, sc
);
1119 // su must not be larger than an object
1120 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 1 << 23, 1));
1121 // su must be a factor of object size
1122 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 511, 1));
1123 // su and sc must be non-zero
1124 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 0, 1));
1125 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 1, 0));
1126 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 0, 0));
1131 TEST_F(TestClsRbd
, get_mutable_metadata_features
)
1133 librados::IoCtx ioctx
;
1134 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1136 string oid
= get_temp_image_name();
1137 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, RBD_FEATURE_EXCLUSIVE_LOCK
,
1140 uint64_t size
, features
, incompatible_features
;
1141 std::map
<rados::cls::lock::locker_id_t
,
1142 rados::cls::lock::locker_info_t
> lockers
;
1143 bool exclusive_lock
;
1144 std::string lock_tag
;
1145 ::SnapContext snapc
;
1148 ASSERT_EQ(0, get_mutable_metadata(&ioctx
, oid
, true, &size
, &features
,
1149 &incompatible_features
, &lockers
,
1150 &exclusive_lock
, &lock_tag
, &snapc
,
1152 ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK
), features
);
1153 ASSERT_EQ(0U, incompatible_features
);
1155 ASSERT_EQ(0, get_mutable_metadata(&ioctx
, oid
, false, &size
, &features
,
1156 &incompatible_features
, &lockers
,
1157 &exclusive_lock
, &lock_tag
, &snapc
,
1159 ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK
), features
);
1160 ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK
),
1161 incompatible_features
);
1166 TEST_F(TestClsRbd
, object_map_save
)
1168 librados::IoCtx ioctx
;
1169 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1171 string oid
= get_temp_image_name();
1172 BitVector
<2> ref_bit_vector
;
1173 ref_bit_vector
.resize(32);
1174 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1175 ref_bit_vector
[i
] = 1;
1178 librados::ObjectWriteOperation op
;
1179 object_map_save(&op
, ref_bit_vector
);
1180 ASSERT_EQ(0, ioctx
.operate(oid
, &op
));
1182 BitVector
<2> osd_bit_vector
;
1183 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1184 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1187 TEST_F(TestClsRbd
, object_map_resize
)
1189 librados::IoCtx ioctx
;
1190 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1192 string oid
= get_temp_image_name();
1193 BitVector
<2> ref_bit_vector
;
1194 ref_bit_vector
.resize(32);
1195 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1196 ref_bit_vector
[i
] = 1;
1199 librados::ObjectWriteOperation op1
;
1200 object_map_resize(&op1
, ref_bit_vector
.size(), 1);
1201 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1203 BitVector
<2> osd_bit_vector
;
1204 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1205 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1207 ref_bit_vector
.resize(64);
1208 for (uint64_t i
= 32; i
< ref_bit_vector
.size(); ++i
) {
1209 ref_bit_vector
[i
] = 2;
1212 librados::ObjectWriteOperation op2
;
1213 object_map_resize(&op2
, ref_bit_vector
.size(), 2);
1214 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1215 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1216 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1218 ref_bit_vector
.resize(32);
1220 librados::ObjectWriteOperation op3
;
1221 object_map_resize(&op3
, ref_bit_vector
.size(), 1);
1222 ASSERT_EQ(-ESTALE
, ioctx
.operate(oid
, &op3
));
1224 librados::ObjectWriteOperation op4
;
1225 object_map_resize(&op4
, ref_bit_vector
.size(), 2);
1226 ASSERT_EQ(0, ioctx
.operate(oid
, &op4
));
1228 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1229 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1234 TEST_F(TestClsRbd
, object_map_update
)
1236 librados::IoCtx ioctx
;
1237 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1239 string oid
= get_temp_image_name();
1240 BitVector
<2> ref_bit_vector
;
1241 ref_bit_vector
.resize(16);
1242 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1243 ref_bit_vector
[i
] = 2;
1246 BitVector
<2> osd_bit_vector
;
1248 librados::ObjectWriteOperation op1
;
1249 object_map_resize(&op1
, ref_bit_vector
.size(), 2);
1250 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1251 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1252 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1254 ref_bit_vector
[7] = 1;
1255 ref_bit_vector
[8] = 1;
1257 librados::ObjectWriteOperation op2
;
1258 object_map_update(&op2
, 7, 9, 1, boost::optional
<uint8_t>());
1259 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1260 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1261 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1263 ref_bit_vector
[7] = 3;
1264 ref_bit_vector
[8] = 3;
1266 librados::ObjectWriteOperation op3
;
1267 object_map_update(&op3
, 6, 10, 3, 1);
1268 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
1269 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1270 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1275 TEST_F(TestClsRbd
, object_map_load_enoent
)
1277 librados::IoCtx ioctx
;
1278 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1280 string oid
= get_temp_image_name();
1281 BitVector
<2> osd_bit_vector
;
1282 ASSERT_EQ(-ENOENT
, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1287 TEST_F(TestClsRbd
, object_map_snap_add
)
1289 librados::IoCtx ioctx
;
1290 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1292 string oid
= get_temp_image_name();
1293 BitVector
<2> ref_bit_vector
;
1294 ref_bit_vector
.resize(16);
1295 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1297 ref_bit_vector
[i
] = OBJECT_NONEXISTENT
;
1299 ref_bit_vector
[i
] = OBJECT_EXISTS
;
1303 BitVector
<2> osd_bit_vector
;
1305 librados::ObjectWriteOperation op1
;
1306 object_map_resize(&op1
, ref_bit_vector
.size(), OBJECT_EXISTS
);
1307 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1309 librados::ObjectWriteOperation op2
;
1310 object_map_update(&op2
, 0, 4, OBJECT_NONEXISTENT
, boost::optional
<uint8_t>());
1311 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1313 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1314 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1316 librados::ObjectWriteOperation op3
;
1317 object_map_snap_add(&op3
);
1318 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
1320 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1321 if (ref_bit_vector
[i
] == OBJECT_EXISTS
) {
1322 ref_bit_vector
[i
] = OBJECT_EXISTS_CLEAN
;
1326 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1327 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1330 TEST_F(TestClsRbd
, object_map_snap_remove
)
1332 librados::IoCtx ioctx
;
1333 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1335 string oid
= get_temp_image_name();
1336 BitVector
<2> ref_bit_vector
;
1337 ref_bit_vector
.resize(16);
1338 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1340 ref_bit_vector
[i
] = OBJECT_EXISTS_CLEAN
;
1342 ref_bit_vector
[i
] = OBJECT_EXISTS
;
1346 BitVector
<2> osd_bit_vector
;
1348 librados::ObjectWriteOperation op1
;
1349 object_map_resize(&op1
, ref_bit_vector
.size(), OBJECT_EXISTS
);
1350 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1352 librados::ObjectWriteOperation op2
;
1353 object_map_update(&op2
, 0, 4, OBJECT_EXISTS_CLEAN
, boost::optional
<uint8_t>());
1354 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1356 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1357 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1359 BitVector
<2> snap_bit_vector
;
1360 snap_bit_vector
.resize(4);
1361 for (uint64_t i
= 0; i
< snap_bit_vector
.size(); ++i
) {
1362 if (i
== 1 || i
== 2) {
1363 snap_bit_vector
[i
] = OBJECT_EXISTS
;
1365 snap_bit_vector
[i
] = OBJECT_NONEXISTENT
;
1369 librados::ObjectWriteOperation op3
;
1370 object_map_snap_remove(&op3
, snap_bit_vector
);
1371 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
1373 ref_bit_vector
[1] = OBJECT_EXISTS
;
1374 ref_bit_vector
[2] = OBJECT_EXISTS
;
1375 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1376 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1379 TEST_F(TestClsRbd
, flags
)
1381 librados::IoCtx ioctx
;
1382 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1384 string oid
= get_temp_image_name();
1385 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
1388 std::vector
<snapid_t
> snap_ids
;
1389 std::vector
<uint64_t> snap_flags
;
1390 ASSERT_EQ(0, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1391 ASSERT_EQ(0U, flags
);
1393 librados::ObjectWriteOperation op1
;
1394 set_flags(&op1
, CEPH_NOSNAP
, 3, 2);
1395 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1396 ASSERT_EQ(0, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1397 ASSERT_EQ(2U, flags
);
1399 uint64_t snap_id
= 10;
1400 snap_ids
.push_back(snap_id
);
1401 ASSERT_EQ(-ENOENT
, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1402 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, snap_id
, "snap"));
1404 librados::ObjectWriteOperation op2
;
1405 set_flags(&op2
, snap_id
, 31, 4);
1406 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1407 ASSERT_EQ(0, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1408 ASSERT_EQ(2U, flags
);
1409 ASSERT_EQ(snap_ids
.size(), snap_flags
.size());
1410 ASSERT_EQ(6U, snap_flags
[0]);
1415 TEST_F(TestClsRbd
, metadata
)
1417 librados::IoCtx ioctx
;
1418 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1420 string oid
= get_temp_image_name();
1421 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
1423 map
<string
, bufferlist
> pairs
;
1425 ASSERT_EQ(0, metadata_list(&ioctx
, oid
, "", 0, &pairs
));
1426 ASSERT_TRUE(pairs
.empty());
1428 pairs
["key1"].append("value1");
1429 pairs
["key2"].append("value2");
1430 ASSERT_EQ(0, metadata_set(&ioctx
, oid
, pairs
));
1431 ASSERT_EQ(0, metadata_get(&ioctx
, oid
, "key1", &value
));
1432 ASSERT_EQ(0, strcmp("value1", value
.c_str()));
1434 ASSERT_EQ(0, metadata_list(&ioctx
, oid
, "", 0, &pairs
));
1435 ASSERT_EQ(2U, pairs
.size());
1436 ASSERT_EQ(0, strncmp("value1", pairs
["key1"].c_str(), 6));
1437 ASSERT_EQ(0, strncmp("value2", pairs
["key2"].c_str(), 6));
1440 ASSERT_EQ(0, metadata_remove(&ioctx
, oid
, "key1"));
1441 ASSERT_EQ(0, metadata_remove(&ioctx
, oid
, "key3"));
1442 ASSERT_TRUE(metadata_get(&ioctx
, oid
, "key1", &value
) < 0);
1443 ASSERT_EQ(0, metadata_list(&ioctx
, oid
, "", 0, &pairs
));
1444 ASSERT_EQ(1U, pairs
.size());
1445 ASSERT_EQ(0, strncmp("value2", pairs
["key2"].c_str(), 6));
1448 char key
[10], val
[20];
1449 for (int i
= 0; i
< 1024; i
++) {
1450 sprintf(key
, "key%d", i
);
1451 sprintf(val
, "value%d", i
);
1452 pairs
[key
].append(val
, strlen(val
));
1454 ASSERT_EQ(0, metadata_set(&ioctx
, oid
, pairs
));
1456 string last_read
= "";
1457 uint64_t max_read
= 48, r
;
1459 map
<string
, bufferlist
> data
;
1461 map
<string
, bufferlist
> cur
;
1462 metadata_list(&ioctx
, oid
, last_read
, max_read
, &cur
);
1464 for (map
<string
, bufferlist
>::iterator it
= cur
.begin();
1465 it
!= cur
.end(); ++it
)
1466 data
[it
->first
] = it
->second
;
1467 last_read
= cur
.rbegin()->first
;
1469 } while (r
== max_read
);
1470 ASSERT_EQ(size
, 1024U);
1471 for (map
<string
, bufferlist
>::iterator it
= data
.begin();
1472 it
!= data
.end(); ++it
) {
1473 ASSERT_TRUE(it
->second
.contents_equal(pairs
[it
->first
]));
1479 TEST_F(TestClsRbd
, set_features
)
1481 librados::IoCtx ioctx
;
1482 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1484 string oid
= get_temp_image_name();
1485 uint64_t base_features
= RBD_FEATURE_LAYERING
| RBD_FEATURE_DEEP_FLATTEN
;
1486 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, base_features
, oid
, -1));
1488 uint64_t features
= RBD_FEATURES_MUTABLE
;
1489 uint64_t mask
= RBD_FEATURES_MUTABLE
;
1490 ASSERT_EQ(0, set_features(&ioctx
, oid
, features
, mask
));
1492 uint64_t actual_features
;
1493 ASSERT_EQ(0, get_features(&ioctx
, oid
, CEPH_NOSNAP
, &actual_features
));
1495 uint64_t expected_features
= RBD_FEATURES_MUTABLE
| base_features
;
1496 ASSERT_EQ(expected_features
, actual_features
);
1499 mask
= RBD_FEATURE_OBJECT_MAP
;
1500 ASSERT_EQ(0, set_features(&ioctx
, oid
, features
, mask
));
1502 ASSERT_EQ(0, get_features(&ioctx
, oid
, CEPH_NOSNAP
, &actual_features
));
1504 expected_features
= (RBD_FEATURES_MUTABLE
| base_features
) &
1505 ~RBD_FEATURE_OBJECT_MAP
;
1506 ASSERT_EQ(expected_features
, actual_features
);
1508 ASSERT_EQ(0, set_features(&ioctx
, oid
, 0, RBD_FEATURE_DEEP_FLATTEN
));
1509 ASSERT_EQ(-EINVAL
, set_features(&ioctx
, oid
, RBD_FEATURE_DEEP_FLATTEN
,
1510 RBD_FEATURE_DEEP_FLATTEN
));
1512 ASSERT_EQ(-EINVAL
, set_features(&ioctx
, oid
, 0, RBD_FEATURE_LAYERING
));
1515 TEST_F(TestClsRbd
, mirror
) {
1516 librados::IoCtx ioctx
;
1517 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1518 ioctx
.remove(RBD_MIRRORING
);
1520 std::vector
<cls::rbd::MirrorPeer
> peers
;
1521 ASSERT_EQ(-ENOENT
, mirror_peer_list(&ioctx
, &peers
));
1524 ASSERT_EQ(-ENOENT
, mirror_uuid_get(&ioctx
, &uuid
));
1525 ASSERT_EQ(-EINVAL
, mirror_peer_add(&ioctx
, "uuid1", "cluster1", "client"));
1527 cls::rbd::MirrorMode mirror_mode
;
1528 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1529 ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED
, mirror_mode
);
1531 ASSERT_EQ(-EINVAL
, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_IMAGE
));
1532 ASSERT_EQ(-EINVAL
, mirror_uuid_set(&ioctx
, ""));
1533 ASSERT_EQ(0, mirror_uuid_set(&ioctx
, "mirror-uuid"));
1534 ASSERT_EQ(0, mirror_uuid_get(&ioctx
, &uuid
));
1535 ASSERT_EQ("mirror-uuid", uuid
);
1537 ASSERT_EQ(0, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_IMAGE
));
1538 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1539 ASSERT_EQ(cls::rbd::MIRROR_MODE_IMAGE
, mirror_mode
);
1541 ASSERT_EQ(-EINVAL
, mirror_uuid_set(&ioctx
, "new-mirror-uuid"));
1543 ASSERT_EQ(0, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_POOL
));
1544 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1545 ASSERT_EQ(cls::rbd::MIRROR_MODE_POOL
, mirror_mode
);
1547 ASSERT_EQ(-EINVAL
, mirror_peer_add(&ioctx
, "mirror-uuid", "cluster1", "client"));
1548 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid1", "cluster1", "client"));
1549 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid2", "cluster2", "admin"));
1550 ASSERT_EQ(-ESTALE
, mirror_peer_add(&ioctx
, "uuid2", "cluster3", "foo"));
1551 ASSERT_EQ(-EEXIST
, mirror_peer_add(&ioctx
, "uuid3", "cluster1", "foo"));
1552 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid3", "cluster3", "admin", 123));
1553 ASSERT_EQ(-EEXIST
, mirror_peer_add(&ioctx
, "uuid4", "cluster3", "admin"));
1554 ASSERT_EQ(-EEXIST
, mirror_peer_add(&ioctx
, "uuid4", "cluster3", "admin", 123));
1555 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid4", "cluster3", "admin", 234));
1557 ASSERT_EQ(0, mirror_peer_list(&ioctx
, &peers
));
1558 std::vector
<cls::rbd::MirrorPeer
> expected_peers
= {
1559 {"uuid1", "cluster1", "client", -1},
1560 {"uuid2", "cluster2", "admin", -1},
1561 {"uuid3", "cluster3", "admin", 123},
1562 {"uuid4", "cluster3", "admin", 234}};
1563 ASSERT_EQ(expected_peers
, peers
);
1565 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid5"));
1566 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid4"));
1567 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid2"));
1569 ASSERT_EQ(-ENOENT
, mirror_peer_set_client(&ioctx
, "uuid4", "new client"));
1570 ASSERT_EQ(0, mirror_peer_set_client(&ioctx
, "uuid1", "new client"));
1572 ASSERT_EQ(-ENOENT
, mirror_peer_set_cluster(&ioctx
, "uuid4", "new cluster"));
1573 ASSERT_EQ(0, mirror_peer_set_cluster(&ioctx
, "uuid3", "new cluster"));
1575 ASSERT_EQ(0, mirror_peer_list(&ioctx
, &peers
));
1577 {"uuid1", "cluster1", "new client", -1},
1578 {"uuid3", "new cluster", "admin", 123}};
1579 ASSERT_EQ(expected_peers
, peers
);
1580 ASSERT_EQ(-EBUSY
, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_DISABLED
));
1582 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid3"));
1583 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid1"));
1584 ASSERT_EQ(0, mirror_peer_list(&ioctx
, &peers
));
1585 expected_peers
= {};
1586 ASSERT_EQ(expected_peers
, peers
);
1588 ASSERT_EQ(0, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_DISABLED
));
1589 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1590 ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED
, mirror_mode
);
1591 ASSERT_EQ(-ENOENT
, mirror_uuid_get(&ioctx
, &uuid
));
1594 TEST_F(TestClsRbd
, mirror_image
) {
1595 librados::IoCtx ioctx
;
1596 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1597 ioctx
.remove(RBD_MIRRORING
);
1599 std::map
<std::string
, std::string
> mirror_image_ids
;
1600 ASSERT_EQ(-ENOENT
, mirror_image_list(&ioctx
, "", 0, &mirror_image_ids
));
1602 cls::rbd::MirrorImage
image1("uuid1", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1603 cls::rbd::MirrorImage
image2("uuid2", cls::rbd::MIRROR_IMAGE_STATE_DISABLING
);
1604 cls::rbd::MirrorImage
image3("uuid3", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1606 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1607 ASSERT_EQ(-ENOENT
, mirror_image_set(&ioctx
, "image_id2", image2
));
1608 image2
.state
= cls::rbd::MIRROR_IMAGE_STATE_ENABLED
;
1609 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1610 image2
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1611 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1612 ASSERT_EQ(-EINVAL
, mirror_image_set(&ioctx
, "image_id1", image2
));
1613 ASSERT_EQ(-EEXIST
, mirror_image_set(&ioctx
, "image_id3", image2
));
1614 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1616 std::string image_id
;
1617 ASSERT_EQ(0, mirror_image_get_image_id(&ioctx
, "uuid2", &image_id
));
1618 ASSERT_EQ("image_id2", image_id
);
1620 cls::rbd::MirrorImage read_image
;
1621 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id1", &read_image
));
1622 ASSERT_EQ(read_image
, image1
);
1623 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id2", &read_image
));
1624 ASSERT_EQ(read_image
, image2
);
1625 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id3", &read_image
));
1626 ASSERT_EQ(read_image
, image3
);
1628 ASSERT_EQ(0, mirror_image_list(&ioctx
, "", 1, &mirror_image_ids
));
1629 std::map
<std::string
, std::string
> expected_mirror_image_ids
= {
1630 {"image_id1", "uuid1"}};
1631 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1633 ASSERT_EQ(0, mirror_image_list(&ioctx
, "image_id1", 2, &mirror_image_ids
));
1634 expected_mirror_image_ids
= {{"image_id2", "uuid2"}, {"image_id3", "uuid3"}};
1635 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1637 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id2"));
1638 ASSERT_EQ(-ENOENT
, mirror_image_get_image_id(&ioctx
, "uuid2", &image_id
));
1639 ASSERT_EQ(-EBUSY
, mirror_image_remove(&ioctx
, "image_id1"));
1641 ASSERT_EQ(0, mirror_image_list(&ioctx
, "", 3, &mirror_image_ids
));
1642 expected_mirror_image_ids
= {{"image_id1", "uuid1"}, {"image_id3", "uuid3"}};
1643 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1645 image1
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1646 image3
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1647 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1648 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id1", &read_image
));
1649 ASSERT_EQ(read_image
, image1
);
1650 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1651 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id1"));
1652 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id3"));
1654 ASSERT_EQ(0, mirror_image_list(&ioctx
, "", 3, &mirror_image_ids
));
1655 expected_mirror_image_ids
= {};
1656 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1659 TEST_F(TestClsRbd
, mirror_image_status
) {
1660 struct WatchCtx
: public librados::WatchCtx2
{
1661 librados::IoCtx
*m_ioctx
;
1663 WatchCtx(librados::IoCtx
*ioctx
) : m_ioctx(ioctx
) {}
1664 void handle_notify(uint64_t notify_id
, uint64_t cookie
,
1665 uint64_t notifier_id
, bufferlist
& bl_
) override
{
1667 m_ioctx
->notify_ack(RBD_MIRRORING
, notify_id
, cookie
, bl
);
1669 void handle_error(uint64_t cookie
, int err
) override
{}
1672 map
<std::string
, cls::rbd::MirrorImage
> images
;
1673 map
<std::string
, cls::rbd::MirrorImageStatus
> statuses
;
1674 std::map
<cls::rbd::MirrorImageStatusState
, int> states
;
1675 cls::rbd::MirrorImageStatus read_status
;
1676 uint64_t watch_handle
;
1677 librados::IoCtx ioctx
;
1679 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1680 ioctx
.remove(RBD_MIRRORING
);
1682 // Test list fails on nonexistent RBD_MIRRORING object
1684 ASSERT_EQ(-ENOENT
, mirror_image_status_list(&ioctx
, "", 1024, &images
,
1689 cls::rbd::MirrorImage
image1("uuid1", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1690 cls::rbd::MirrorImage
image2("uuid2", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1691 cls::rbd::MirrorImage
image3("uuid3", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1693 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1694 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1695 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1697 cls::rbd::MirrorImageStatus
status1(cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
);
1698 cls::rbd::MirrorImageStatus
status2(cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
);
1699 cls::rbd::MirrorImageStatus
status3(cls::rbd::MIRROR_IMAGE_STATUS_STATE_ERROR
);
1701 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1704 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1705 ASSERT_EQ(3U, images
.size());
1706 ASSERT_EQ(1U, statuses
.size());
1708 // Test status is down due to RBD_MIRRORING is not watched
1711 ASSERT_EQ(statuses
["image_id1"], status1
);
1712 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1713 ASSERT_EQ(read_status
, status1
);
1715 // Test status summary. All statuses are unknown due to down.
1717 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1718 ASSERT_EQ(1U, states
.size());
1719 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1721 // Test remove_down removes stale statuses
1723 ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx
));
1724 ASSERT_EQ(-ENOENT
, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1725 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1726 ASSERT_EQ(3U, images
.size());
1727 ASSERT_TRUE(statuses
.empty());
1728 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1729 ASSERT_EQ(1U, states
.size());
1730 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1732 // Test statuses are not down after watcher is started
1734 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1736 WatchCtx
watch_ctx(&ioctx
);
1737 ASSERT_EQ(0, ioctx
.watch2(RBD_MIRRORING
, &watch_handle
, &watch_ctx
));
1739 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid2", status2
));
1740 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid3", status3
));
1742 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1744 ASSERT_EQ(read_status
, status1
);
1745 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid2", &read_status
));
1747 ASSERT_EQ(read_status
, status2
);
1748 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid3", &read_status
));
1750 ASSERT_EQ(read_status
, status3
);
1754 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1755 ASSERT_EQ(3U, images
.size());
1756 ASSERT_EQ(3U, statuses
.size());
1757 ASSERT_EQ(statuses
["image_id1"], status1
);
1758 ASSERT_EQ(statuses
["image_id2"], status2
);
1759 ASSERT_EQ(statuses
["image_id3"], status3
);
1761 ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx
));
1762 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1763 ASSERT_EQ(read_status
, status1
);
1766 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1767 ASSERT_EQ(3U, images
.size());
1768 ASSERT_EQ(3U, statuses
.size());
1769 ASSERT_EQ(statuses
["image_id1"], status1
);
1770 ASSERT_EQ(statuses
["image_id2"], status2
);
1771 ASSERT_EQ(statuses
["image_id3"], status3
);
1774 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1775 ASSERT_EQ(3U, states
.size());
1776 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1777 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
]);
1778 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_ERROR
]);
1782 status1
.state
= status3
.state
= cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
;
1783 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1784 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid3", status3
));
1785 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid3", &read_status
));
1786 ASSERT_EQ(read_status
, status3
);
1789 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1790 ASSERT_EQ(1U, states
.size());
1791 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
]);
1795 ASSERT_EQ(0, mirror_image_status_remove(&ioctx
, "uuid3"));
1796 ASSERT_EQ(-ENOENT
, mirror_image_status_get(&ioctx
, "uuid3", &read_status
));
1799 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1800 ASSERT_EQ(3U, images
.size());
1801 ASSERT_EQ(2U, statuses
.size());
1802 ASSERT_EQ(statuses
["image_id1"], status1
);
1803 ASSERT_EQ(statuses
["image_id2"], status2
);
1806 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1807 ASSERT_EQ(2U, states
.size());
1808 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1809 ASSERT_EQ(2, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
]);
1811 // Test statuses are down after removing watcher
1813 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1814 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid2", status2
));
1815 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid3", status3
));
1819 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1820 ASSERT_EQ(3U, images
.size());
1821 ASSERT_EQ(3U, statuses
.size());
1822 ASSERT_EQ(statuses
["image_id1"], status1
);
1823 ASSERT_EQ(statuses
["image_id2"], status2
);
1824 ASSERT_EQ(statuses
["image_id3"], status3
);
1826 ioctx
.unwatch2(watch_handle
);
1828 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1829 ASSERT_EQ(3U, images
.size());
1830 ASSERT_EQ(3U, statuses
.size());
1832 ASSERT_EQ(statuses
["image_id1"], status1
);
1834 ASSERT_EQ(statuses
["image_id2"], status2
);
1836 ASSERT_EQ(statuses
["image_id3"], status3
);
1838 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1839 ASSERT_EQ(read_status
, status1
);
1842 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1843 ASSERT_EQ(1U, states
.size());
1844 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1846 ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx
));
1847 ASSERT_EQ(-ENOENT
, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1851 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1852 ASSERT_EQ(3U, images
.size());
1853 ASSERT_TRUE(statuses
.empty());
1856 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1857 ASSERT_EQ(1U, states
.size());
1858 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1862 image1
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1863 image2
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1864 image3
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1866 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1867 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1868 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1870 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id1"));
1871 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id2"));
1872 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id3"));
1875 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1876 ASSERT_EQ(0U, states
.size());
1878 // Test status list with large number of images
1881 ASSERT_EQ(0U, N
% 2);
1883 for (size_t i
= 0; i
< N
; i
++) {
1884 std::string id
= "id" + stringify(i
);
1885 std::string uuid
= "uuid" + stringify(i
);
1886 cls::rbd::MirrorImage
image(uuid
, cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1887 cls::rbd::MirrorImageStatus
status(cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
);
1888 ASSERT_EQ(0, mirror_image_set(&ioctx
, id
, image
));
1889 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, uuid
, status
));
1892 std::string last_read
= "";
1895 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
* 2, &images
,
1897 ASSERT_EQ(N
, images
.size());
1898 ASSERT_EQ(N
, statuses
.size());
1902 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
/ 2, &images
,
1904 ASSERT_EQ(N
/ 2, images
.size());
1905 ASSERT_EQ(N
/ 2, statuses
.size());
1907 last_read
= images
.rbegin()->first
;
1910 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
/ 2, &images
,
1912 ASSERT_EQ(N
/ 2, images
.size());
1913 ASSERT_EQ(N
/ 2, statuses
.size());
1915 last_read
= images
.rbegin()->first
;
1918 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
/ 2, &images
,
1920 ASSERT_EQ(0U, images
.size());
1921 ASSERT_EQ(0U, statuses
.size());
1924 TEST_F(TestClsRbd
, mirror_instances
) {
1925 librados::IoCtx ioctx
;
1926 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1927 ioctx
.remove(RBD_MIRROR_LEADER
);
1929 std::vector
<std::string
> instance_ids
;
1930 ASSERT_EQ(-ENOENT
, mirror_instances_list(&ioctx
, &instance_ids
));
1932 ASSERT_EQ(0, ioctx
.create(RBD_MIRROR_LEADER
, true));
1933 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1934 ASSERT_EQ(0U, instance_ids
.size());
1936 ASSERT_EQ(0, mirror_instances_add(&ioctx
, "instance_id1"));
1937 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1938 ASSERT_EQ(1U, instance_ids
.size());
1939 ASSERT_EQ(instance_ids
[0], "instance_id1");
1941 ASSERT_EQ(0, mirror_instances_add(&ioctx
, "instance_id1"));
1942 ASSERT_EQ(0, mirror_instances_add(&ioctx
, "instance_id2"));
1943 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1944 ASSERT_EQ(2U, instance_ids
.size());
1946 ASSERT_EQ(0, mirror_instances_remove(&ioctx
, "instance_id1"));
1947 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1948 ASSERT_EQ(1U, instance_ids
.size());
1949 ASSERT_EQ(instance_ids
[0], "instance_id2");
1951 ASSERT_EQ(0, mirror_instances_remove(&ioctx
, "instance_id2"));
1952 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1953 ASSERT_EQ(0U, instance_ids
.size());
1956 TEST_F(TestClsRbd
, group_create
) {
1957 librados::IoCtx ioctx
;
1958 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1960 string group_id
= "group_id";
1961 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
1965 ASSERT_EQ(0, ioctx
.stat(group_id
, &psize
, &pmtime
));
1968 TEST_F(TestClsRbd
, group_dir_list
) {
1969 librados::IoCtx ioctx
;
1970 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1972 string group_id1
= "cgid1";
1973 string group_name1
= "cgname1";
1974 string group_id2
= "cgid2";
1975 string group_name2
= "cgname2";
1976 ASSERT_EQ(0, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name1
, group_id1
));
1977 ASSERT_EQ(0, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name2
, group_id2
));
1979 map
<string
, string
> cgs
;
1980 ASSERT_EQ(0, group_dir_list(&ioctx
, RBD_GROUP_DIRECTORY
, "", 10, &cgs
));
1982 ASSERT_EQ(2U, cgs
.size());
1984 auto it
= cgs
.begin();
1985 ASSERT_EQ(group_id1
, it
->second
);
1986 ASSERT_EQ(group_name1
, it
->first
);
1989 ASSERT_EQ(group_id2
, it
->second
);
1990 ASSERT_EQ(group_name2
, it
->first
);
1993 void add_group_to_dir(librados::IoCtx ioctx
, string group_id
, string group_name
) {
1994 ASSERT_EQ(0, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
1997 ASSERT_EQ(0, ioctx
.omap_get_keys(RBD_GROUP_DIRECTORY
, "", 10, &keys
));
1998 ASSERT_EQ(2U, keys
.size());
1999 ASSERT_EQ("id_" + group_id
, *keys
.begin());
2000 ASSERT_EQ("name_" + group_name
, *keys
.rbegin());
2003 TEST_F(TestClsRbd
, group_dir_add
) {
2004 librados::IoCtx ioctx
;
2005 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2006 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2008 string group_id
= "cgid";
2009 string group_name
= "cgname";
2010 add_group_to_dir(ioctx
, group_id
, group_name
);
2013 TEST_F(TestClsRbd
, dir_add_already_existing
) {
2014 librados::IoCtx ioctx
;
2015 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2016 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2018 string group_id
= "cgidexisting";
2019 string group_name
= "cgnameexisting";
2020 add_group_to_dir(ioctx
, group_id
, group_name
);
2022 ASSERT_EQ(-EEXIST
, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2025 TEST_F(TestClsRbd
, group_dir_remove
) {
2026 librados::IoCtx ioctx
;
2027 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2028 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2030 string group_id
= "cgidtodel";
2031 string group_name
= "cgnametodel";
2032 add_group_to_dir(ioctx
, group_id
, group_name
);
2034 ASSERT_EQ(0, group_dir_remove(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2037 ASSERT_EQ(0, ioctx
.omap_get_keys(RBD_GROUP_DIRECTORY
, "", 10, &keys
));
2038 ASSERT_EQ(0U, keys
.size());
2041 TEST_F(TestClsRbd
, group_dir_remove_missing
) {
2042 librados::IoCtx ioctx
;
2043 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2044 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2046 string group_id
= "cgidtodelmissing";
2047 string group_name
= "cgnametodelmissing";
2048 // These two lines ensure that RBD_GROUP_DIRECTORY exists. It's important for the
2050 add_group_to_dir(ioctx
, group_id
, group_name
);
2052 ASSERT_EQ(0, group_dir_remove(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2055 ASSERT_EQ(-ENOENT
, group_dir_remove(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2058 ASSERT_EQ(0, ioctx
.omap_get_keys(RBD_GROUP_DIRECTORY
, "", 10, &keys
));
2059 ASSERT_EQ(0U, keys
.size());
2062 void test_image_add(librados::IoCtx
&ioctx
, const string
& group_id
,
2063 const string
& image_id
, int64_t pool_id
) {
2065 cls::rbd::GroupImageStatus
st(image_id
, pool_id
,
2066 cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE
);
2067 ASSERT_EQ(0, group_image_set(&ioctx
, group_id
, st
));
2070 ASSERT_EQ(0, ioctx
.omap_get_keys(group_id
, "", 10, &keys
));
2072 auto it
= keys
.begin();
2073 ASSERT_EQ(2U, keys
.size());
2075 string image_key
= cls::rbd::GroupImageSpec(image_id
, pool_id
).image_key();
2076 ASSERT_EQ(image_key
, *it
);
2078 ASSERT_EQ("snap_seq", *it
);
2081 TEST_F(TestClsRbd
, group_image_add
) {
2082 librados::IoCtx ioctx
;
2083 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2085 string group_id
= "group_id";
2086 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2088 int64_t pool_id
= ioctx
.get_id();
2089 string image_id
= "image_id";
2090 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2093 TEST_F(TestClsRbd
, group_image_remove
) {
2094 librados::IoCtx ioctx
;
2095 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2097 string group_id
= "group_id";
2098 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2100 int64_t pool_id
= ioctx
.get_id();
2101 string image_id
= "image_id";
2102 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2104 cls::rbd::GroupImageSpec
spec(image_id
, pool_id
);
2105 ASSERT_EQ(0, group_image_remove(&ioctx
, group_id
, spec
));
2107 ASSERT_EQ(0, ioctx
.omap_get_keys(group_id
, "", 10, &keys
));
2108 ASSERT_EQ(1U, keys
.size());
2109 ASSERT_EQ("snap_seq", *(keys
.begin()));
2112 TEST_F(TestClsRbd
, group_image_list
) {
2113 librados::IoCtx ioctx
;
2114 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2116 string group_id
= "group_id";
2117 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2119 int64_t pool_id
= ioctx
.get_id();
2120 string image_id
= "imageid"; // Image id shouldn't contain underscores
2121 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2123 vector
<cls::rbd::GroupImageStatus
> images
;
2124 cls::rbd::GroupImageSpec empty_image_spec
= cls::rbd::GroupImageSpec();
2125 ASSERT_EQ(0, group_image_list(&ioctx
, group_id
, empty_image_spec
, 1024,
2127 ASSERT_EQ(1U, images
.size());
2128 ASSERT_EQ(image_id
, images
[0].spec
.image_id
);
2129 ASSERT_EQ(pool_id
, images
[0].spec
.pool_id
);
2130 ASSERT_EQ(cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE
, images
[0].state
);
2132 cls::rbd::GroupImageStatus last_image
= *images
.rbegin();
2133 ASSERT_EQ(0, group_image_list(&ioctx
, group_id
, last_image
.spec
, 1024,
2135 ASSERT_EQ(0U, images
.size());
2138 TEST_F(TestClsRbd
, group_image_clean
) {
2139 librados::IoCtx ioctx
;
2140 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2142 string group_id
= "group_id1";
2143 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2145 int64_t pool_id
= ioctx
.get_id();
2146 string image_id
= "image_id";
2147 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2149 cls::rbd::GroupImageStatus
incomplete_st(image_id
, pool_id
,
2150 cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE
);
2152 ASSERT_EQ(0, group_image_set(&ioctx
, group_id
, incomplete_st
));
2153 // Set to dirty first in order to make sure that group_image_clean
2154 // actually does something.
2155 cls::rbd::GroupImageStatus
attached_st(image_id
, pool_id
,
2156 cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED
);
2157 ASSERT_EQ(0, group_image_set(&ioctx
, group_id
, attached_st
));
2159 string image_key
= cls::rbd::GroupImageSpec(image_id
, pool_id
).image_key();
2161 map
<string
, bufferlist
> vals
;
2162 ASSERT_EQ(0, ioctx
.omap_get_vals(group_id
, "", 10, &vals
));
2164 cls::rbd::GroupImageLinkState ref_state
;
2165 bufferlist::iterator it
= vals
[image_key
].begin();
2166 ::decode(ref_state
, it
);
2167 ASSERT_EQ(cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED
, ref_state
);
2170 TEST_F(TestClsRbd
, image_add_group
) {
2171 librados::IoCtx ioctx
;
2172 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2174 int64_t pool_id
= ioctx
.get_id();
2175 string image_id
= "imageid";
2177 ASSERT_EQ(0, create_image(&ioctx
, image_id
, 2<<20, 0,
2178 RBD_FEATURE_LAYERING
, image_id
, -1));
2180 string group_id
= "group_id";
2182 cls::rbd::GroupSpec
spec(group_id
, pool_id
);
2183 ASSERT_EQ(0, image_add_group(&ioctx
, image_id
, spec
));
2185 map
<string
, bufferlist
> vals
;
2186 ASSERT_EQ(0, ioctx
.omap_get_vals(image_id
, "", RBD_GROUP_REF
, 10, &vals
));
2188 cls::rbd::GroupSpec val_spec
;
2189 bufferlist::iterator it
= vals
[RBD_GROUP_REF
].begin();
2190 ::decode(val_spec
, it
);
2192 ASSERT_EQ(group_id
, val_spec
.group_id
);
2193 ASSERT_EQ(pool_id
, val_spec
.pool_id
);
2196 TEST_F(TestClsRbd
, image_remove_group
) {
2197 librados::IoCtx ioctx
;
2198 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2200 int64_t pool_id
= ioctx
.get_id();
2201 string image_id
= "image_id";
2203 ASSERT_EQ(0, create_image(&ioctx
, image_id
, 2<<20, 0,
2204 RBD_FEATURE_LAYERING
, image_id
, -1));
2206 string group_id
= "group_id";
2208 cls::rbd::GroupSpec
spec(group_id
, pool_id
);
2209 ASSERT_EQ(0, image_add_group(&ioctx
, image_id
, spec
));
2210 // Add reference in order to make sure that image_remove_group actually
2212 ASSERT_EQ(0, image_remove_group(&ioctx
, image_id
, spec
));
2214 map
<string
, bufferlist
> vals
;
2215 ASSERT_EQ(0, ioctx
.omap_get_vals(image_id
, "", RBD_GROUP_REF
, 10, &vals
));
2217 ASSERT_EQ(0U, vals
.size());
2220 TEST_F(TestClsRbd
, image_get_group
) {
2221 librados::IoCtx ioctx
;
2222 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2224 int64_t pool_id
= ioctx
.get_id();
2225 string image_id
= "imageidgroupspec";
2227 ASSERT_EQ(0, create_image(&ioctx
, image_id
, 2<<20, 0,
2228 RBD_FEATURE_LAYERING
, image_id
, -1));
2230 string group_id
= "group_id_get_group_spec";
2232 cls::rbd::GroupSpec
spec_add(group_id
, pool_id
);
2233 ASSERT_EQ(0, image_add_group(&ioctx
, image_id
, spec_add
));
2235 cls::rbd::GroupSpec spec
;
2236 ASSERT_EQ(0, image_get_group(&ioctx
, image_id
, &spec
));
2238 ASSERT_EQ(group_id
, spec
.group_id
);
2239 ASSERT_EQ(pool_id
, spec
.pool_id
);
2242 TEST_F(TestClsRbd
, trash_methods
)
2244 librados::IoCtx ioctx
;
2245 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2247 string id
= "123456789";
2248 string id2
= "123456780";
2250 std::map
<string
, cls::rbd::TrashImageSpec
> entries
;
2251 ASSERT_EQ(-ENOENT
, trash_list(&ioctx
, "", 1024, &entries
));
2253 utime_t now1
= ceph_clock_now();
2254 utime_t now1_delay
= now1
;
2256 cls::rbd::TrashImageSpec
trash_spec(cls::rbd::TRASH_IMAGE_SOURCE_USER
, "name",
2258 ASSERT_EQ(0, trash_add(&ioctx
, id
, trash_spec
));
2260 utime_t now2
= ceph_clock_now();
2261 utime_t now2_delay
= now2
;
2263 cls::rbd::TrashImageSpec
trash_spec2(cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING
,
2264 "name2", now2
, now2_delay
);
2265 ASSERT_EQ(-EEXIST
, trash_add(&ioctx
, id
, trash_spec2
));
2267 ASSERT_EQ(0, trash_remove(&ioctx
, id
));
2268 ASSERT_EQ(-ENOENT
, trash_remove(&ioctx
, id
));
2270 ASSERT_EQ(0, trash_list(&ioctx
, "", 1024, &entries
));
2271 ASSERT_TRUE(entries
.empty());
2273 ASSERT_EQ(0, trash_add(&ioctx
, id
, trash_spec2
));
2274 ASSERT_EQ(0, trash_add(&ioctx
, id2
, trash_spec
));
2276 ASSERT_EQ(0, trash_list(&ioctx
, "", 1, &entries
));
2277 ASSERT_TRUE(entries
.find(id2
) != entries
.end());
2278 ASSERT_EQ(cls::rbd::TRASH_IMAGE_SOURCE_USER
, entries
[id2
].source
);
2279 ASSERT_EQ(std::string("name"), entries
[id2
].name
);
2280 ASSERT_EQ(now1
, entries
[id2
].deletion_time
);
2281 ASSERT_EQ(now1_delay
, entries
[id2
].deferment_end_time
);
2283 ASSERT_EQ(0, trash_list(&ioctx
, id2
, 1, &entries
));
2284 ASSERT_TRUE(entries
.find(id
) != entries
.end());
2285 ASSERT_EQ(cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING
, entries
[id
].source
);
2286 ASSERT_EQ(std::string("name2"), entries
[id
].name
);
2287 ASSERT_EQ(now2
, entries
[id
].deletion_time
);
2288 ASSERT_EQ(now2_delay
, entries
[id
].deferment_end_time
);
2290 ASSERT_EQ(0, trash_list(&ioctx
, id
, 1, &entries
));
2291 ASSERT_TRUE(entries
.empty());
2293 cls::rbd::TrashImageSpec spec_res1
;
2294 ASSERT_EQ(0, trash_get(&ioctx
, id
, &spec_res1
));
2295 cls::rbd::TrashImageSpec spec_res2
;
2296 ASSERT_EQ(0, trash_get(&ioctx
, id2
, &spec_res2
));
2298 ASSERT_EQ(spec_res1
.name
, "name2");
2299 ASSERT_EQ(spec_res1
.deletion_time
, now2
);
2300 ASSERT_EQ(spec_res1
.deferment_end_time
, now2_delay
);
2302 ASSERT_EQ(spec_res2
.name
, "name");
2303 ASSERT_EQ(spec_res2
.deletion_time
, now1
);
2304 ASSERT_EQ(spec_res2
.deferment_end_time
, now1_delay
);