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