]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/test_ObjectMap.cc
update sources to 12.2.8
[ceph.git] / ceph / src / test / librbd / test_ObjectMap.cc
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"
12 #include <list>
13
14 void register_test_object_map() {
15 }
16
17 class TestObjectMap : public TestFixture {
18 public:
19
20 int when_open_object_map(librbd::ImageCtx *ictx) {
21 C_SaferCond ctx;
22 librbd::ObjectMap<> object_map(*ictx, ictx->snap_id);
23 object_map.open(&ctx);
24 return ctx.wait();
25 }
26 };
27
28 TEST_F(TestObjectMap, RefreshInvalidatesWhenCorrupt) {
29 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
30
31 librbd::ImageCtx *ictx;
32 ASSERT_EQ(0, open_image(m_image_name, &ictx));
33 bool flags_set;
34 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
35 ASSERT_FALSE(flags_set);
36
37 C_SaferCond lock_ctx;
38 {
39 RWLock::WLocker owner_locker(ictx->owner_lock);
40 ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
41 }
42 ASSERT_EQ(0, lock_ctx.wait());
43
44 std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
45 bufferlist bl;
46 bl.append("corrupt");
47 ASSERT_EQ(0, ictx->md_ctx.write_full(oid, bl));
48
49 ASSERT_EQ(0, when_open_object_map(ictx));
50 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
51 ASSERT_TRUE(flags_set);
52 }
53
54 TEST_F(TestObjectMap, RefreshInvalidatesWhenTooSmall) {
55 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
56
57 librbd::ImageCtx *ictx;
58 ASSERT_EQ(0, open_image(m_image_name, &ictx));
59 bool flags_set;
60 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
61 ASSERT_FALSE(flags_set);
62
63 C_SaferCond lock_ctx;
64 {
65 RWLock::WLocker owner_locker(ictx->owner_lock);
66 ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
67 }
68 ASSERT_EQ(0, lock_ctx.wait());
69
70 librados::ObjectWriteOperation op;
71 librbd::cls_client::object_map_resize(&op, 0, OBJECT_NONEXISTENT);
72
73 std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
74 ASSERT_EQ(0, ictx->md_ctx.operate(oid, &op));
75
76 ASSERT_EQ(0, when_open_object_map(ictx));
77 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
78 ASSERT_TRUE(flags_set);
79 }
80
81 TEST_F(TestObjectMap, InvalidateFlagOnDisk) {
82 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
83
84 librbd::ImageCtx *ictx;
85 ASSERT_EQ(0, open_image(m_image_name, &ictx));
86 bool flags_set;
87 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
88 ASSERT_FALSE(flags_set);
89
90 C_SaferCond lock_ctx;
91 {
92 RWLock::WLocker owner_locker(ictx->owner_lock);
93 ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
94 }
95 ASSERT_EQ(0, lock_ctx.wait());
96
97 std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
98 bufferlist bl;
99 bl.append("corrupt");
100 ASSERT_EQ(0, ictx->md_ctx.write_full(oid, bl));
101
102 ASSERT_EQ(0, when_open_object_map(ictx));
103 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
104 ASSERT_TRUE(flags_set);
105
106 ASSERT_EQ(0, open_image(m_image_name, &ictx));
107 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
108 ASSERT_TRUE(flags_set);
109 }
110
111 TEST_F(TestObjectMap, AcquireLockInvalidatesWhenTooSmall) {
112 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
113
114 librbd::ImageCtx *ictx;
115 ASSERT_EQ(0, open_image(m_image_name, &ictx));
116 bool flags_set;
117 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
118 ASSERT_FALSE(flags_set);
119
120 librados::ObjectWriteOperation op;
121 librbd::cls_client::object_map_resize(&op, 0, OBJECT_NONEXISTENT);
122
123 std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
124 ASSERT_EQ(0, ictx->md_ctx.operate(oid, &op));
125
126 C_SaferCond lock_ctx;
127 {
128 RWLock::WLocker owner_locker(ictx->owner_lock);
129 ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
130 }
131 ASSERT_EQ(0, lock_ctx.wait());
132
133 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
134 ASSERT_TRUE(flags_set);
135
136 // Test the flag is stored on disk
137 ASSERT_EQ(0, ictx->state->refresh());
138 ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID,
139 &flags_set));
140 ASSERT_TRUE(flags_set);
141 }