]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librados_test_stub/TestIoCtxImpl.cc
update sources to v12.2.3
[ceph.git] / ceph / src / test / librados_test_stub / TestIoCtxImpl.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "test/librados_test_stub/TestIoCtxImpl.h"
5#include "test/librados_test_stub/TestClassHandler.h"
6#include "test/librados_test_stub/TestRadosClient.h"
7#include "test/librados_test_stub/TestWatchNotify.h"
8#include "librados/AioCompletionImpl.h"
9#include "include/assert.h"
10#include "common/Finisher.h"
11#include "common/valgrind.h"
12#include "objclass/objclass.h"
13#include <boost/bind.hpp>
14#include <errno.h>
15
16namespace librados {
17
18TestIoCtxImpl::TestIoCtxImpl() : m_client(NULL) {
19 get();
20}
21
22TestIoCtxImpl::TestIoCtxImpl(TestRadosClient *client, int64_t pool_id,
23 const std::string& pool_name)
24 : m_client(client), m_pool_id(pool_id), m_pool_name(pool_name),
25 m_snap_seq(CEPH_NOSNAP)
26{
27 m_client->get();
28 get();
29}
30
31TestIoCtxImpl::TestIoCtxImpl(const TestIoCtxImpl& rhs)
32 : m_client(rhs.m_client),
33 m_pool_id(rhs.m_pool_id),
34 m_pool_name(rhs.m_pool_name),
35 m_snap_seq(rhs.m_snap_seq)
36{
37 m_client->get();
38 get();
39}
40
41TestIoCtxImpl::~TestIoCtxImpl() {
31f18b77 42 assert(m_pending_ops == 0);
7c673cae
FG
43}
44
45void TestObjectOperationImpl::get() {
31f18b77 46 m_refcount++;
7c673cae
FG
47}
48
49void TestObjectOperationImpl::put() {
31f18b77 50 if (--m_refcount == 0) {
7c673cae
FG
51 ANNOTATE_HAPPENS_AFTER(&m_refcount);
52 ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&m_refcount);
53 delete this;
54 } else {
55 ANNOTATE_HAPPENS_BEFORE(&m_refcount);
56 }
57}
58
59void TestIoCtxImpl::get() {
31f18b77 60 m_refcount++;
7c673cae
FG
61}
62
63void TestIoCtxImpl::put() {
31f18b77 64 if (--m_refcount == 0) {
7c673cae
FG
65 m_client->put();
66 delete this;
67 }
68}
69
70uint64_t TestIoCtxImpl::get_instance_id() const {
71 return m_client->get_instance_id();
72}
73
74int64_t TestIoCtxImpl::get_id() {
75 return m_pool_id;
76}
77
78uint64_t TestIoCtxImpl::get_last_version() {
79 return 0;
80}
81
82std::string TestIoCtxImpl::get_pool_name() {
83 return m_pool_name;
84}
85
86int TestIoCtxImpl::aio_flush() {
87 m_client->flush_aio_operations();
88 return 0;
89}
90
91void TestIoCtxImpl::aio_flush_async(AioCompletionImpl *c) {
92 m_client->flush_aio_operations(c);
93}
94
95void TestIoCtxImpl::aio_notify(const std::string& oid, AioCompletionImpl *c,
96 bufferlist& bl, uint64_t timeout_ms,
97 bufferlist *pbl) {
31f18b77 98 m_pending_ops++;
7c673cae
FG
99 c->get();
100 C_AioNotify *ctx = new C_AioNotify(this, c);
101 m_client->get_watch_notify()->aio_notify(m_client, oid, bl, timeout_ms, pbl,
102 ctx);
103}
104
105int TestIoCtxImpl::aio_operate(const std::string& oid, TestObjectOperationImpl &ops,
106 AioCompletionImpl *c, SnapContext *snap_context,
107 int flags) {
108 // TODO flags for now
109 ops.get();
31f18b77 110 m_pending_ops++;
7c673cae
FG
111 m_client->add_aio_operation(oid, true, boost::bind(
112 &TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
113 reinterpret_cast<bufferlist*>(0),
114 snap_context != NULL ? *snap_context : m_snapc), c);
115 return 0;
116}
117
118int TestIoCtxImpl::aio_operate_read(const std::string& oid,
119 TestObjectOperationImpl &ops,
120 AioCompletionImpl *c, int flags,
121 bufferlist *pbl) {
122 // TODO ignoring flags for now
123 ops.get();
31f18b77 124 m_pending_ops++;
7c673cae
FG
125 m_client->add_aio_operation(oid, true, boost::bind(
126 &TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl, m_snapc), c);
127 return 0;
128}
129
130int TestIoCtxImpl::aio_watch(const std::string& o, AioCompletionImpl *c,
131 uint64_t *handle, librados::WatchCtx2 *watch_ctx) {
31f18b77 132 m_pending_ops++;
7c673cae
FG
133 c->get();
134 C_AioNotify *ctx = new C_AioNotify(this, c);
135 if (m_client->is_blacklisted()) {
136 m_client->get_aio_finisher()->queue(ctx, -EBLACKLISTED);
137 } else {
138 m_client->get_watch_notify()->aio_watch(m_client, o, get_instance_id(),
139 handle, watch_ctx, ctx);
140 }
141 return 0;
142}
143
144int TestIoCtxImpl::aio_unwatch(uint64_t handle, AioCompletionImpl *c) {
31f18b77 145 m_pending_ops++;
7c673cae
FG
146 c->get();
147 C_AioNotify *ctx = new C_AioNotify(this, c);
148 if (m_client->is_blacklisted()) {
149 m_client->get_aio_finisher()->queue(ctx, -EBLACKLISTED);
150 } else {
151 m_client->get_watch_notify()->aio_unwatch(m_client, handle, ctx);
152 }
153 return 0;
154}
155
156int TestIoCtxImpl::exec(const std::string& oid, TestClassHandler *handler,
157 const char *cls, const char *method,
158 bufferlist& inbl, bufferlist* outbl,
159 const SnapContext &snapc) {
160 if (m_client->is_blacklisted()) {
161 return -EBLACKLISTED;
162 }
163
164 cls_method_cxx_call_t call = handler->get_method(cls, method);
165 if (call == NULL) {
166 return -ENOSYS;
167 }
168
169 return (*call)(reinterpret_cast<cls_method_context_t>(
170 handler->get_method_context(this, oid, snapc).get()), &inbl, outbl);
171}
172
173int TestIoCtxImpl::list_watchers(const std::string& o,
174 std::list<obj_watch_t> *out_watchers) {
175 if (m_client->is_blacklisted()) {
176 return -EBLACKLISTED;
177 }
178
179 return m_client->get_watch_notify()->list_watchers(o, out_watchers);
180}
181
182int TestIoCtxImpl::notify(const std::string& o, bufferlist& bl,
183 uint64_t timeout_ms, bufferlist *pbl) {
184 if (m_client->is_blacklisted()) {
185 return -EBLACKLISTED;
186 }
187
188 return m_client->get_watch_notify()->notify(m_client, o, bl, timeout_ms, pbl);
189}
190
191void TestIoCtxImpl::notify_ack(const std::string& o, uint64_t notify_id,
192 uint64_t handle, bufferlist& bl) {
193 m_client->get_watch_notify()->notify_ack(m_client, o, notify_id, handle,
194 m_client->get_instance_id(), bl);
195}
196
197int TestIoCtxImpl::operate(const std::string& oid, TestObjectOperationImpl &ops) {
198 AioCompletionImpl *comp = new AioCompletionImpl();
199
200 ops.get();
31f18b77 201 m_pending_ops++;
7c673cae
FG
202 m_client->add_aio_operation(oid, false, boost::bind(
203 &TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
204 reinterpret_cast<bufferlist*>(0), m_snapc), comp);
205
206 comp->wait_for_safe();
207 int ret = comp->get_return_value();
208 comp->put();
209 return ret;
210}
211
212int TestIoCtxImpl::operate_read(const std::string& oid, TestObjectOperationImpl &ops,
213 bufferlist *pbl) {
214 AioCompletionImpl *comp = new AioCompletionImpl();
215
216 ops.get();
31f18b77 217 m_pending_ops++;
7c673cae
FG
218 m_client->add_aio_operation(oid, false, boost::bind(
219 &TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl,
220 m_snapc), comp);
221
222 comp->wait_for_complete();
223 int ret = comp->get_return_value();
224 comp->put();
225 return ret;
226}
227
228void TestIoCtxImpl::aio_selfmanaged_snap_create(uint64_t *snapid,
229 AioCompletionImpl *c) {
230 m_client->add_aio_operation(
231 "", true,
232 boost::bind(&TestIoCtxImpl::selfmanaged_snap_create, this, snapid), c);
233}
234
235void TestIoCtxImpl::aio_selfmanaged_snap_remove(uint64_t snapid,
236 AioCompletionImpl *c) {
237 m_client->add_aio_operation(
238 "", true,
239 boost::bind(&TestIoCtxImpl::selfmanaged_snap_remove, this, snapid), c);
240}
241
242int TestIoCtxImpl::selfmanaged_snap_set_write_ctx(snap_t seq,
243 std::vector<snap_t>& snaps) {
244 std::vector<snapid_t> snap_ids(snaps.begin(), snaps.end());
245 m_snapc = SnapContext(seq, snap_ids);
246 return 0;
247}
248
249int TestIoCtxImpl::set_alloc_hint(const std::string& oid,
250 uint64_t expected_object_size,
b32b8144
FG
251 uint64_t expected_write_size,
252 const SnapContext &snapc) {
7c673cae
FG
253 return 0;
254}
255
256void TestIoCtxImpl::set_snap_read(snap_t seq) {
257 if (seq == 0) {
258 seq = CEPH_NOSNAP;
259 }
260 m_snap_seq = seq;
261}
262
263int TestIoCtxImpl::tmap_update(const std::string& oid, bufferlist& cmdbl) {
264 if (m_client->is_blacklisted()) {
265 return -EBLACKLISTED;
266 }
267
268 // TODO: protect against concurrent tmap updates
269 bufferlist tmap_header;
270 std::map<string,bufferlist> tmap;
271 uint64_t size = 0;
272 int r = stat(oid, &size, NULL);
273 if (r == -ENOENT) {
274 r = create(oid, false);
275 }
276 if (r < 0) {
277 return r;
278 }
279
280 if (size > 0) {
281 bufferlist inbl;
282 r = read(oid, size, 0, &inbl);
283 if (r < 0) {
284 return r;
285 }
286 bufferlist::iterator iter = inbl.begin();
287 ::decode(tmap_header, iter);
288 ::decode(tmap, iter);
289 }
290
291 __u8 c;
292 std::string key;
293 bufferlist value;
294 bufferlist::iterator iter = cmdbl.begin();
295 ::decode(c, iter);
296 ::decode(key, iter);
297
298 switch (c) {
299 case CEPH_OSD_TMAP_SET:
300 ::decode(value, iter);
301 tmap[key] = value;
302 break;
303 case CEPH_OSD_TMAP_RM:
304 r = tmap.erase(key);
305 if (r == 0) {
306 return -ENOENT;
307 }
308 break;
309 default:
310 return -EINVAL;
311 }
312
313 bufferlist out;
314 ::encode(tmap_header, out);
315 ::encode(tmap, out);
316 r = write_full(oid, out, m_snapc);
317 return r;
318}
319
320int TestIoCtxImpl::unwatch(uint64_t handle) {
321 if (m_client->is_blacklisted()) {
322 return -EBLACKLISTED;
323 }
324
325 return m_client->get_watch_notify()->unwatch(m_client, handle);
326}
327
328int TestIoCtxImpl::watch(const std::string& o, uint64_t *handle,
329 librados::WatchCtx *ctx, librados::WatchCtx2 *ctx2) {
330 if (m_client->is_blacklisted()) {
331 return -EBLACKLISTED;
332 }
333
334 return m_client->get_watch_notify()->watch(m_client, o, get_instance_id(),
335 handle, ctx, ctx2);
336}
337
338int TestIoCtxImpl::execute_operation(const std::string& oid,
339 const Operation &operation) {
340 if (m_client->is_blacklisted()) {
341 return -EBLACKLISTED;
342 }
343
344 TestRadosClient::Transaction transaction(m_client, oid);
345 return operation(this, oid);
346}
347
348int TestIoCtxImpl::execute_aio_operations(const std::string& oid,
349 TestObjectOperationImpl *ops,
350 bufferlist *pbl,
351 const SnapContext &snapc) {
352 int ret = 0;
353 if (m_client->is_blacklisted()) {
354 ret = -EBLACKLISTED;
355 } else {
356 TestRadosClient::Transaction transaction(m_client, oid);
357 for (ObjectOperations::iterator it = ops->ops.begin();
358 it != ops->ops.end(); ++it) {
359 ret = (*it)(this, oid, pbl, snapc);
360 if (ret < 0) {
361 break;
362 }
363 }
364 }
31f18b77 365 m_pending_ops--;
7c673cae
FG
366 ops->put();
367 return ret;
368}
369
370void TestIoCtxImpl::handle_aio_notify_complete(AioCompletionImpl *c, int r) {
31f18b77 371 m_pending_ops--;
7c673cae
FG
372
373 m_client->finish_aio_completion(c, r);
374}
375
376} // namespace librados