]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librados_test_stub/LibradosTestStub.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / test / librados_test_stub / LibradosTestStub.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/LibradosTestStub.h"
5#include "include/rados/librados.hpp"
6#include "include/stringify.h"
7#include "common/ceph_argparse.h"
11fdf7f2 8#include "common/ceph_context.h"
7c673cae
FG
9#include "common/common_init.h"
10#include "common/config.h"
11#include "common/debug.h"
12#include "common/snap_types.h"
13#include "librados/AioCompletionImpl.h"
11fdf7f2 14#include "log/Log.h"
7c673cae
FG
15#include "test/librados_test_stub/TestClassHandler.h"
16#include "test/librados_test_stub/TestIoCtxImpl.h"
17#include "test/librados_test_stub/TestRadosClient.h"
18#include "test/librados_test_stub/TestMemCluster.h"
19#include "test/librados_test_stub/TestMemRadosClient.h"
20#include "objclass/objclass.h"
21#include "osd/osd_types.h"
22#include <arpa/inet.h>
7c673cae
FG
23#include <boost/shared_ptr.hpp>
24#include <deque>
f67539c2 25#include <functional>
7c673cae
FG
26#include <list>
27#include <vector>
11fdf7f2 28#include "include/ceph_assert.h"
7c673cae
FG
29#include "include/compat.h"
30
31#define dout_context g_ceph_context
32#define dout_subsys ceph_subsys_rados
33
20effc67
TL
34using namespace std;
35
7c673cae
FG
36namespace librados {
37
38MockTestMemIoCtxImpl &get_mock_io_ctx(IoCtx &ioctx) {
39 MockTestMemIoCtxImpl **mock =
40 reinterpret_cast<MockTestMemIoCtxImpl **>(&ioctx);
41 return **mock;
42}
43
44} // namespace librados
45
46namespace librados_test_stub {
47
48TestClusterRef &cluster() {
49 static TestClusterRef s_cluster;
50 return s_cluster;
51}
52
53void set_cluster(TestClusterRef cluster_ref) {
54 cluster() = cluster_ref;
55}
56
57TestClusterRef get_cluster() {
58 auto &cluster_ref = cluster();
59 if (cluster_ref.get() == nullptr) {
60 cluster_ref.reset(new librados::TestMemCluster());
61 }
62 return cluster_ref;
63}
64
7c673cae
FG
65librados::TestClassHandler *get_class_handler() {
66 static boost::shared_ptr<librados::TestClassHandler> s_class_handler;
67 if (!s_class_handler) {
68 s_class_handler.reset(new librados::TestClassHandler());
69 s_class_handler->open_all_classes();
70 }
71 return s_class_handler.get();
72}
73
f67539c2
TL
74} // namespace librados_test_stub
75
76namespace {
77
7c673cae
FG
78void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen) {
79 if (outbuf) {
80 if (outbl.length() > 0) {
81 *outbuf = (char *)malloc(outbl.length());
82 memcpy(*outbuf, outbl.c_str(), outbl.length());
83 } else {
84 *outbuf = NULL;
85 }
86 }
87 if (outbuflen) {
88 *outbuflen = outbl.length();
89 }
90}
91
92void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen) {
93 if (outbuf) {
94 if (outbl.length() > 0) {
95 *outbuf = (char *)malloc(outbl.length());
96 memcpy(*outbuf, outbl.c_str(), outbl.length());
97 } else {
98 *outbuf = NULL;
99 }
100 }
101 if (outbuflen) {
102 *outbuflen = outbl.length();
103 }
104}
105
106librados::TestRadosClient *create_rados_client() {
107 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
108 CephContext *cct = common_preinit(iparams, CODE_ENVIRONMENT_LIBRARY, 0);
11fdf7f2
TL
109 cct->_conf.parse_env(cct->get_module_type());
110 cct->_conf.apply_changes(nullptr);
111 cct->_log->start();
7c673cae
FG
112
113 auto rados_client =
114 librados_test_stub::get_cluster()->create_rados_client(cct);
115 cct->put();
116 return rados_client;
117}
118
119} // anonymous namespace
120
9f95a23c
TL
121extern "C" int rados_aio_create_completion2(void *cb_arg,
122 rados_callback_t cb_complete,
123 rados_completion_t *pc)
7c673cae
FG
124{
125 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
126 if (cb_complete) {
127 c->set_complete_callback(cb_arg, cb_complete);
128 }
7c673cae
FG
129 *pc = c;
130 return 0;
131}
132
133extern "C" int rados_aio_get_return_value(rados_completion_t c) {
134 return reinterpret_cast<librados::AioCompletionImpl*>(c)->get_return_value();
135}
136
137extern "C" rados_config_t rados_cct(rados_t cluster)
138{
139 librados::TestRadosClient *client =
140 reinterpret_cast<librados::TestRadosClient*>(cluster);
141 return reinterpret_cast<rados_config_t>(client->cct());
142}
143
144extern "C" int rados_conf_set(rados_t cluster, const char *option,
145 const char *value) {
146 librados::TestRadosClient *impl =
147 reinterpret_cast<librados::TestRadosClient*>(cluster);
148 CephContext *cct = impl->cct();
11fdf7f2 149 return cct->_conf.set_val(option, value);
7c673cae
FG
150}
151
152extern "C" int rados_conf_parse_env(rados_t cluster, const char *var) {
153 librados::TestRadosClient *client =
154 reinterpret_cast<librados::TestRadosClient*>(cluster);
11fdf7f2
TL
155 auto& conf = client->cct()->_conf;
156 conf.parse_env(client->cct()->get_module_type(), var);
157 conf.apply_changes(NULL);
158 return 0;
7c673cae
FG
159}
160
161extern "C" int rados_conf_read_file(rados_t cluster, const char *path) {
162 librados::TestRadosClient *client =
163 reinterpret_cast<librados::TestRadosClient*>(cluster);
11fdf7f2
TL
164 auto& conf = client->cct()->_conf;
165 int ret = conf.parse_config_files(path, NULL, 0);
7c673cae 166 if (ret == 0) {
11fdf7f2
TL
167 conf.parse_env(client->cct()->get_module_type());
168 conf.apply_changes(NULL);
9f95a23c 169 conf.complain_about_parse_error(client->cct());
7c673cae
FG
170 } else if (ret == -ENOENT) {
171 // ignore missing client config
172 return 0;
173 }
174 return ret;
175}
176
177extern "C" int rados_connect(rados_t cluster) {
178 librados::TestRadosClient *client =
179 reinterpret_cast<librados::TestRadosClient*>(cluster);
180 return client->connect();
181}
182
183extern "C" int rados_create(rados_t *cluster, const char * const id) {
184 *cluster = create_rados_client();
185 return 0;
186}
187
11fdf7f2
TL
188extern "C" int rados_create_with_context(rados_t *cluster,
189 rados_config_t cct_) {
190 auto cct = reinterpret_cast<CephContext*>(cct_);
191 *cluster = librados_test_stub::get_cluster()->create_rados_client(cct);
192 return 0;
193}
194
7c673cae
FG
195extern "C" rados_config_t rados_ioctx_cct(rados_ioctx_t ioctx)
196{
197 librados::TestIoCtxImpl *ctx =
198 reinterpret_cast<librados::TestIoCtxImpl*>(ioctx);
199 return reinterpret_cast<rados_config_t>(ctx->get_rados_client()->cct());
200}
201
202extern "C" int rados_ioctx_create(rados_t cluster, const char *pool_name,
203 rados_ioctx_t *ioctx) {
204 librados::TestRadosClient *client =
205 reinterpret_cast<librados::TestRadosClient*>(cluster);
206
207 int64_t pool_id = client->pool_lookup(pool_name);
208 if (pool_id < 0) {
209 return static_cast<int>(pool_id);
210 }
211
212 *ioctx = reinterpret_cast<rados_ioctx_t>(
213 client->create_ioctx(pool_id, pool_name));
214 return 0;
215}
216
217extern "C" int rados_ioctx_create2(rados_t cluster, int64_t pool_id,
218 rados_ioctx_t *ioctx)
219{
220 librados::TestRadosClient *client =
221 reinterpret_cast<librados::TestRadosClient*>(cluster);
222
223 std::list<std::pair<int64_t, std::string> > pools;
224 int r = client->pool_list(pools);
225 if (r < 0) {
226 return r;
227 }
228
229 for (std::list<std::pair<int64_t, std::string> >::iterator it =
230 pools.begin(); it != pools.end(); ++it) {
231 if (it->first == pool_id) {
232 *ioctx = reinterpret_cast<rados_ioctx_t>(
233 client->create_ioctx(pool_id, it->second));
234 return 0;
235 }
236 }
237 return -ENOENT;
238}
239
240extern "C" void rados_ioctx_destroy(rados_ioctx_t io) {
241 librados::TestIoCtxImpl *ctx =
242 reinterpret_cast<librados::TestIoCtxImpl*>(io);
243 ctx->put();
244}
245
246extern "C" rados_t rados_ioctx_get_cluster(rados_ioctx_t io) {
247 librados::TestIoCtxImpl *ctx =
248 reinterpret_cast<librados::TestIoCtxImpl*>(io);
249 return reinterpret_cast<rados_t>(ctx->get_rados_client());
250}
251
252extern "C" int rados_mon_command(rados_t cluster, const char **cmd,
253 size_t cmdlen, const char *inbuf,
254 size_t inbuflen, char **outbuf,
255 size_t *outbuflen, char **outs,
256 size_t *outslen) {
257 librados::TestRadosClient *client =
258 reinterpret_cast<librados::TestRadosClient*>(cluster);
259
260 vector<string> cmdvec;
261 for (size_t i = 0; i < cmdlen; i++) {
262 cmdvec.push_back(cmd[i]);
263 }
264
265 bufferlist inbl;
266 inbl.append(inbuf, inbuflen);
267
268 bufferlist outbl;
269 string outstring;
270 int ret = client->mon_command(cmdvec, inbl, &outbl, &outstring);
271
272 do_out_buffer(outbl, outbuf, outbuflen);
273 do_out_buffer(outstring, outs, outslen);
274 return ret;
275}
276
277extern "C" int rados_nobjects_list_open(rados_ioctx_t io,
278 rados_list_ctx_t *ctx) {
279 librados::TestIoCtxImpl *io_ctx =
280 reinterpret_cast<librados::TestIoCtxImpl*>(io);
281 librados::TestRadosClient *client = io_ctx->get_rados_client();
282
283 std::list<librados::TestRadosClient::Object> *list =
284 new std::list<librados::TestRadosClient::Object>();
285
286 client->object_list(io_ctx->get_id(), list);
287 list->push_front(librados::TestRadosClient::Object());
288 *ctx = reinterpret_cast<rados_list_ctx_t>(list);
289 return 0;
290}
291
292extern "C" int rados_nobjects_list_next(rados_list_ctx_t ctx,
293 const char **entry,
294 const char **key,
295 const char **nspace) {
296 std::list<librados::TestRadosClient::Object> *list =
297 reinterpret_cast<std::list<librados::TestRadosClient::Object> *>(ctx);
298 if (!list->empty()) {
299 list->pop_front();
300 }
301 if (list->empty()) {
302 return -ENOENT;
303 }
304
305 librados::TestRadosClient::Object &obj = list->front();
306 if (entry != NULL) {
307 *entry = obj.oid.c_str();
308 }
309 if (key != NULL) {
310 *key = obj.locator.c_str();
311 }
312 if (nspace != NULL) {
313 *nspace = obj.nspace.c_str();
314 }
315 return 0;
316}
317
318extern "C" void rados_nobjects_list_close(rados_list_ctx_t ctx) {
319 std::list<librados::TestRadosClient::Object> *list =
320 reinterpret_cast<std::list<librados::TestRadosClient::Object> *>(ctx);
321 delete list;
322}
323
324extern "C" int rados_pool_create(rados_t cluster, const char *pool_name) {
325 librados::TestRadosClient *client =
326 reinterpret_cast<librados::TestRadosClient*>(cluster);
327 return client->pool_create(pool_name);
328}
329
330extern "C" int rados_pool_delete(rados_t cluster, const char *pool_name) {
331 librados::TestRadosClient *client =
332 reinterpret_cast<librados::TestRadosClient*>(cluster);
333 return client->pool_delete(pool_name);
334}
335
336extern "C" void rados_shutdown(rados_t cluster) {
337 librados::TestRadosClient *client =
338 reinterpret_cast<librados::TestRadosClient*>(cluster);
339 client->put();
340}
341
342extern "C" int rados_wait_for_latest_osdmap(rados_t cluster) {
343 librados::TestRadosClient *client =
344 reinterpret_cast<librados::TestRadosClient*>(cluster);
345 return client->wait_for_latest_osdmap();
346}
347
f67539c2
TL
348using namespace std::placeholders;
349
7c673cae
FG
350namespace librados {
351
9f95a23c
TL
352AioCompletion::~AioCompletion()
353{
354 auto c = reinterpret_cast<AioCompletionImpl *>(pc);
7c673cae 355 c->release();
9f95a23c
TL
356}
357
358void AioCompletion::release() {
7c673cae
FG
359 delete this;
360}
361
362IoCtx::IoCtx() : io_ctx_impl(NULL) {
363}
364
365IoCtx::~IoCtx() {
366 close();
367}
368
369IoCtx::IoCtx(const IoCtx& rhs) {
370 io_ctx_impl = rhs.io_ctx_impl;
371 if (io_ctx_impl) {
372 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
373 ctx->get();
374 }
375}
376
11fdf7f2
TL
377IoCtx::IoCtx(IoCtx&& rhs) noexcept : io_ctx_impl(std::exchange(rhs.io_ctx_impl, nullptr))
378{
379}
380
7c673cae
FG
381IoCtx& IoCtx::operator=(const IoCtx& rhs) {
382 if (io_ctx_impl) {
383 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
384 ctx->put();
385 }
386
387 io_ctx_impl = rhs.io_ctx_impl;
388 if (io_ctx_impl) {
389 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
390 ctx->get();
391 }
392 return *this;
393}
394
11fdf7f2
TL
395librados::IoCtx& librados::IoCtx::operator=(IoCtx&& rhs) noexcept
396{
397 if (io_ctx_impl) {
398 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
399 ctx->put();
400 }
401
402 io_ctx_impl = std::exchange(rhs.io_ctx_impl, nullptr);
403 return *this;
404}
405
7c673cae
FG
406int IoCtx::aio_flush() {
407 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
408 ctx->aio_flush();
409 return 0;
410}
411
412int IoCtx::aio_flush_async(AioCompletion *c) {
413 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
414 ctx->aio_flush_async(c->pc);
415 return 0;
416}
417
418int IoCtx::aio_notify(const std::string& oid, AioCompletion *c, bufferlist& bl,
419 uint64_t timeout_ms, bufferlist *pbl) {
420 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
421 ctx->aio_notify(oid, c->pc, bl, timeout_ms, pbl);
422 return 0;
423}
424
425int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
426 ObjectReadOperation *op, bufferlist *pbl) {
427 return aio_operate(oid, c, op, 0, pbl);
428}
429
430int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
431 ObjectReadOperation *op, int flags,
432 bufferlist *pbl) {
433 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
434 TestObjectOperationImpl *ops = reinterpret_cast<TestObjectOperationImpl*>(op->impl);
f67539c2
TL
435 return ctx->aio_operate_read(oid, *ops, c->pc, flags, pbl,
436 ctx->get_snap_read(), nullptr);
7c673cae
FG
437}
438
31f18b77
FG
439int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
440 ObjectReadOperation *op, int flags,
441 bufferlist *pbl, const blkin_trace_info *trace_info) {
442 return aio_operate(oid, c, op, flags, pbl);
443}
444
7c673cae
FG
445int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
446 ObjectWriteOperation *op) {
447 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
448 TestObjectOperationImpl *ops = reinterpret_cast<TestObjectOperationImpl*>(op->impl);
1e59de90 449 return ctx->aio_operate(oid, *ops, c->pc, nullptr, nullptr, 0);
7c673cae
FG
450}
451
452int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
453 ObjectWriteOperation *op, snap_t seq,
11fdf7f2
TL
454 std::vector<snap_t>& snaps, int flags,
455 const blkin_trace_info *trace_info) {
7c673cae
FG
456 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
457 TestObjectOperationImpl *ops = reinterpret_cast<TestObjectOperationImpl*>(op->impl);
458
459 std::vector<snapid_t> snv;
460 snv.resize(snaps.size());
461 for (size_t i = 0; i < snaps.size(); ++i)
462 snv[i] = snaps[i];
463 SnapContext snapc(seq, snv);
464
1e59de90 465 return ctx->aio_operate(oid, *ops, c->pc, &snapc, nullptr, flags);
11fdf7f2
TL
466}
467
468int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
469 ObjectWriteOperation *op, snap_t seq,
470 std::vector<snap_t>& snaps) {
471 return aio_operate(oid, c, op, seq, snaps, 0, nullptr);
7c673cae
FG
472}
473
31f18b77
FG
474int IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
475 ObjectWriteOperation *op, snap_t seq,
476 std::vector<snap_t>& snaps,
477 const blkin_trace_info *trace_info) {
11fdf7f2 478 return aio_operate(oid, c, op, seq, snaps, 0, trace_info);
31f18b77
FG
479}
480
7c673cae
FG
481int IoCtx::aio_remove(const std::string& oid, AioCompletion *c) {
482 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
483 return ctx->aio_remove(oid, c->pc);
484}
485
11fdf7f2
TL
486int IoCtx::aio_remove(const std::string& oid, AioCompletion *c, int flags) {
487 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
488 return ctx->aio_remove(oid, c->pc, flags);
489}
490
7c673cae
FG
491int IoCtx::aio_watch(const std::string& o, AioCompletion *c, uint64_t *handle,
492 librados::WatchCtx2 *watch_ctx) {
493 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
494 return ctx->aio_watch(o, c->pc, handle, watch_ctx);
495}
496
497int IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c) {
498 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
499 return ctx->aio_unwatch(handle, c->pc);
500}
501
502config_t IoCtx::cct() {
503 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
504 return reinterpret_cast<config_t>(ctx->get_rados_client()->cct());
505}
506
507void IoCtx::close() {
508 if (io_ctx_impl) {
509 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
510 ctx->put();
511 }
512 io_ctx_impl = NULL;
513}
514
515int IoCtx::create(const std::string& oid, bool exclusive) {
516 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
517 return ctx->execute_operation(
f67539c2 518 oid, std::bind(&TestIoCtxImpl::create, _1, _2, exclusive,
9f95a23c 519 ctx->get_snap_context()));
7c673cae
FG
520}
521
522void IoCtx::dup(const IoCtx& rhs) {
523 close();
524 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(rhs.io_ctx_impl);
525 io_ctx_impl = reinterpret_cast<IoCtxImpl*>(ctx->clone());
526}
527
528int IoCtx::exec(const std::string& oid, const char *cls, const char *method,
529 bufferlist& inbl, bufferlist& outbl) {
530 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
531 return ctx->execute_operation(
f67539c2
TL
532 oid, std::bind(&TestIoCtxImpl::exec, _1, _2,
533 librados_test_stub::get_class_handler(), cls,
534 method, inbl, &outbl, ctx->get_snap_read(),
535 ctx->get_snap_context()));
7c673cae
FG
536}
537
538void IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io) {
539 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(p);
540 ctx->get();
541
542 io.close();
543 io.io_ctx_impl = reinterpret_cast<IoCtxImpl*>(ctx);
544}
545
546uint64_t IoCtx::get_instance_id() const {
547 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
548 return ctx->get_instance_id();
549}
550
551int64_t IoCtx::get_id() {
552 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
553 return ctx->get_id();
554}
555
556uint64_t IoCtx::get_last_version() {
557 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
558 return ctx->get_last_version();
559}
560
561std::string IoCtx::get_pool_name() {
562 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
563 return ctx->get_pool_name();
564}
565
566int IoCtx::list_snaps(const std::string& o, snap_set_t *out_snaps) {
567 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
568 return ctx->execute_operation(
f67539c2 569 o, std::bind(&TestIoCtxImpl::list_snaps, _1, _2, out_snaps));
7c673cae
FG
570}
571
572int IoCtx::list_watchers(const std::string& o,
573 std::list<obj_watch_t> *out_watchers) {
574 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
575 return ctx->execute_operation(
f67539c2 576 o, std::bind(&TestIoCtxImpl::list_watchers, _1, _2, out_watchers));
7c673cae
FG
577}
578
579int IoCtx::notify(const std::string& o, uint64_t ver, bufferlist& bl) {
580 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
581 return ctx->notify(o, bl, 0, NULL);
582}
583
584int IoCtx::notify2(const std::string& o, bufferlist& bl,
585 uint64_t timeout_ms, bufferlist *pbl) {
586 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
587 return ctx->notify(o, bl, timeout_ms, pbl);
588}
589
590void IoCtx::notify_ack(const std::string& o, uint64_t notify_id,
591 uint64_t handle, bufferlist& bl) {
592 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
593 ctx->notify_ack(o, notify_id, handle, bl);
594}
595
596int IoCtx::omap_get_vals(const std::string& oid,
597 const std::string& start_after,
598 uint64_t max_return,
599 std::map<std::string, bufferlist> *out_vals) {
600 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
601 return ctx->execute_operation(
f67539c2 602 oid, std::bind(&TestIoCtxImpl::omap_get_vals, _1, _2, start_after, "",
7c673cae
FG
603 max_return, out_vals));
604}
605
606int IoCtx::operate(const std::string& oid, ObjectWriteOperation *op) {
607 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
608 TestObjectOperationImpl *ops = reinterpret_cast<TestObjectOperationImpl*>(op->impl);
609 return ctx->operate(oid, *ops);
610}
611
612int IoCtx::operate(const std::string& oid, ObjectReadOperation *op,
613 bufferlist *pbl) {
614 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
615 TestObjectOperationImpl *ops = reinterpret_cast<TestObjectOperationImpl*>(op->impl);
616 return ctx->operate_read(oid, *ops, pbl);
617}
618
619int IoCtx::read(const std::string& oid, bufferlist& bl, size_t len,
620 uint64_t off) {
621 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
622 return ctx->execute_operation(
f67539c2
TL
623 oid, std::bind(&TestIoCtxImpl::read, _1, _2, len, off, &bl,
624 ctx->get_snap_read(), nullptr));
7c673cae
FG
625}
626
627int IoCtx::remove(const std::string& oid) {
628 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
629 return ctx->execute_operation(
f67539c2 630 oid, std::bind(&TestIoCtxImpl::remove, _1, _2, ctx->get_snap_context()));
7c673cae
FG
631}
632
633int IoCtx::selfmanaged_snap_create(uint64_t *snapid) {
634 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
635 return ctx->selfmanaged_snap_create(snapid);
636}
637
638void IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid, AioCompletion* c) {
639 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
640 return ctx->aio_selfmanaged_snap_create(snapid, c->pc);
641}
642
643int IoCtx::selfmanaged_snap_remove(uint64_t snapid) {
644 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
645 return ctx->selfmanaged_snap_remove(snapid);
646}
647
648void IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid, AioCompletion* c) {
649 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
650 ctx->aio_selfmanaged_snap_remove(snapid, c->pc);
651}
652
653int IoCtx::selfmanaged_snap_rollback(const std::string& oid,
654 uint64_t snapid) {
655 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
656 return ctx->selfmanaged_snap_rollback(oid, snapid);
657}
658
659int IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq,
660 std::vector<snap_t>& snaps) {
661 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
662 return ctx->selfmanaged_snap_set_write_ctx(seq, snaps);
663}
664
665void IoCtx::snap_set_read(snap_t seq) {
666 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
667 ctx->set_snap_read(seq);
668}
669
11fdf7f2
TL
670int IoCtx::sparse_read(const std::string& oid, std::map<uint64_t,uint64_t>& m,
671 bufferlist& bl, size_t len, uint64_t off) {
672 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
673 return ctx->execute_operation(
f67539c2
TL
674 oid, std::bind(&TestIoCtxImpl::sparse_read, _1, _2, off, len, &m, &bl,
675 ctx->get_snap_read()));
11fdf7f2
TL
676}
677
7c673cae
FG
678int IoCtx::stat(const std::string& oid, uint64_t *psize, time_t *pmtime) {
679 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
680 return ctx->execute_operation(
f67539c2 681 oid, std::bind(&TestIoCtxImpl::stat, _1, _2, psize, pmtime));
7c673cae
FG
682}
683
684int IoCtx::tmap_update(const std::string& oid, bufferlist& cmdbl) {
685 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
686 return ctx->execute_operation(
f67539c2 687 oid, std::bind(&TestIoCtxImpl::tmap_update, _1, _2, cmdbl));
7c673cae
FG
688}
689
690int IoCtx::trunc(const std::string& oid, uint64_t off) {
691 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
692 return ctx->execute_operation(
f67539c2 693 oid, std::bind(&TestIoCtxImpl::truncate, _1, _2, off,
7c673cae
FG
694 ctx->get_snap_context()));
695}
696
697int IoCtx::unwatch2(uint64_t handle) {
698 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
699 return ctx->unwatch(handle);
700}
701
702int IoCtx::unwatch(const std::string& o, uint64_t handle) {
703 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
704 return ctx->unwatch(handle);
705}
706
707int IoCtx::watch(const std::string& o, uint64_t ver, uint64_t *handle,
708 librados::WatchCtx *wctx) {
709 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
710 return ctx->watch(o, handle, wctx, NULL);
711}
712
713int IoCtx::watch2(const std::string& o, uint64_t *handle,
714 librados::WatchCtx2 *wctx) {
715 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
716 return ctx->watch(o, handle, NULL, wctx);
717}
718
719int IoCtx::write(const std::string& oid, bufferlist& bl, size_t len,
720 uint64_t off) {
721 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
722 return ctx->execute_operation(
f67539c2 723 oid, std::bind(&TestIoCtxImpl::write, _1, _2, bl, len, off,
7c673cae
FG
724 ctx->get_snap_context()));
725}
726
727int IoCtx::write_full(const std::string& oid, bufferlist& bl) {
728 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
729 return ctx->execute_operation(
f67539c2 730 oid, std::bind(&TestIoCtxImpl::write_full, _1, _2, bl,
7c673cae
FG
731 ctx->get_snap_context()));
732}
733
734int IoCtx::writesame(const std::string& oid, bufferlist& bl, size_t len,
735 uint64_t off) {
736 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
737 return ctx->execute_operation(
f67539c2 738 oid, std::bind(&TestIoCtxImpl::writesame, _1, _2, bl, len, off,
7c673cae
FG
739 ctx->get_snap_context()));
740}
741
c07f9fc5
FG
742int IoCtx::cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl) {
743 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
744 return ctx->execute_operation(
f67539c2
TL
745 oid, std::bind(&TestIoCtxImpl::cmpext, _1, _2, off, cmp_bl,
746 ctx->get_snap_read()));
c07f9fc5
FG
747}
748
749int IoCtx::application_enable(const std::string& app_name, bool force) {
750 return 0;
751}
752
753int IoCtx::application_enable_async(const std::string& app_name,
754 bool force, PoolAsyncCompletion *c) {
755 return -EOPNOTSUPP;
756}
757
758int IoCtx::application_list(std::set<std::string> *app_names) {
759 return -EOPNOTSUPP;
760}
761
762int IoCtx::application_metadata_get(const std::string& app_name,
763 const std::string &key,
764 std::string *value) {
765 return -EOPNOTSUPP;
766}
767
768int IoCtx::application_metadata_set(const std::string& app_name,
769 const std::string &key,
770 const std::string& value) {
771 return -EOPNOTSUPP;
772}
773
774int IoCtx::application_metadata_remove(const std::string& app_name,
775 const std::string &key) {
776 return -EOPNOTSUPP;
777}
778
779int IoCtx::application_metadata_list(const std::string& app_name,
780 std::map<std::string, std::string> *values) {
781 return -EOPNOTSUPP;
782}
783
11fdf7f2
TL
784void IoCtx::set_namespace(const std::string& nspace) {
785 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
786 ctx->set_namespace(nspace);
787}
788
789std::string IoCtx::get_namespace() const {
790 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
791 return ctx->get_namespace();
792}
793
20effc67
TL
794void IoCtx::set_pool_full_try() {
795}
796
797bool IoCtx::get_pool_full_try() {
798 return false;
799}
800
7c673cae
FG
801static int save_operation_result(int result, int *pval) {
802 if (pval != NULL) {
803 *pval = result;
804 }
805 return result;
806}
807
808ObjectOperation::ObjectOperation() {
809 TestObjectOperationImpl *o = new TestObjectOperationImpl();
810 o->get();
811 impl = reinterpret_cast<ObjectOperationImpl*>(o);
812}
813
814ObjectOperation::~ObjectOperation() {
815 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
816 if (o) {
817 o->put();
818 o = NULL;
819 }
820}
821
822void ObjectOperation::assert_exists() {
823 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2
TL
824 o->ops.push_back(std::bind(&TestIoCtxImpl::assert_exists, _1, _2, _4));
825}
826
827void ObjectOperation::assert_version(uint64_t ver) {
828 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
829 o->ops.push_back(std::bind(&TestIoCtxImpl::assert_version, _1, _2, ver));
7c673cae
FG
830}
831
832void ObjectOperation::exec(const char *cls, const char *method,
833 bufferlist& inbl) {
834 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2
TL
835 o->ops.push_back(std::bind(&TestIoCtxImpl::exec, _1, _2,
836 librados_test_stub::get_class_handler(), cls,
837 method, inbl, _3, _4, _5));
7c673cae
FG
838}
839
840void ObjectOperation::set_op_flags2(int flags) {
841}
842
843size_t ObjectOperation::size() {
844 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
845 return o->ops.size();
846}
847
11fdf7f2
TL
848void ObjectOperation::cmpext(uint64_t off, const bufferlist& cmp_bl,
849 int *prval) {
c07f9fc5 850 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2
TL
851 ObjectOperationTestImpl op = std::bind(&TestIoCtxImpl::cmpext, _1, _2, off,
852 cmp_bl, _4);
c07f9fc5 853 if (prval != NULL) {
f67539c2
TL
854 op = std::bind(save_operation_result,
855 std::bind(op, _1, _2, _3, _4, _5, _6), prval);
c07f9fc5
FG
856 }
857 o->ops.push_back(op);
858}
859
7c673cae
FG
860void ObjectReadOperation::list_snaps(snap_set_t *out_snaps, int *prval) {
861 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
862
f67539c2 863 ObjectOperationTestImpl op = std::bind(&TestIoCtxImpl::list_snaps, _1, _2,
7c673cae
FG
864 out_snaps);
865 if (prval != NULL) {
f67539c2
TL
866 op = std::bind(save_operation_result,
867 std::bind(op, _1, _2, _3, _4, _5, _6), prval);
7c673cae
FG
868 }
869 o->ops.push_back(op);
870}
871
872void ObjectReadOperation::list_watchers(std::list<obj_watch_t> *out_watchers,
873 int *prval) {
874 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
875
f67539c2 876 ObjectOperationTestImpl op = std::bind(&TestIoCtxImpl::list_watchers, _1,
7c673cae
FG
877 _2, out_watchers);
878 if (prval != NULL) {
f67539c2
TL
879 op = std::bind(save_operation_result,
880 std::bind(op, _1, _2, _3, _4, _5, _6), prval);
7c673cae
FG
881 }
882 o->ops.push_back(op);
883}
884
885void ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl,
886 int *prval) {
887 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
888
889 ObjectOperationTestImpl op;
890 if (pbl != NULL) {
f67539c2 891 op = std::bind(&TestIoCtxImpl::read, _1, _2, len, off, pbl, _4, nullptr);
7c673cae 892 } else {
f67539c2 893 op = std::bind(&TestIoCtxImpl::read, _1, _2, len, off, _3, _4, nullptr);
7c673cae
FG
894 }
895
896 if (prval != NULL) {
f67539c2
TL
897 op = std::bind(save_operation_result,
898 std::bind(op, _1, _2, _3, _4, _5, _6), prval);
7c673cae
FG
899 }
900 o->ops.push_back(op);
901}
902
903void ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
904 std::map<uint64_t,uint64_t> *m,
1d09f67e
TL
905 bufferlist *pbl, int *prval,
906 uint64_t truncate_size,
907 uint32_t truncate_seq) {
7c673cae
FG
908 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
909
910 ObjectOperationTestImpl op;
911 if (pbl != NULL) {
f67539c2 912 op = std::bind(&TestIoCtxImpl::sparse_read, _1, _2, off, len, m, pbl, _4);
7c673cae 913 } else {
f67539c2 914 op = std::bind(&TestIoCtxImpl::sparse_read, _1, _2, off, len, m, _3, _4);
7c673cae
FG
915 }
916
917 if (prval != NULL) {
f67539c2
TL
918 op = std::bind(save_operation_result,
919 std::bind(op, _1, _2, _3, _4, _5, _6), prval);
7c673cae
FG
920 }
921 o->ops.push_back(op);
922}
923
924void ObjectReadOperation::stat(uint64_t *psize, time_t *pmtime, int *prval) {
925 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
926
f67539c2 927 ObjectOperationTestImpl op = std::bind(&TestIoCtxImpl::stat, _1, _2,
7c673cae
FG
928 psize, pmtime);
929
930 if (prval != NULL) {
f67539c2
TL
931 op = std::bind(save_operation_result,
932 std::bind(op, _1, _2, _3, _4, _5, _6), prval);
7c673cae
FG
933 }
934 o->ops.push_back(op);
935}
936
937void ObjectWriteOperation::append(const bufferlist &bl) {
938 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 939 o->ops.push_back(std::bind(&TestIoCtxImpl::append, _1, _2, bl, _5));
7c673cae
FG
940}
941
942void ObjectWriteOperation::create(bool exclusive) {
943 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 944 o->ops.push_back(std::bind(&TestIoCtxImpl::create, _1, _2, exclusive, _5));
7c673cae
FG
945}
946
947void ObjectWriteOperation::omap_set(const std::map<std::string, bufferlist> &map) {
948 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 949 o->ops.push_back(std::bind(&TestIoCtxImpl::omap_set, _1, _2, boost::ref(map)));
7c673cae
FG
950}
951
952void ObjectWriteOperation::remove() {
953 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 954 o->ops.push_back(std::bind(&TestIoCtxImpl::remove, _1, _2, _5));
7c673cae
FG
955}
956
957void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid) {
958 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 959 o->ops.push_back(std::bind(&TestIoCtxImpl::selfmanaged_snap_rollback,
7c673cae
FG
960 _1, _2, snapid));
961}
962
963void ObjectWriteOperation::set_alloc_hint(uint64_t expected_object_size,
964 uint64_t expected_write_size) {
965 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 966 o->ops.push_back(std::bind(&TestIoCtxImpl::set_alloc_hint, _1, _2,
92f5a8d4 967 expected_object_size, expected_write_size, 0,
f67539c2 968 _5));
7c673cae
FG
969}
970
92f5a8d4
TL
971void ObjectWriteOperation::set_alloc_hint2(uint64_t expected_object_size,
972 uint64_t expected_write_size,
973 uint32_t flags) {
974 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 975 o->ops.push_back(std::bind(&TestIoCtxImpl::set_alloc_hint, _1, _2,
92f5a8d4 976 expected_object_size, expected_write_size, flags,
f67539c2 977 _5));
92f5a8d4 978}
7c673cae
FG
979
980void ObjectWriteOperation::tmap_update(const bufferlist& cmdbl) {
981 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 982 o->ops.push_back(std::bind(&TestIoCtxImpl::tmap_update, _1, _2,
7c673cae
FG
983 cmdbl));
984}
985
986void ObjectWriteOperation::truncate(uint64_t off) {
987 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 988 o->ops.push_back(std::bind(&TestIoCtxImpl::truncate, _1, _2, off, _5));
7c673cae
FG
989}
990
991void ObjectWriteOperation::write(uint64_t off, const bufferlist& bl) {
992 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2
TL
993 o->ops.push_back(std::bind(&TestIoCtxImpl::write, _1, _2, bl, bl.length(),
994 off, _5));
7c673cae
FG
995}
996
997void ObjectWriteOperation::write_full(const bufferlist& bl) {
998 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 999 o->ops.push_back(std::bind(&TestIoCtxImpl::write_full, _1, _2, bl, _5));
7c673cae
FG
1000}
1001
f67539c2
TL
1002void ObjectWriteOperation::writesame(uint64_t off, uint64_t len,
1003 const bufferlist& bl) {
7c673cae 1004 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2
TL
1005 o->ops.push_back(std::bind(&TestIoCtxImpl::writesame, _1, _2, bl, len,
1006 off, _5));
7c673cae
FG
1007}
1008
1009void ObjectWriteOperation::zero(uint64_t off, uint64_t len) {
1010 TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
f67539c2 1011 o->ops.push_back(std::bind(&TestIoCtxImpl::zero, _1, _2, off, len, _5));
7c673cae
FG
1012}
1013
1014Rados::Rados() : client(NULL) {
1015}
1016
1017Rados::Rados(IoCtx& ioctx) {
1018 TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(ioctx.io_ctx_impl);
1019 TestRadosClient *impl = ctx->get_rados_client();
1020 impl->get();
1021
1022 client = reinterpret_cast<RadosClient*>(impl);
11fdf7f2 1023 ceph_assert(client != NULL);
7c673cae
FG
1024}
1025
1026Rados::~Rados() {
1027 shutdown();
1028}
1029
eafe8130
TL
1030void Rados::from_rados_t(rados_t p, Rados &rados) {
1031 if (rados.client != nullptr) {
1032 reinterpret_cast<TestRadosClient*>(rados.client)->put();
1033 rados.client = nullptr;
1034 }
1035
1036 auto impl = reinterpret_cast<TestRadosClient*>(p);
1037 if (impl) {
1038 impl->get();
1039 rados.client = reinterpret_cast<RadosClient*>(impl);
1040 }
1041}
1042
7c673cae 1043AioCompletion *Rados::aio_create_completion(void *cb_arg,
9f95a23c 1044 callback_t cb_complete) {
7c673cae 1045 AioCompletionImpl *c;
9f95a23c 1046 int r = rados_aio_create_completion2(cb_arg, cb_complete,
7c673cae 1047 reinterpret_cast<void**>(&c));
11fdf7f2 1048 ceph_assert(r == 0);
7c673cae
FG
1049 return new AioCompletion(c);
1050}
1051
1052int Rados::aio_watch_flush(AioCompletion* c) {
1053 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1054 return impl->aio_watch_flush(c->pc);
1055}
1056
f67539c2 1057int Rados::blocklist_add(const std::string& client_address,
7c673cae
FG
1058 uint32_t expire_seconds) {
1059 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
f67539c2 1060 return impl->blocklist_add(client_address, expire_seconds);
7c673cae
FG
1061}
1062
1063config_t Rados::cct() {
1064 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1065 return reinterpret_cast<config_t>(impl->cct());
1066}
1067
1068int Rados::cluster_fsid(std::string* fsid) {
1069 *fsid = "00000000-1111-2222-3333-444444444444";
1070 return 0;
1071}
1072
1073int Rados::conf_set(const char *option, const char *value) {
1074 return rados_conf_set(reinterpret_cast<rados_t>(client), option, value);
1075}
1076
1077int Rados::conf_get(const char *option, std::string &val) {
1078 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1079 CephContext *cct = impl->cct();
1080
1081 char *str = NULL;
11fdf7f2 1082 int ret = cct->_conf.get_val(option, &str, -1);
7c673cae
FG
1083 if (ret != 0) {
1084 free(str);
1085 return ret;
1086 }
1087
1088 val = str;
1089 free(str);
1090 return 0;
1091}
1092
1093int Rados::conf_parse_env(const char *env) const {
1094 return rados_conf_parse_env(reinterpret_cast<rados_t>(client), env);
1095}
1096
1097int Rados::conf_read_file(const char * const path) const {
1098 return rados_conf_read_file(reinterpret_cast<rados_t>(client), path);
1099}
1100
1101int Rados::connect() {
1102 return rados_connect(reinterpret_cast<rados_t>(client));
1103}
1104
1105uint64_t Rados::get_instance_id() {
1106 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1107 return impl->get_instance_id();
1108}
1109
11fdf7f2
TL
1110int Rados::get_min_compatible_osd(int8_t* require_osd_release) {
1111 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1112 return impl->get_min_compatible_osd(require_osd_release);
1113}
1114
1115int Rados::get_min_compatible_client(int8_t* min_compat_client,
1116 int8_t* require_min_compat_client) {
1117 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1118 return impl->get_min_compatible_client(min_compat_client,
1119 require_min_compat_client);
1120}
1121
7c673cae
FG
1122int Rados::init(const char * const id) {
1123 return rados_create(reinterpret_cast<rados_t *>(&client), id);
1124}
1125
11fdf7f2
TL
1126int Rados::init_with_context(config_t cct_) {
1127 return rados_create_with_context(reinterpret_cast<rados_t *>(&client), cct_);
1128}
1129
7c673cae
FG
1130int Rados::ioctx_create(const char *name, IoCtx &io) {
1131 rados_ioctx_t p;
1132 int ret = rados_ioctx_create(reinterpret_cast<rados_t>(client), name, &p);
1133 if (ret) {
1134 return ret;
1135 }
1136
1137 io.close();
1138 io.io_ctx_impl = reinterpret_cast<IoCtxImpl*>(p);
1139 return 0;
1140}
1141
1142int Rados::ioctx_create2(int64_t pool_id, IoCtx &io)
1143{
1144 rados_ioctx_t p;
1145 int ret = rados_ioctx_create2(reinterpret_cast<rados_t>(client), pool_id, &p);
1146 if (ret) {
1147 return ret;
1148 }
1149
1150 io.close();
1151 io.io_ctx_impl = reinterpret_cast<IoCtxImpl*>(p);
1152 return 0;
1153}
1154
1155int Rados::mon_command(std::string cmd, const bufferlist& inbl,
1156 bufferlist *outbl, std::string *outs) {
1157 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1158
1159 std::vector<std::string> cmds;
1160 cmds.push_back(cmd);
1161 return impl->mon_command(cmds, inbl, outbl, outs);
1162}
1163
c07f9fc5
FG
1164int Rados::service_daemon_register(const std::string& service,
1165 const std::string& name,
1166 const std::map<std::string,std::string>& metadata) {
1167 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1168 return impl->service_daemon_register(service, name, metadata);
1169}
1170
11fdf7f2 1171int Rados::service_daemon_update_status(std::map<std::string,std::string>&& status) {
c07f9fc5 1172 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
11fdf7f2 1173 return impl->service_daemon_update_status(std::move(status));
c07f9fc5
FG
1174}
1175
7c673cae
FG
1176int Rados::pool_create(const char *name) {
1177 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1178 return impl->pool_create(name);
1179}
1180
1181int Rados::pool_delete(const char *name) {
1182 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1183 return impl->pool_delete(name);
1184}
1185
1186int Rados::pool_get_base_tier(int64_t pool, int64_t* base_tier) {
1187 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1188 return impl->pool_get_base_tier(pool, base_tier);
1189}
1190
1191int Rados::pool_list(std::list<std::string>& v) {
1192 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1193 std::list<std::pair<int64_t, std::string> > pools;
1194 int r = impl->pool_list(pools);
1195 if (r < 0) {
1196 return r;
1197 }
1198
1199 v.clear();
1200 for (std::list<std::pair<int64_t, std::string> >::iterator it = pools.begin();
1201 it != pools.end(); ++it) {
1202 v.push_back(it->second);
1203 }
1204 return 0;
1205}
1206
1207int Rados::pool_list2(std::list<std::pair<int64_t, std::string> >& v)
1208{
1209 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1210 return impl->pool_list(v);
1211}
1212
1213int64_t Rados::pool_lookup(const char *name) {
1214 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1215 return impl->pool_lookup(name);
1216}
1217
1218int Rados::pool_reverse_lookup(int64_t id, std::string *name) {
1219 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1220 return impl->pool_reverse_lookup(id, name);
1221}
1222
1223void Rados::shutdown() {
1224 if (client == NULL) {
1225 return;
1226 }
1227 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1228 impl->put();
1229 client = NULL;
1230}
1231
f67539c2 1232void Rados::test_blocklist_self(bool set) {
7c673cae
FG
1233}
1234
1235int Rados::wait_for_latest_osdmap() {
1236 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1237 return impl->wait_for_latest_osdmap();
1238}
1239
1240int Rados::watch_flush() {
1241 TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
1242 return impl->watch_flush();
1243}
1244
1245WatchCtx::~WatchCtx() {
1246}
1247
1248WatchCtx2::~WatchCtx2() {
1249}
1250
1251} // namespace librados
1252
1253int cls_cxx_create(cls_method_context_t hctx, bool exclusive) {
1254 librados::TestClassHandler::MethodContext *ctx =
1255 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
9f95a23c 1256 return ctx->io_ctx_impl->create(ctx->oid, exclusive, ctx->snapc);
7c673cae
FG
1257}
1258
f64942e4
AA
1259int cls_cxx_remove(cls_method_context_t hctx) {
1260 librados::TestClassHandler::MethodContext *ctx =
1261 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1262 return ctx->io_ctx_impl->remove(ctx->oid, ctx->io_ctx_impl->get_snap_context());
1263}
1264
7c673cae
FG
1265int cls_get_request_origin(cls_method_context_t hctx, entity_inst_t *origin) {
1266 librados::TestClassHandler::MethodContext *ctx =
1267 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1268
1269 librados::TestRadosClient *rados_client =
1270 ctx->io_ctx_impl->get_rados_client();
1271
1272 struct sockaddr_in sin;
11fdf7f2 1273 memset(&sin, 0, sizeof(sin));
7c673cae
FG
1274 sin.sin_family = AF_INET;
1275 sin.sin_port = 0;
1276 inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
1277
1278 entity_addr_t entity_addr(entity_addr_t::TYPE_DEFAULT,
1279 rados_client->get_nonce());
1280 entity_addr.in4_addr() = sin;
1281
1282 *origin = entity_inst_t(
1283 entity_name_t::CLIENT(rados_client->get_instance_id()),
1284 entity_addr);
1285 return 0;
1286}
1287
1288int cls_cxx_getxattr(cls_method_context_t hctx, const char *name,
1289 bufferlist *outbl) {
1290 std::map<string, bufferlist> attrs;
1291 int r = cls_cxx_getxattrs(hctx, &attrs);
1292 if (r < 0) {
1293 return r;
1294 }
1295
1296 std::map<string, bufferlist>::iterator it = attrs.find(name);
1297 if (it == attrs.end()) {
1298 return -ENODATA;
1299 }
1300 *outbl = it->second;
1301 return 0;
1302}
1303
1304int cls_cxx_getxattrs(cls_method_context_t hctx, std::map<string, bufferlist> *attrset) {
1305 librados::TestClassHandler::MethodContext *ctx =
1306 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1307 return ctx->io_ctx_impl->xattr_get(ctx->oid, attrset);
1308}
1309
1310int cls_cxx_map_get_keys(cls_method_context_t hctx, const string &start_obj,
c07f9fc5 1311 uint64_t max_to_get, std::set<string> *keys, bool *more) {
7c673cae
FG
1312 librados::TestClassHandler::MethodContext *ctx =
1313 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1314
1315 keys->clear();
1316 std::map<string, bufferlist> vals;
c07f9fc5
FG
1317 int r = ctx->io_ctx_impl->omap_get_vals2(ctx->oid, start_obj, "", max_to_get,
1318 &vals, more);
1319 if (r < 0) {
1320 return r;
1321 }
7c673cae 1322
c07f9fc5
FG
1323 for (std::map<string, bufferlist>::iterator it = vals.begin();
1324 it != vals.end(); ++it) {
1325 keys->insert(it->first);
1326 }
7c673cae
FG
1327 return keys->size();
1328}
1329
1330int cls_cxx_map_get_val(cls_method_context_t hctx, const string &key,
1331 bufferlist *outbl) {
1332 librados::TestClassHandler::MethodContext *ctx =
1333 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1334
1335 std::map<string, bufferlist> vals;
1336 int r = ctx->io_ctx_impl->omap_get_vals(ctx->oid, "", key, 1024, &vals);
1337 if (r < 0) {
1338 return r;
1339 }
1340
1341 std::map<string, bufferlist>::iterator it = vals.find(key);
1342 if (it == vals.end()) {
1343 return -ENOENT;
1344 }
1345
1346 *outbl = it->second;
1347 return 0;
1348}
1349
1350int cls_cxx_map_get_vals(cls_method_context_t hctx, const string &start_obj,
1351 const string &filter_prefix, uint64_t max_to_get,
c07f9fc5 1352 std::map<string, bufferlist> *vals, bool *more) {
7c673cae
FG
1353 librados::TestClassHandler::MethodContext *ctx =
1354 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
c07f9fc5
FG
1355 int r = ctx->io_ctx_impl->omap_get_vals2(ctx->oid, start_obj, filter_prefix,
1356 max_to_get, vals, more);
7c673cae
FG
1357 if (r < 0) {
1358 return r;
1359 }
1360 return vals->size();
1361}
1362
1363int cls_cxx_map_remove_key(cls_method_context_t hctx, const string &key) {
1364 std::set<std::string> keys;
1365 keys.insert(key);
1366
1367 librados::TestClassHandler::MethodContext *ctx =
1368 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1369 return ctx->io_ctx_impl->omap_rm_keys(ctx->oid, keys);
1370}
1371
1372int cls_cxx_map_set_val(cls_method_context_t hctx, const string &key,
1373 bufferlist *inbl) {
1374 std::map<std::string, bufferlist> m;
1375 m[key] = *inbl;
1376 return cls_cxx_map_set_vals(hctx, &m);
1377}
1378
1379int cls_cxx_map_set_vals(cls_method_context_t hctx,
1380 const std::map<string, bufferlist> *map) {
1381 librados::TestClassHandler::MethodContext *ctx =
1382 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1383 return ctx->io_ctx_impl->omap_set(ctx->oid, *map);
1384}
1385
1386int cls_cxx_read(cls_method_context_t hctx, int ofs, int len,
1387 bufferlist *outbl) {
1388 return cls_cxx_read2(hctx, ofs, len, outbl, 0);
1389}
1390
1391int cls_cxx_read2(cls_method_context_t hctx, int ofs, int len,
1392 bufferlist *outbl, uint32_t op_flags) {
1393 librados::TestClassHandler::MethodContext *ctx =
1394 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
f67539c2
TL
1395 return ctx->io_ctx_impl->read(
1396 ctx->oid, len, ofs, outbl, ctx->snap_id, nullptr);
7c673cae
FG
1397}
1398
1399int cls_cxx_setxattr(cls_method_context_t hctx, const char *name,
1400 bufferlist *inbl) {
1401 librados::TestClassHandler::MethodContext *ctx =
1402 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1403 return ctx->io_ctx_impl->xattr_set(ctx->oid, name, *inbl);
1404}
1405
1406int cls_cxx_stat(cls_method_context_t hctx, uint64_t *size, time_t *mtime) {
1407 librados::TestClassHandler::MethodContext *ctx =
1408 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1409 return ctx->io_ctx_impl->stat(ctx->oid, size, mtime);
1410}
1411
1412int cls_cxx_write(cls_method_context_t hctx, int ofs, int len,
1413 bufferlist *inbl) {
1414 return cls_cxx_write2(hctx, ofs, len, inbl, 0);
1415}
1416
1417int cls_cxx_write2(cls_method_context_t hctx, int ofs, int len,
1418 bufferlist *inbl, uint32_t op_flags) {
1419 librados::TestClassHandler::MethodContext *ctx =
1420 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1421 return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs, ctx->snapc);
1422}
1423
1424int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *inbl) {
1425 librados::TestClassHandler::MethodContext *ctx =
1426 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1427 return ctx->io_ctx_impl->write_full(ctx->oid, *inbl, ctx->snapc);
1428}
1429
11fdf7f2
TL
1430int cls_cxx_replace(cls_method_context_t hctx, int ofs, int len,
1431 bufferlist *inbl) {
1432 librados::TestClassHandler::MethodContext *ctx =
1433 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1434 int r = ctx->io_ctx_impl->truncate(ctx->oid, 0, ctx->snapc);
1435 if (r < 0) {
1436 return r;
1437 }
1438 return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs, ctx->snapc);
1439}
1440
9f95a23c
TL
1441int cls_cxx_truncate(cls_method_context_t hctx, int ofs) {
1442 librados::TestClassHandler::MethodContext *ctx =
1443 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1444 return ctx->io_ctx_impl->truncate(ctx->oid, ofs, ctx->snapc);
1445}
1446
1447int cls_cxx_write_zero(cls_method_context_t hctx, int ofs, int len) {
1448 librados::TestClassHandler::MethodContext *ctx =
1449 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1450 return ctx->io_ctx_impl->zero(ctx->oid, len, ofs, ctx->snapc);
1451}
1452
7c673cae
FG
1453int cls_cxx_list_watchers(cls_method_context_t hctx,
1454 obj_list_watch_response_t *watchers) {
1455 librados::TestClassHandler::MethodContext *ctx =
1456 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1457
1458 std::list<obj_watch_t> obj_watchers;
1459 int r = ctx->io_ctx_impl->list_watchers(ctx->oid, &obj_watchers);
1460 if (r < 0) {
1461 return r;
1462 }
1463
1464 for (auto &w : obj_watchers) {
1465 watch_item_t watcher;
1466 watcher.name = entity_name_t::CLIENT(w.watcher_id);
1467 watcher.cookie = w.cookie;
1468 watcher.timeout_seconds = w.timeout_seconds;
522d829b 1469 watcher.addr.parse(w.addr);
7c673cae
FG
1470 watchers->entries.push_back(watcher);
1471 }
1472
1473 return 0;
1474}
1475
1476uint64_t cls_get_features(cls_method_context_t hctx) {
1477 return CEPH_FEATURES_SUPPORTED_DEFAULT;
1478}
1479
1480uint64_t cls_get_client_features(cls_method_context_t hctx) {
1481 return CEPH_FEATURES_SUPPORTED_DEFAULT;
1482}
1483
11fdf7f2
TL
1484int cls_get_snapset_seq(cls_method_context_t hctx, uint64_t *snap_seq) {
1485 librados::TestClassHandler::MethodContext *ctx =
1486 reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
1487 librados::snap_set_t snapset;
1488 int r = ctx->io_ctx_impl->list_snaps(ctx->oid, &snapset);
1489 if (r < 0) {
1490 return r;
1491 }
1492
1493 *snap_seq = snapset.seq;
1494 return 0;
1495}
1496
7c673cae
FG
1497int cls_log(int level, const char *format, ...) {
1498 int size = 256;
1499 va_list ap;
1500 while (1) {
1501 char buf[size];
1502 va_start(ap, format);
1503 int n = vsnprintf(buf, size, format, ap);
1504 va_end(ap);
1505 if ((n > -1 && n < size) || size > 8196) {
11fdf7f2 1506 dout(ceph::dout::need_dynamic(level)) << buf << dendl;
7c673cae
FG
1507 return n;
1508 }
1509 size *= 2;
1510 }
1511 return 0;
1512}
1513
1514int cls_register(const char *name, cls_handle_t *handle) {
f67539c2 1515 librados::TestClassHandler *cls = librados_test_stub::get_class_handler();
7c673cae
FG
1516 return cls->create(name, handle);
1517}
1518
1519int cls_register_cxx_method(cls_handle_t hclass, const char *method,
1520 int flags,
1521 cls_method_cxx_call_t class_call,
1522 cls_method_handle_t *handle) {
f67539c2 1523 librados::TestClassHandler *cls = librados_test_stub::get_class_handler();
7c673cae
FG
1524 return cls->create_method(hclass, method, class_call, handle);
1525}
1526
1527int cls_register_cxx_filter(cls_handle_t hclass,
1528 const std::string &filter_name,
1529 cls_cxx_filter_factory_t fn,
1530 cls_filter_handle_t *)
1531{
f67539c2 1532 librados::TestClassHandler *cls = librados_test_stub::get_class_handler();
7c673cae
FG
1533 return cls->create_filter(hclass, filter_name, fn);
1534}
11fdf7f2 1535
9f95a23c
TL
1536ceph_release_t cls_get_required_osd_release(cls_handle_t hclass) {
1537 return ceph_release_t::nautilus;
1538}
1539
1540ceph_release_t cls_get_min_compatible_client(cls_handle_t hclass) {
1541 return ceph_release_t::nautilus;
1542}
1543
1544// stubs to silence TestClassHandler::open_class()
1545PGLSFilter::~PGLSFilter()
1546{}
1547
1548int cls_gen_rand_base64(char *, int) {
1549 return -ENOTSUP;
1550}
1551
1552int cls_cxx_chunk_write_and_set(cls_method_handle_t, int,
1553 int, bufferlist *,
1554 uint32_t, bufferlist *, int) {
1555 return -ENOTSUP;
1556}
1557
1558int cls_cxx_map_read_header(cls_method_handle_t, bufferlist *) {
1559 return -ENOTSUP;
1560}
1561
1562uint64_t cls_get_osd_min_alloc_size(cls_method_context_t hctx) {
1563 return 0;
11fdf7f2 1564}
f67539c2
TL
1565
1566uint64_t cls_get_pool_stripe_width(cls_method_context_t hctx) {
1567 return 0;
1568}