1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "test/librbd/test_fixture.h"
4 #include "test/librbd/test_support.h"
5 #include "librbd/ExclusiveLock.h"
6 #include "librbd/ImageCtx.h"
7 #include "librbd/ImageState.h"
8 #include "librbd/ImageWatcher.h"
9 #include "librbd/internal.h"
10 #include "librbd/ObjectMap.h"
11 #include "cls/rbd/cls_rbd_client.h"
14 void register_test_object_map() {
17 class TestObjectMap
: public TestFixture
{
20 int when_open_object_map(librbd::ImageCtx
*ictx
) {
22 librbd::ObjectMap
<> object_map(*ictx
, ictx
->snap_id
);
23 object_map
.open(&ctx
);
28 TEST_F(TestObjectMap
, RefreshInvalidatesWhenCorrupt
) {
29 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
31 librbd::ImageCtx
*ictx
;
32 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
34 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
36 ASSERT_FALSE(flags_set
);
40 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
41 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
43 ASSERT_EQ(0, lock_ctx
.wait());
45 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
48 ASSERT_EQ(0, ictx
->md_ctx
.write_full(oid
, bl
));
50 ASSERT_EQ(0, when_open_object_map(ictx
));
51 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
53 ASSERT_TRUE(flags_set
);
56 TEST_F(TestObjectMap
, RefreshInvalidatesWhenTooSmall
) {
57 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
59 librbd::ImageCtx
*ictx
;
60 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
62 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
64 ASSERT_FALSE(flags_set
);
68 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
69 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
71 ASSERT_EQ(0, lock_ctx
.wait());
73 librados::ObjectWriteOperation op
;
74 librbd::cls_client::object_map_resize(&op
, 0, OBJECT_NONEXISTENT
);
76 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
77 ASSERT_EQ(0, ictx
->md_ctx
.operate(oid
, &op
));
79 ASSERT_EQ(0, when_open_object_map(ictx
));
80 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
82 ASSERT_TRUE(flags_set
);
85 TEST_F(TestObjectMap
, InvalidateFlagOnDisk
) {
86 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
88 librbd::ImageCtx
*ictx
;
89 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
91 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
93 ASSERT_FALSE(flags_set
);
97 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
98 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
100 ASSERT_EQ(0, lock_ctx
.wait());
102 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
104 bl
.append("corrupt");
105 ASSERT_EQ(0, ictx
->md_ctx
.write_full(oid
, bl
));
107 ASSERT_EQ(0, when_open_object_map(ictx
));
108 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
110 ASSERT_TRUE(flags_set
);
112 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
113 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
115 ASSERT_TRUE(flags_set
);
118 TEST_F(TestObjectMap
, AcquireLockInvalidatesWhenTooSmall
) {
119 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
121 librbd::ImageCtx
*ictx
;
122 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
124 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
126 ASSERT_FALSE(flags_set
);
128 librados::ObjectWriteOperation op
;
129 librbd::cls_client::object_map_resize(&op
, 0, OBJECT_NONEXISTENT
);
131 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
132 ASSERT_EQ(0, ictx
->md_ctx
.operate(oid
, &op
));
134 C_SaferCond lock_ctx
;
136 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
137 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
139 ASSERT_EQ(0, lock_ctx
.wait());
141 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
143 ASSERT_TRUE(flags_set
);
145 // Test the flag is stored on disk
146 ASSERT_EQ(0, ictx
->state
->refresh());
147 ASSERT_EQ(0, ictx
->test_flags(CEPH_NOSNAP
, RBD_FLAG_OBJECT_MAP_INVALID
,
149 ASSERT_TRUE(flags_set
);