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
<cls::rbd::SnapshotNamespace
> snap_namespaces
;
1019 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1020 ASSERT_EQ(0u, snapc
.snaps
.size());
1021 ASSERT_EQ(0u, snapc
.seq
);
1022 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
1023 ASSERT_EQ(0u, snap_namespaces
.size());
1025 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 0, "snap1"));
1027 librados::ObjectWriteOperation op
;
1028 ::librbd::cls_client::snapshot_add(&op
, 1, "snap1", groupSnapNamespace
);
1029 int r
= ioctx
.operate(oid
, &op
);
1032 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1033 ASSERT_EQ(2u, snapc
.snaps
.size());
1034 ASSERT_EQ(1u, snapc
.snaps
[0]);
1035 ASSERT_EQ(0u, snapc
.snaps
[1]);
1036 ASSERT_EQ(1u, snapc
.seq
);
1037 ASSERT_EQ(0, snapshot_namespace_list(&ioctx
, oid
, snapc
.snaps
, &snap_namespaces
));
1038 ASSERT_EQ(groupSnapNamespace
, snap_namespaces
[0]);
1039 ASSERT_EQ(userSnapNamespace
, snap_namespaces
[1]);
1044 TEST_F(TestClsRbd
, snapshots_timestamps
)
1046 librados::IoCtx ioctx
;
1047 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1049 string oid
= get_temp_image_name();
1051 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, 0, oid
, -1));
1053 vector
<utime_t
> snap_timestamps
;
1056 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1057 ASSERT_EQ(0u, snapc
.snaps
.size());
1058 ASSERT_EQ(0u, snapc
.seq
);
1059 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
1060 ASSERT_EQ(0u, snap_timestamps
.size());
1062 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, 0, "snap1"));
1064 ASSERT_EQ(0, get_snapcontext(&ioctx
, oid
, &snapc
));
1065 ASSERT_EQ(1u, snapc
.snaps
.size());
1066 ASSERT_EQ(0, snapshot_timestamp_list(&ioctx
, oid
, snapc
.snaps
, &snap_timestamps
));
1067 ASSERT_LT(0U, snap_timestamps
[0].tv
.tv_sec
);
1072 TEST_F(TestClsRbd
, snapid_race
)
1074 librados::IoCtx ioctx
;
1075 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1078 buffer::ptr
bp(4096);
1082 string oid
= get_temp_image_name();
1083 ASSERT_EQ(0, ioctx
.write(oid
, bl
, 4096, 0));
1084 ASSERT_EQ(0, old_snapshot_add(&ioctx
, oid
, 1, "test1"));
1085 ASSERT_EQ(0, old_snapshot_add(&ioctx
, oid
, 3, "test3"));
1086 ASSERT_EQ(-ESTALE
, old_snapshot_add(&ioctx
, oid
, 2, "test2"));
1091 TEST_F(TestClsRbd
, stripingv2
)
1093 librados::IoCtx ioctx
;
1094 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1096 string oid
= get_temp_image_name();
1097 string oid2
= get_temp_image_name();
1098 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, 0, oid
, -1));
1100 uint64_t su
= 65536, sc
= 12;
1101 ASSERT_EQ(-ENOEXEC
, get_stripe_unit_count(&ioctx
, oid
, &su
, &sc
));
1102 ASSERT_EQ(-ENOEXEC
, set_stripe_unit_count(&ioctx
, oid
, su
, sc
));
1104 ASSERT_EQ(0, create_image(&ioctx
, oid2
, 10, 22, RBD_FEATURE_STRIPINGV2
,
1106 ASSERT_EQ(0, get_stripe_unit_count(&ioctx
, oid2
, &su
, &sc
));
1107 ASSERT_EQ(1ull << 22, su
);
1108 ASSERT_EQ(1ull, sc
);
1111 ASSERT_EQ(0, set_stripe_unit_count(&ioctx
, oid2
, su
, sc
));
1113 ASSERT_EQ(0, get_stripe_unit_count(&ioctx
, oid2
, &su
, &sc
));
1114 ASSERT_EQ(8192ull, su
);
1115 ASSERT_EQ(456ull, sc
);
1117 // su must not be larger than an object
1118 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 1 << 23, 1));
1119 // su must be a factor of object size
1120 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 511, 1));
1121 // su and sc must be non-zero
1122 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 0, 1));
1123 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 1, 0));
1124 ASSERT_EQ(-EINVAL
, set_stripe_unit_count(&ioctx
, oid2
, 0, 0));
1129 TEST_F(TestClsRbd
, get_mutable_metadata_features
)
1131 librados::IoCtx ioctx
;
1132 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1134 string oid
= get_temp_image_name();
1135 ASSERT_EQ(0, create_image(&ioctx
, oid
, 10, 22, RBD_FEATURE_EXCLUSIVE_LOCK
,
1138 uint64_t size
, features
, incompatible_features
;
1139 std::map
<rados::cls::lock::locker_id_t
,
1140 rados::cls::lock::locker_info_t
> lockers
;
1141 bool exclusive_lock
;
1142 std::string lock_tag
;
1143 ::SnapContext snapc
;
1146 ASSERT_EQ(0, get_mutable_metadata(&ioctx
, oid
, true, &size
, &features
,
1147 &incompatible_features
, &lockers
,
1148 &exclusive_lock
, &lock_tag
, &snapc
,
1150 ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK
), features
);
1151 ASSERT_EQ(0U, incompatible_features
);
1153 ASSERT_EQ(0, get_mutable_metadata(&ioctx
, oid
, false, &size
, &features
,
1154 &incompatible_features
, &lockers
,
1155 &exclusive_lock
, &lock_tag
, &snapc
,
1157 ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK
), features
);
1158 ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK
),
1159 incompatible_features
);
1164 TEST_F(TestClsRbd
, object_map_save
)
1166 librados::IoCtx ioctx
;
1167 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1169 string oid
= get_temp_image_name();
1170 BitVector
<2> ref_bit_vector
;
1171 ref_bit_vector
.resize(32);
1172 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1173 ref_bit_vector
[i
] = 1;
1176 librados::ObjectWriteOperation op
;
1177 object_map_save(&op
, ref_bit_vector
);
1178 ASSERT_EQ(0, ioctx
.operate(oid
, &op
));
1180 BitVector
<2> osd_bit_vector
;
1181 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1182 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1185 TEST_F(TestClsRbd
, object_map_resize
)
1187 librados::IoCtx ioctx
;
1188 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1190 string oid
= get_temp_image_name();
1191 BitVector
<2> ref_bit_vector
;
1192 ref_bit_vector
.resize(32);
1193 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1194 ref_bit_vector
[i
] = 1;
1197 librados::ObjectWriteOperation op1
;
1198 object_map_resize(&op1
, ref_bit_vector
.size(), 1);
1199 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1201 BitVector
<2> osd_bit_vector
;
1202 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1203 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1205 ref_bit_vector
.resize(64);
1206 for (uint64_t i
= 32; i
< ref_bit_vector
.size(); ++i
) {
1207 ref_bit_vector
[i
] = 2;
1210 librados::ObjectWriteOperation op2
;
1211 object_map_resize(&op2
, ref_bit_vector
.size(), 2);
1212 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1213 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1214 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1216 ref_bit_vector
.resize(32);
1218 librados::ObjectWriteOperation op3
;
1219 object_map_resize(&op3
, ref_bit_vector
.size(), 1);
1220 ASSERT_EQ(-ESTALE
, ioctx
.operate(oid
, &op3
));
1222 librados::ObjectWriteOperation op4
;
1223 object_map_resize(&op4
, ref_bit_vector
.size(), 2);
1224 ASSERT_EQ(0, ioctx
.operate(oid
, &op4
));
1226 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1227 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1232 TEST_F(TestClsRbd
, object_map_update
)
1234 librados::IoCtx ioctx
;
1235 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1237 string oid
= get_temp_image_name();
1238 BitVector
<2> ref_bit_vector
;
1239 ref_bit_vector
.resize(16);
1240 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1241 ref_bit_vector
[i
] = 2;
1244 BitVector
<2> osd_bit_vector
;
1246 librados::ObjectWriteOperation op1
;
1247 object_map_resize(&op1
, ref_bit_vector
.size(), 2);
1248 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1249 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1250 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1252 ref_bit_vector
[7] = 1;
1253 ref_bit_vector
[8] = 1;
1255 librados::ObjectWriteOperation op2
;
1256 object_map_update(&op2
, 7, 9, 1, boost::optional
<uint8_t>());
1257 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1258 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1259 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1261 ref_bit_vector
[7] = 3;
1262 ref_bit_vector
[8] = 3;
1264 librados::ObjectWriteOperation op3
;
1265 object_map_update(&op3
, 6, 10, 3, 1);
1266 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
1267 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1268 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1273 TEST_F(TestClsRbd
, object_map_load_enoent
)
1275 librados::IoCtx ioctx
;
1276 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1278 string oid
= get_temp_image_name();
1279 BitVector
<2> osd_bit_vector
;
1280 ASSERT_EQ(-ENOENT
, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1285 TEST_F(TestClsRbd
, object_map_snap_add
)
1287 librados::IoCtx ioctx
;
1288 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1290 string oid
= get_temp_image_name();
1291 BitVector
<2> ref_bit_vector
;
1292 ref_bit_vector
.resize(16);
1293 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1295 ref_bit_vector
[i
] = OBJECT_NONEXISTENT
;
1297 ref_bit_vector
[i
] = OBJECT_EXISTS
;
1301 BitVector
<2> osd_bit_vector
;
1303 librados::ObjectWriteOperation op1
;
1304 object_map_resize(&op1
, ref_bit_vector
.size(), OBJECT_EXISTS
);
1305 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1307 librados::ObjectWriteOperation op2
;
1308 object_map_update(&op2
, 0, 4, OBJECT_NONEXISTENT
, boost::optional
<uint8_t>());
1309 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1311 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1312 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1314 librados::ObjectWriteOperation op3
;
1315 object_map_snap_add(&op3
);
1316 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
1318 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1319 if (ref_bit_vector
[i
] == OBJECT_EXISTS
) {
1320 ref_bit_vector
[i
] = OBJECT_EXISTS_CLEAN
;
1324 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1325 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1328 TEST_F(TestClsRbd
, object_map_snap_remove
)
1330 librados::IoCtx ioctx
;
1331 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1333 string oid
= get_temp_image_name();
1334 BitVector
<2> ref_bit_vector
;
1335 ref_bit_vector
.resize(16);
1336 for (uint64_t i
= 0; i
< ref_bit_vector
.size(); ++i
) {
1338 ref_bit_vector
[i
] = OBJECT_EXISTS_CLEAN
;
1340 ref_bit_vector
[i
] = OBJECT_EXISTS
;
1344 BitVector
<2> osd_bit_vector
;
1346 librados::ObjectWriteOperation op1
;
1347 object_map_resize(&op1
, ref_bit_vector
.size(), OBJECT_EXISTS
);
1348 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1350 librados::ObjectWriteOperation op2
;
1351 object_map_update(&op2
, 0, 4, OBJECT_EXISTS_CLEAN
, boost::optional
<uint8_t>());
1352 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1354 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1355 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1357 BitVector
<2> snap_bit_vector
;
1358 snap_bit_vector
.resize(4);
1359 for (uint64_t i
= 0; i
< snap_bit_vector
.size(); ++i
) {
1360 if (i
== 1 || i
== 2) {
1361 snap_bit_vector
[i
] = OBJECT_EXISTS
;
1363 snap_bit_vector
[i
] = OBJECT_NONEXISTENT
;
1367 librados::ObjectWriteOperation op3
;
1368 object_map_snap_remove(&op3
, snap_bit_vector
);
1369 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
1371 ref_bit_vector
[1] = OBJECT_EXISTS
;
1372 ref_bit_vector
[2] = OBJECT_EXISTS
;
1373 ASSERT_EQ(0, object_map_load(&ioctx
, oid
, &osd_bit_vector
));
1374 ASSERT_EQ(ref_bit_vector
, osd_bit_vector
);
1377 TEST_F(TestClsRbd
, flags
)
1379 librados::IoCtx ioctx
;
1380 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1382 string oid
= get_temp_image_name();
1383 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
1386 std::vector
<snapid_t
> snap_ids
;
1387 std::vector
<uint64_t> snap_flags
;
1388 ASSERT_EQ(0, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1389 ASSERT_EQ(0U, flags
);
1391 librados::ObjectWriteOperation op1
;
1392 set_flags(&op1
, CEPH_NOSNAP
, 3, 2);
1393 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
1394 ASSERT_EQ(0, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1395 ASSERT_EQ(2U, flags
);
1397 uint64_t snap_id
= 10;
1398 snap_ids
.push_back(snap_id
);
1399 ASSERT_EQ(-ENOENT
, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1400 ASSERT_EQ(0, snapshot_add(&ioctx
, oid
, snap_id
, "snap"));
1402 librados::ObjectWriteOperation op2
;
1403 set_flags(&op2
, snap_id
, 31, 4);
1404 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
1405 ASSERT_EQ(0, get_flags(&ioctx
, oid
, &flags
, snap_ids
, &snap_flags
));
1406 ASSERT_EQ(2U, flags
);
1407 ASSERT_EQ(snap_ids
.size(), snap_flags
.size());
1408 ASSERT_EQ(6U, snap_flags
[0]);
1413 TEST_F(TestClsRbd
, metadata
)
1415 librados::IoCtx ioctx
;
1416 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1418 string oid
= get_temp_image_name();
1419 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, 0, oid
, -1));
1421 map
<string
, bufferlist
> pairs
;
1423 ASSERT_EQ(0, metadata_list(&ioctx
, oid
, "", 0, &pairs
));
1424 ASSERT_TRUE(pairs
.empty());
1426 pairs
["key1"].append("value1");
1427 pairs
["key2"].append("value2");
1428 ASSERT_EQ(0, metadata_set(&ioctx
, oid
, pairs
));
1429 ASSERT_EQ(0, metadata_get(&ioctx
, oid
, "key1", &value
));
1430 ASSERT_EQ(0, strcmp("value1", value
.c_str()));
1432 ASSERT_EQ(0, metadata_list(&ioctx
, oid
, "", 0, &pairs
));
1433 ASSERT_EQ(2U, pairs
.size());
1434 ASSERT_EQ(0, strncmp("value1", pairs
["key1"].c_str(), 6));
1435 ASSERT_EQ(0, strncmp("value2", pairs
["key2"].c_str(), 6));
1438 ASSERT_EQ(0, metadata_remove(&ioctx
, oid
, "key1"));
1439 ASSERT_EQ(0, metadata_remove(&ioctx
, oid
, "key3"));
1440 ASSERT_TRUE(metadata_get(&ioctx
, oid
, "key1", &value
) < 0);
1441 ASSERT_EQ(0, metadata_list(&ioctx
, oid
, "", 0, &pairs
));
1442 ASSERT_EQ(1U, pairs
.size());
1443 ASSERT_EQ(0, strncmp("value2", pairs
["key2"].c_str(), 6));
1446 char key
[10], val
[20];
1447 for (int i
= 0; i
< 1024; i
++) {
1448 sprintf(key
, "key%d", i
);
1449 sprintf(val
, "value%d", i
);
1450 pairs
[key
].append(val
, strlen(val
));
1452 ASSERT_EQ(0, metadata_set(&ioctx
, oid
, pairs
));
1454 string last_read
= "";
1455 uint64_t max_read
= 48, r
;
1457 map
<string
, bufferlist
> data
;
1459 map
<string
, bufferlist
> cur
;
1460 metadata_list(&ioctx
, oid
, last_read
, max_read
, &cur
);
1462 for (map
<string
, bufferlist
>::iterator it
= cur
.begin();
1463 it
!= cur
.end(); ++it
)
1464 data
[it
->first
] = it
->second
;
1465 last_read
= cur
.rbegin()->first
;
1467 } while (r
== max_read
);
1468 ASSERT_EQ(size
, 1024U);
1469 for (map
<string
, bufferlist
>::iterator it
= data
.begin();
1470 it
!= data
.end(); ++it
) {
1471 ASSERT_TRUE(it
->second
.contents_equal(pairs
[it
->first
]));
1477 TEST_F(TestClsRbd
, set_features
)
1479 librados::IoCtx ioctx
;
1480 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1482 string oid
= get_temp_image_name();
1483 uint64_t base_features
= RBD_FEATURE_LAYERING
| RBD_FEATURE_DEEP_FLATTEN
;
1484 ASSERT_EQ(0, create_image(&ioctx
, oid
, 0, 22, base_features
, oid
, -1));
1486 uint64_t features
= RBD_FEATURES_MUTABLE
;
1487 uint64_t mask
= RBD_FEATURES_MUTABLE
;
1488 ASSERT_EQ(0, set_features(&ioctx
, oid
, features
, mask
));
1490 uint64_t actual_features
;
1491 ASSERT_EQ(0, get_features(&ioctx
, oid
, CEPH_NOSNAP
, &actual_features
));
1493 uint64_t expected_features
= RBD_FEATURES_MUTABLE
| base_features
;
1494 ASSERT_EQ(expected_features
, actual_features
);
1497 mask
= RBD_FEATURE_OBJECT_MAP
;
1498 ASSERT_EQ(0, set_features(&ioctx
, oid
, features
, mask
));
1500 ASSERT_EQ(0, get_features(&ioctx
, oid
, CEPH_NOSNAP
, &actual_features
));
1502 expected_features
= (RBD_FEATURES_MUTABLE
| base_features
) &
1503 ~RBD_FEATURE_OBJECT_MAP
;
1504 ASSERT_EQ(expected_features
, actual_features
);
1506 ASSERT_EQ(0, set_features(&ioctx
, oid
, 0, RBD_FEATURE_DEEP_FLATTEN
));
1507 ASSERT_EQ(-EINVAL
, set_features(&ioctx
, oid
, RBD_FEATURE_DEEP_FLATTEN
,
1508 RBD_FEATURE_DEEP_FLATTEN
));
1510 ASSERT_EQ(-EINVAL
, set_features(&ioctx
, oid
, 0, RBD_FEATURE_LAYERING
));
1513 TEST_F(TestClsRbd
, mirror
) {
1514 librados::IoCtx ioctx
;
1515 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1516 ioctx
.remove(RBD_MIRRORING
);
1518 std::vector
<cls::rbd::MirrorPeer
> peers
;
1519 ASSERT_EQ(-ENOENT
, mirror_peer_list(&ioctx
, &peers
));
1522 ASSERT_EQ(-ENOENT
, mirror_uuid_get(&ioctx
, &uuid
));
1523 ASSERT_EQ(-EINVAL
, mirror_peer_add(&ioctx
, "uuid1", "cluster1", "client"));
1525 cls::rbd::MirrorMode mirror_mode
;
1526 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1527 ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED
, mirror_mode
);
1529 ASSERT_EQ(-EINVAL
, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_IMAGE
));
1530 ASSERT_EQ(-EINVAL
, mirror_uuid_set(&ioctx
, ""));
1531 ASSERT_EQ(0, mirror_uuid_set(&ioctx
, "mirror-uuid"));
1532 ASSERT_EQ(0, mirror_uuid_get(&ioctx
, &uuid
));
1533 ASSERT_EQ("mirror-uuid", uuid
);
1535 ASSERT_EQ(0, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_IMAGE
));
1536 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1537 ASSERT_EQ(cls::rbd::MIRROR_MODE_IMAGE
, mirror_mode
);
1539 ASSERT_EQ(-EINVAL
, mirror_uuid_set(&ioctx
, "new-mirror-uuid"));
1541 ASSERT_EQ(0, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_POOL
));
1542 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1543 ASSERT_EQ(cls::rbd::MIRROR_MODE_POOL
, mirror_mode
);
1545 ASSERT_EQ(-EINVAL
, mirror_peer_add(&ioctx
, "mirror-uuid", "cluster1", "client"));
1546 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid1", "cluster1", "client"));
1547 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid2", "cluster2", "admin"));
1548 ASSERT_EQ(-ESTALE
, mirror_peer_add(&ioctx
, "uuid2", "cluster3", "foo"));
1549 ASSERT_EQ(-EEXIST
, mirror_peer_add(&ioctx
, "uuid3", "cluster1", "foo"));
1550 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid3", "cluster3", "admin", 123));
1551 ASSERT_EQ(-EEXIST
, mirror_peer_add(&ioctx
, "uuid4", "cluster3", "admin"));
1552 ASSERT_EQ(-EEXIST
, mirror_peer_add(&ioctx
, "uuid4", "cluster3", "admin", 123));
1553 ASSERT_EQ(0, mirror_peer_add(&ioctx
, "uuid4", "cluster3", "admin", 234));
1555 ASSERT_EQ(0, mirror_peer_list(&ioctx
, &peers
));
1556 std::vector
<cls::rbd::MirrorPeer
> expected_peers
= {
1557 {"uuid1", "cluster1", "client", -1},
1558 {"uuid2", "cluster2", "admin", -1},
1559 {"uuid3", "cluster3", "admin", 123},
1560 {"uuid4", "cluster3", "admin", 234}};
1561 ASSERT_EQ(expected_peers
, peers
);
1563 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid5"));
1564 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid4"));
1565 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid2"));
1567 ASSERT_EQ(-ENOENT
, mirror_peer_set_client(&ioctx
, "uuid4", "new client"));
1568 ASSERT_EQ(0, mirror_peer_set_client(&ioctx
, "uuid1", "new client"));
1570 ASSERT_EQ(-ENOENT
, mirror_peer_set_cluster(&ioctx
, "uuid4", "new cluster"));
1571 ASSERT_EQ(0, mirror_peer_set_cluster(&ioctx
, "uuid3", "new cluster"));
1573 ASSERT_EQ(0, mirror_peer_list(&ioctx
, &peers
));
1575 {"uuid1", "cluster1", "new client", -1},
1576 {"uuid3", "new cluster", "admin", 123}};
1577 ASSERT_EQ(expected_peers
, peers
);
1578 ASSERT_EQ(-EBUSY
, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_DISABLED
));
1580 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid3"));
1581 ASSERT_EQ(0, mirror_peer_remove(&ioctx
, "uuid1"));
1582 ASSERT_EQ(0, mirror_peer_list(&ioctx
, &peers
));
1583 expected_peers
= {};
1584 ASSERT_EQ(expected_peers
, peers
);
1586 ASSERT_EQ(0, mirror_mode_set(&ioctx
, cls::rbd::MIRROR_MODE_DISABLED
));
1587 ASSERT_EQ(0, mirror_mode_get(&ioctx
, &mirror_mode
));
1588 ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED
, mirror_mode
);
1589 ASSERT_EQ(-ENOENT
, mirror_uuid_get(&ioctx
, &uuid
));
1592 TEST_F(TestClsRbd
, mirror_image
) {
1593 librados::IoCtx ioctx
;
1594 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1595 ioctx
.remove(RBD_MIRRORING
);
1597 std::map
<std::string
, std::string
> mirror_image_ids
;
1598 ASSERT_EQ(-ENOENT
, mirror_image_list(&ioctx
, "", 0, &mirror_image_ids
));
1600 cls::rbd::MirrorImage
image1("uuid1", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1601 cls::rbd::MirrorImage
image2("uuid2", cls::rbd::MIRROR_IMAGE_STATE_DISABLING
);
1602 cls::rbd::MirrorImage
image3("uuid3", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1604 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1605 ASSERT_EQ(-ENOENT
, mirror_image_set(&ioctx
, "image_id2", image2
));
1606 image2
.state
= cls::rbd::MIRROR_IMAGE_STATE_ENABLED
;
1607 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1608 image2
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1609 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1610 ASSERT_EQ(-EINVAL
, mirror_image_set(&ioctx
, "image_id1", image2
));
1611 ASSERT_EQ(-EEXIST
, mirror_image_set(&ioctx
, "image_id3", image2
));
1612 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1614 std::string image_id
;
1615 ASSERT_EQ(0, mirror_image_get_image_id(&ioctx
, "uuid2", &image_id
));
1616 ASSERT_EQ("image_id2", image_id
);
1618 cls::rbd::MirrorImage read_image
;
1619 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id1", &read_image
));
1620 ASSERT_EQ(read_image
, image1
);
1621 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id2", &read_image
));
1622 ASSERT_EQ(read_image
, image2
);
1623 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id3", &read_image
));
1624 ASSERT_EQ(read_image
, image3
);
1626 ASSERT_EQ(0, mirror_image_list(&ioctx
, "", 1, &mirror_image_ids
));
1627 std::map
<std::string
, std::string
> expected_mirror_image_ids
= {
1628 {"image_id1", "uuid1"}};
1629 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1631 ASSERT_EQ(0, mirror_image_list(&ioctx
, "image_id1", 2, &mirror_image_ids
));
1632 expected_mirror_image_ids
= {{"image_id2", "uuid2"}, {"image_id3", "uuid3"}};
1633 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1635 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id2"));
1636 ASSERT_EQ(-ENOENT
, mirror_image_get_image_id(&ioctx
, "uuid2", &image_id
));
1637 ASSERT_EQ(-EBUSY
, mirror_image_remove(&ioctx
, "image_id1"));
1639 ASSERT_EQ(0, mirror_image_list(&ioctx
, "", 3, &mirror_image_ids
));
1640 expected_mirror_image_ids
= {{"image_id1", "uuid1"}, {"image_id3", "uuid3"}};
1641 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1643 image1
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1644 image3
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1645 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1646 ASSERT_EQ(0, mirror_image_get(&ioctx
, "image_id1", &read_image
));
1647 ASSERT_EQ(read_image
, image1
);
1648 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1649 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id1"));
1650 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id3"));
1652 ASSERT_EQ(0, mirror_image_list(&ioctx
, "", 3, &mirror_image_ids
));
1653 expected_mirror_image_ids
= {};
1654 ASSERT_EQ(expected_mirror_image_ids
, mirror_image_ids
);
1657 TEST_F(TestClsRbd
, mirror_image_status
) {
1658 struct WatchCtx
: public librados::WatchCtx2
{
1659 librados::IoCtx
*m_ioctx
;
1661 WatchCtx(librados::IoCtx
*ioctx
) : m_ioctx(ioctx
) {}
1662 void handle_notify(uint64_t notify_id
, uint64_t cookie
,
1663 uint64_t notifier_id
, bufferlist
& bl_
) override
{
1665 m_ioctx
->notify_ack(RBD_MIRRORING
, notify_id
, cookie
, bl
);
1667 void handle_error(uint64_t cookie
, int err
) override
{}
1670 map
<std::string
, cls::rbd::MirrorImage
> images
;
1671 map
<std::string
, cls::rbd::MirrorImageStatus
> statuses
;
1672 std::map
<cls::rbd::MirrorImageStatusState
, int> states
;
1673 cls::rbd::MirrorImageStatus read_status
;
1674 uint64_t watch_handle
;
1675 librados::IoCtx ioctx
;
1677 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1678 ioctx
.remove(RBD_MIRRORING
);
1680 // Test list fails on nonexistent RBD_MIRRORING object
1682 ASSERT_EQ(-ENOENT
, mirror_image_status_list(&ioctx
, "", 1024, &images
,
1687 cls::rbd::MirrorImage
image1("uuid1", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1688 cls::rbd::MirrorImage
image2("uuid2", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1689 cls::rbd::MirrorImage
image3("uuid3", cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1691 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1692 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1693 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1695 cls::rbd::MirrorImageStatus
status1(cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
);
1696 cls::rbd::MirrorImageStatus
status2(cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
);
1697 cls::rbd::MirrorImageStatus
status3(cls::rbd::MIRROR_IMAGE_STATUS_STATE_ERROR
);
1699 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1702 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1703 ASSERT_EQ(3U, images
.size());
1704 ASSERT_EQ(1U, statuses
.size());
1706 // Test status is down due to RBD_MIRRORING is not watched
1709 ASSERT_EQ(statuses
["image_id1"], status1
);
1710 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1711 ASSERT_EQ(read_status
, status1
);
1713 // Test status summary. All statuses are unknown due to down.
1715 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1716 ASSERT_EQ(1U, states
.size());
1717 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1719 // Test remove_down removes stale statuses
1721 ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx
));
1722 ASSERT_EQ(-ENOENT
, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1723 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1724 ASSERT_EQ(3U, images
.size());
1725 ASSERT_TRUE(statuses
.empty());
1726 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1727 ASSERT_EQ(1U, states
.size());
1728 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1730 // Test statuses are not down after watcher is started
1732 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1734 WatchCtx
watch_ctx(&ioctx
);
1735 ASSERT_EQ(0, ioctx
.watch2(RBD_MIRRORING
, &watch_handle
, &watch_ctx
));
1737 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid2", status2
));
1738 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid3", status3
));
1740 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1742 ASSERT_EQ(read_status
, status1
);
1743 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid2", &read_status
));
1745 ASSERT_EQ(read_status
, status2
);
1746 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid3", &read_status
));
1748 ASSERT_EQ(read_status
, status3
);
1752 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1753 ASSERT_EQ(3U, images
.size());
1754 ASSERT_EQ(3U, statuses
.size());
1755 ASSERT_EQ(statuses
["image_id1"], status1
);
1756 ASSERT_EQ(statuses
["image_id2"], status2
);
1757 ASSERT_EQ(statuses
["image_id3"], status3
);
1759 ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx
));
1760 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1761 ASSERT_EQ(read_status
, status1
);
1764 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1765 ASSERT_EQ(3U, images
.size());
1766 ASSERT_EQ(3U, statuses
.size());
1767 ASSERT_EQ(statuses
["image_id1"], status1
);
1768 ASSERT_EQ(statuses
["image_id2"], status2
);
1769 ASSERT_EQ(statuses
["image_id3"], status3
);
1772 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1773 ASSERT_EQ(3U, states
.size());
1774 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1775 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
]);
1776 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_ERROR
]);
1780 status1
.state
= status3
.state
= cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
;
1781 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1782 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid3", status3
));
1783 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid3", &read_status
));
1784 ASSERT_EQ(read_status
, status3
);
1787 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1788 ASSERT_EQ(1U, states
.size());
1789 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
]);
1793 ASSERT_EQ(0, mirror_image_status_remove(&ioctx
, "uuid3"));
1794 ASSERT_EQ(-ENOENT
, mirror_image_status_get(&ioctx
, "uuid3", &read_status
));
1797 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1798 ASSERT_EQ(3U, images
.size());
1799 ASSERT_EQ(2U, statuses
.size());
1800 ASSERT_EQ(statuses
["image_id1"], status1
);
1801 ASSERT_EQ(statuses
["image_id2"], status2
);
1804 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1805 ASSERT_EQ(2U, states
.size());
1806 ASSERT_EQ(1, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1807 ASSERT_EQ(2, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING
]);
1809 // Test statuses are down after removing watcher
1811 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid1", status1
));
1812 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid2", status2
));
1813 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, "uuid3", status3
));
1817 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1818 ASSERT_EQ(3U, images
.size());
1819 ASSERT_EQ(3U, statuses
.size());
1820 ASSERT_EQ(statuses
["image_id1"], status1
);
1821 ASSERT_EQ(statuses
["image_id2"], status2
);
1822 ASSERT_EQ(statuses
["image_id3"], status3
);
1824 ioctx
.unwatch2(watch_handle
);
1826 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1827 ASSERT_EQ(3U, images
.size());
1828 ASSERT_EQ(3U, statuses
.size());
1830 ASSERT_EQ(statuses
["image_id1"], status1
);
1832 ASSERT_EQ(statuses
["image_id2"], status2
);
1834 ASSERT_EQ(statuses
["image_id3"], status3
);
1836 ASSERT_EQ(0, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1837 ASSERT_EQ(read_status
, status1
);
1840 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1841 ASSERT_EQ(1U, states
.size());
1842 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1844 ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx
));
1845 ASSERT_EQ(-ENOENT
, mirror_image_status_get(&ioctx
, "uuid1", &read_status
));
1849 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, "", 1024, &images
, &statuses
));
1850 ASSERT_EQ(3U, images
.size());
1851 ASSERT_TRUE(statuses
.empty());
1854 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1855 ASSERT_EQ(1U, states
.size());
1856 ASSERT_EQ(3, states
[cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
]);
1860 image1
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1861 image2
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1862 image3
.state
= cls::rbd::MIRROR_IMAGE_STATE_DISABLING
;
1864 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id1", image1
));
1865 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id2", image2
));
1866 ASSERT_EQ(0, mirror_image_set(&ioctx
, "image_id3", image3
));
1868 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id1"));
1869 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id2"));
1870 ASSERT_EQ(0, mirror_image_remove(&ioctx
, "image_id3"));
1873 ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx
, &states
));
1874 ASSERT_EQ(0U, states
.size());
1876 // Test status list with large number of images
1879 ASSERT_EQ(0U, N
% 2);
1881 for (size_t i
= 0; i
< N
; i
++) {
1882 std::string id
= "id" + stringify(i
);
1883 std::string uuid
= "uuid" + stringify(i
);
1884 cls::rbd::MirrorImage
image(uuid
, cls::rbd::MIRROR_IMAGE_STATE_ENABLED
);
1885 cls::rbd::MirrorImageStatus
status(cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
);
1886 ASSERT_EQ(0, mirror_image_set(&ioctx
, id
, image
));
1887 ASSERT_EQ(0, mirror_image_status_set(&ioctx
, uuid
, status
));
1890 std::string last_read
= "";
1893 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
* 2, &images
,
1895 ASSERT_EQ(N
, images
.size());
1896 ASSERT_EQ(N
, statuses
.size());
1900 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
/ 2, &images
,
1902 ASSERT_EQ(N
/ 2, images
.size());
1903 ASSERT_EQ(N
/ 2, statuses
.size());
1905 last_read
= images
.rbegin()->first
;
1908 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
/ 2, &images
,
1910 ASSERT_EQ(N
/ 2, images
.size());
1911 ASSERT_EQ(N
/ 2, statuses
.size());
1913 last_read
= images
.rbegin()->first
;
1916 ASSERT_EQ(0, mirror_image_status_list(&ioctx
, last_read
, N
/ 2, &images
,
1918 ASSERT_EQ(0U, images
.size());
1919 ASSERT_EQ(0U, statuses
.size());
1922 TEST_F(TestClsRbd
, mirror_instances
) {
1923 librados::IoCtx ioctx
;
1924 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1925 ioctx
.remove(RBD_MIRROR_LEADER
);
1927 std::vector
<std::string
> instance_ids
;
1928 ASSERT_EQ(-ENOENT
, mirror_instances_list(&ioctx
, &instance_ids
));
1930 ASSERT_EQ(0, ioctx
.create(RBD_MIRROR_LEADER
, true));
1931 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1932 ASSERT_EQ(0U, instance_ids
.size());
1934 ASSERT_EQ(0, mirror_instances_add(&ioctx
, "instance_id1"));
1935 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1936 ASSERT_EQ(1U, instance_ids
.size());
1937 ASSERT_EQ(instance_ids
[0], "instance_id1");
1939 ASSERT_EQ(0, mirror_instances_add(&ioctx
, "instance_id1"));
1940 ASSERT_EQ(0, mirror_instances_add(&ioctx
, "instance_id2"));
1941 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1942 ASSERT_EQ(2U, instance_ids
.size());
1944 ASSERT_EQ(0, mirror_instances_remove(&ioctx
, "instance_id1"));
1945 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1946 ASSERT_EQ(1U, instance_ids
.size());
1947 ASSERT_EQ(instance_ids
[0], "instance_id2");
1949 ASSERT_EQ(0, mirror_instances_remove(&ioctx
, "instance_id2"));
1950 ASSERT_EQ(0, mirror_instances_list(&ioctx
, &instance_ids
));
1951 ASSERT_EQ(0U, instance_ids
.size());
1954 TEST_F(TestClsRbd
, group_create
) {
1955 librados::IoCtx ioctx
;
1956 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1958 string group_id
= "group_id";
1959 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
1963 ASSERT_EQ(0, ioctx
.stat(group_id
, &psize
, &pmtime
));
1966 TEST_F(TestClsRbd
, group_dir_list
) {
1967 librados::IoCtx ioctx
;
1968 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
1970 string group_id1
= "cgid1";
1971 string group_name1
= "cgname1";
1972 string group_id2
= "cgid2";
1973 string group_name2
= "cgname2";
1974 ASSERT_EQ(0, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name1
, group_id1
));
1975 ASSERT_EQ(0, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name2
, group_id2
));
1977 map
<string
, string
> cgs
;
1978 ASSERT_EQ(0, group_dir_list(&ioctx
, RBD_GROUP_DIRECTORY
, "", 10, &cgs
));
1980 ASSERT_EQ(2U, cgs
.size());
1982 auto it
= cgs
.begin();
1983 ASSERT_EQ(group_id1
, it
->second
);
1984 ASSERT_EQ(group_name1
, it
->first
);
1987 ASSERT_EQ(group_id2
, it
->second
);
1988 ASSERT_EQ(group_name2
, it
->first
);
1991 void add_group_to_dir(librados::IoCtx ioctx
, string group_id
, string group_name
) {
1992 ASSERT_EQ(0, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
1995 ASSERT_EQ(0, ioctx
.omap_get_keys(RBD_GROUP_DIRECTORY
, "", 10, &keys
));
1996 ASSERT_EQ(2U, keys
.size());
1997 ASSERT_EQ("id_" + group_id
, *keys
.begin());
1998 ASSERT_EQ("name_" + group_name
, *keys
.rbegin());
2001 TEST_F(TestClsRbd
, group_dir_add
) {
2002 librados::IoCtx ioctx
;
2003 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2004 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2006 string group_id
= "cgid";
2007 string group_name
= "cgname";
2008 add_group_to_dir(ioctx
, group_id
, group_name
);
2011 TEST_F(TestClsRbd
, dir_add_already_existing
) {
2012 librados::IoCtx ioctx
;
2013 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2014 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2016 string group_id
= "cgidexisting";
2017 string group_name
= "cgnameexisting";
2018 add_group_to_dir(ioctx
, group_id
, group_name
);
2020 ASSERT_EQ(-EEXIST
, group_dir_add(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2023 TEST_F(TestClsRbd
, group_dir_remove
) {
2024 librados::IoCtx ioctx
;
2025 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2026 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2028 string group_id
= "cgidtodel";
2029 string group_name
= "cgnametodel";
2030 add_group_to_dir(ioctx
, group_id
, group_name
);
2032 ASSERT_EQ(0, group_dir_remove(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2035 ASSERT_EQ(0, ioctx
.omap_get_keys(RBD_GROUP_DIRECTORY
, "", 10, &keys
));
2036 ASSERT_EQ(0U, keys
.size());
2039 TEST_F(TestClsRbd
, group_dir_remove_missing
) {
2040 librados::IoCtx ioctx
;
2041 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2042 ioctx
.remove(RBD_GROUP_DIRECTORY
);
2044 string group_id
= "cgidtodelmissing";
2045 string group_name
= "cgnametodelmissing";
2046 // These two lines ensure that RBD_GROUP_DIRECTORY exists. It's important for the
2048 add_group_to_dir(ioctx
, group_id
, group_name
);
2050 ASSERT_EQ(0, group_dir_remove(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2053 ASSERT_EQ(-ENOENT
, group_dir_remove(&ioctx
, RBD_GROUP_DIRECTORY
, group_name
, group_id
));
2056 ASSERT_EQ(0, ioctx
.omap_get_keys(RBD_GROUP_DIRECTORY
, "", 10, &keys
));
2057 ASSERT_EQ(0U, keys
.size());
2060 void test_image_add(librados::IoCtx
&ioctx
, const string
& group_id
,
2061 const string
& image_id
, int64_t pool_id
) {
2063 cls::rbd::GroupImageStatus
st(image_id
, pool_id
,
2064 cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE
);
2065 ASSERT_EQ(0, group_image_set(&ioctx
, group_id
, st
));
2068 ASSERT_EQ(0, ioctx
.omap_get_keys(group_id
, "", 10, &keys
));
2070 auto it
= keys
.begin();
2071 ASSERT_EQ(2U, keys
.size());
2073 string image_key
= cls::rbd::GroupImageSpec(image_id
, pool_id
).image_key();
2074 ASSERT_EQ(image_key
, *it
);
2076 ASSERT_EQ("snap_seq", *it
);
2079 TEST_F(TestClsRbd
, group_image_add
) {
2080 librados::IoCtx ioctx
;
2081 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2083 string group_id
= "group_id";
2084 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2086 int64_t pool_id
= ioctx
.get_id();
2087 string image_id
= "image_id";
2088 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2091 TEST_F(TestClsRbd
, group_image_remove
) {
2092 librados::IoCtx ioctx
;
2093 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2095 string group_id
= "group_id";
2096 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2098 int64_t pool_id
= ioctx
.get_id();
2099 string image_id
= "image_id";
2100 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2102 cls::rbd::GroupImageSpec
spec(image_id
, pool_id
);
2103 ASSERT_EQ(0, group_image_remove(&ioctx
, group_id
, spec
));
2105 ASSERT_EQ(0, ioctx
.omap_get_keys(group_id
, "", 10, &keys
));
2106 ASSERT_EQ(1U, keys
.size());
2107 ASSERT_EQ("snap_seq", *(keys
.begin()));
2110 TEST_F(TestClsRbd
, group_image_list
) {
2111 librados::IoCtx ioctx
;
2112 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2114 string group_id
= "group_id";
2115 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2117 int64_t pool_id
= ioctx
.get_id();
2118 string image_id
= "imageid"; // Image id shouldn't contain underscores
2119 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2121 vector
<cls::rbd::GroupImageStatus
> images
;
2122 cls::rbd::GroupImageSpec empty_image_spec
= cls::rbd::GroupImageSpec();
2123 ASSERT_EQ(0, group_image_list(&ioctx
, group_id
, empty_image_spec
, 1024,
2125 ASSERT_EQ(1U, images
.size());
2126 ASSERT_EQ(image_id
, images
[0].spec
.image_id
);
2127 ASSERT_EQ(pool_id
, images
[0].spec
.pool_id
);
2128 ASSERT_EQ(cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE
, images
[0].state
);
2130 cls::rbd::GroupImageStatus last_image
= *images
.rbegin();
2131 ASSERT_EQ(0, group_image_list(&ioctx
, group_id
, last_image
.spec
, 1024,
2133 ASSERT_EQ(0U, images
.size());
2136 TEST_F(TestClsRbd
, group_image_clean
) {
2137 librados::IoCtx ioctx
;
2138 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2140 string group_id
= "group_id1";
2141 ASSERT_EQ(0, group_create(&ioctx
, group_id
));
2143 int64_t pool_id
= ioctx
.get_id();
2144 string image_id
= "image_id";
2145 test_image_add(ioctx
, group_id
, image_id
, pool_id
);
2147 cls::rbd::GroupImageStatus
incomplete_st(image_id
, pool_id
,
2148 cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE
);
2150 ASSERT_EQ(0, group_image_set(&ioctx
, group_id
, incomplete_st
));
2151 // Set to dirty first in order to make sure that group_image_clean
2152 // actually does something.
2153 cls::rbd::GroupImageStatus
attached_st(image_id
, pool_id
,
2154 cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED
);
2155 ASSERT_EQ(0, group_image_set(&ioctx
, group_id
, attached_st
));
2157 string image_key
= cls::rbd::GroupImageSpec(image_id
, pool_id
).image_key();
2159 map
<string
, bufferlist
> vals
;
2160 ASSERT_EQ(0, ioctx
.omap_get_vals(group_id
, "", 10, &vals
));
2162 cls::rbd::GroupImageLinkState ref_state
;
2163 bufferlist::iterator it
= vals
[image_key
].begin();
2164 ::decode(ref_state
, it
);
2165 ASSERT_EQ(cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED
, ref_state
);
2168 TEST_F(TestClsRbd
, image_add_group
) {
2169 librados::IoCtx ioctx
;
2170 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2172 int64_t pool_id
= ioctx
.get_id();
2173 string image_id
= "imageid";
2175 ASSERT_EQ(0, create_image(&ioctx
, image_id
, 2<<20, 0,
2176 RBD_FEATURE_LAYERING
, image_id
, -1));
2178 string group_id
= "group_id";
2180 cls::rbd::GroupSpec
spec(group_id
, pool_id
);
2181 ASSERT_EQ(0, image_add_group(&ioctx
, image_id
, spec
));
2183 map
<string
, bufferlist
> vals
;
2184 ASSERT_EQ(0, ioctx
.omap_get_vals(image_id
, "", RBD_GROUP_REF
, 10, &vals
));
2186 cls::rbd::GroupSpec val_spec
;
2187 bufferlist::iterator it
= vals
[RBD_GROUP_REF
].begin();
2188 ::decode(val_spec
, it
);
2190 ASSERT_EQ(group_id
, val_spec
.group_id
);
2191 ASSERT_EQ(pool_id
, val_spec
.pool_id
);
2194 TEST_F(TestClsRbd
, image_remove_group
) {
2195 librados::IoCtx ioctx
;
2196 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2198 int64_t pool_id
= ioctx
.get_id();
2199 string image_id
= "image_id";
2201 ASSERT_EQ(0, create_image(&ioctx
, image_id
, 2<<20, 0,
2202 RBD_FEATURE_LAYERING
, image_id
, -1));
2204 string group_id
= "group_id";
2206 cls::rbd::GroupSpec
spec(group_id
, pool_id
);
2207 ASSERT_EQ(0, image_add_group(&ioctx
, image_id
, spec
));
2208 // Add reference in order to make sure that image_remove_group actually
2210 ASSERT_EQ(0, image_remove_group(&ioctx
, image_id
, spec
));
2212 map
<string
, bufferlist
> vals
;
2213 ASSERT_EQ(0, ioctx
.omap_get_vals(image_id
, "", RBD_GROUP_REF
, 10, &vals
));
2215 ASSERT_EQ(0U, vals
.size());
2218 TEST_F(TestClsRbd
, image_get_group
) {
2219 librados::IoCtx ioctx
;
2220 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2222 int64_t pool_id
= ioctx
.get_id();
2223 string image_id
= "imageidgroupspec";
2225 ASSERT_EQ(0, create_image(&ioctx
, image_id
, 2<<20, 0,
2226 RBD_FEATURE_LAYERING
, image_id
, -1));
2228 string group_id
= "group_id_get_group_spec";
2230 cls::rbd::GroupSpec
spec_add(group_id
, pool_id
);
2231 ASSERT_EQ(0, image_add_group(&ioctx
, image_id
, spec_add
));
2233 cls::rbd::GroupSpec spec
;
2234 ASSERT_EQ(0, image_get_group(&ioctx
, image_id
, &spec
));
2236 ASSERT_EQ(group_id
, spec
.group_id
);
2237 ASSERT_EQ(pool_id
, spec
.pool_id
);
2240 TEST_F(TestClsRbd
, trash_methods
)
2242 librados::IoCtx ioctx
;
2243 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
2245 string id
= "123456789";
2246 string id2
= "123456780";
2248 std::map
<string
, cls::rbd::TrashImageSpec
> entries
;
2249 ASSERT_EQ(-ENOENT
, trash_list(&ioctx
, "", 1024, &entries
));
2251 utime_t now1
= ceph_clock_now();
2252 utime_t now1_delay
= now1
;
2254 cls::rbd::TrashImageSpec
trash_spec(cls::rbd::TRASH_IMAGE_SOURCE_USER
, "name",
2256 ASSERT_EQ(0, trash_add(&ioctx
, id
, trash_spec
));
2258 utime_t now2
= ceph_clock_now();
2259 utime_t now2_delay
= now2
;
2261 cls::rbd::TrashImageSpec
trash_spec2(cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING
,
2262 "name2", now2
, now2_delay
);
2263 ASSERT_EQ(-EEXIST
, trash_add(&ioctx
, id
, trash_spec2
));
2265 ASSERT_EQ(0, trash_remove(&ioctx
, id
));
2266 ASSERT_EQ(-ENOENT
, trash_remove(&ioctx
, id
));
2268 ASSERT_EQ(0, trash_list(&ioctx
, "", 1024, &entries
));
2269 ASSERT_TRUE(entries
.empty());
2271 ASSERT_EQ(0, trash_add(&ioctx
, id
, trash_spec2
));
2272 ASSERT_EQ(0, trash_add(&ioctx
, id2
, trash_spec
));
2274 ASSERT_EQ(0, trash_list(&ioctx
, "", 1, &entries
));
2275 ASSERT_TRUE(entries
.find(id2
) != entries
.end());
2276 ASSERT_EQ(cls::rbd::TRASH_IMAGE_SOURCE_USER
, entries
[id2
].source
);
2277 ASSERT_EQ(std::string("name"), entries
[id2
].name
);
2278 ASSERT_EQ(now1
, entries
[id2
].deletion_time
);
2279 ASSERT_EQ(now1_delay
, entries
[id2
].deferment_end_time
);
2281 ASSERT_EQ(0, trash_list(&ioctx
, id2
, 1, &entries
));
2282 ASSERT_TRUE(entries
.find(id
) != entries
.end());
2283 ASSERT_EQ(cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING
, entries
[id
].source
);
2284 ASSERT_EQ(std::string("name2"), entries
[id
].name
);
2285 ASSERT_EQ(now2
, entries
[id
].deletion_time
);
2286 ASSERT_EQ(now2_delay
, entries
[id
].deferment_end_time
);
2288 ASSERT_EQ(0, trash_list(&ioctx
, id
, 1, &entries
));
2289 ASSERT_TRUE(entries
.empty());
2291 cls::rbd::TrashImageSpec spec_res1
;
2292 ASSERT_EQ(0, trash_get(&ioctx
, id
, &spec_res1
));
2293 cls::rbd::TrashImageSpec spec_res2
;
2294 ASSERT_EQ(0, trash_get(&ioctx
, id2
, &spec_res2
));
2296 ASSERT_EQ(spec_res1
.name
, "name2");
2297 ASSERT_EQ(spec_res1
.deletion_time
, now2
);
2298 ASSERT_EQ(spec_res1
.deferment_end_time
, now2_delay
);
2300 ASSERT_EQ(spec_res2
.name
, "name");
2301 ASSERT_EQ(spec_res2
.deletion_time
, now1
);
2302 ASSERT_EQ(spec_res2
.deferment_end_time
, now1_delay
);