1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
8 #include "common/common_init.h"
9 #include "common/config.h"
10 #include "common/debug.h"
11 #include "common/snap_types.h"
12 #include "librados/AioCompletionImpl.h"
13 #include "test/librados_test_stub/TestClassHandler.h"
14 #include "test/librados_test_stub/TestIoCtxImpl.h"
15 #include "test/librados_test_stub/TestRadosClient.h"
16 #include "test/librados_test_stub/TestMemCluster.h"
17 #include "test/librados_test_stub/TestMemRadosClient.h"
18 #include "objclass/objclass.h"
19 #include "osd/osd_types.h"
20 #include <arpa/inet.h>
21 #include <boost/bind.hpp>
22 #include <boost/shared_ptr.hpp>
26 #include "include/assert.h"
27 #include "include/compat.h"
29 #define dout_context g_ceph_context
30 #define dout_subsys ceph_subsys_rados
34 MockTestMemIoCtxImpl
&get_mock_io_ctx(IoCtx
&ioctx
) {
35 MockTestMemIoCtxImpl
**mock
=
36 reinterpret_cast<MockTestMemIoCtxImpl
**>(&ioctx
);
40 } // namespace librados
42 namespace librados_test_stub
{
44 TestClusterRef
&cluster() {
45 static TestClusterRef s_cluster
;
49 void set_cluster(TestClusterRef cluster_ref
) {
50 cluster() = cluster_ref
;
53 TestClusterRef
get_cluster() {
54 auto &cluster_ref
= cluster();
55 if (cluster_ref
.get() == nullptr) {
56 cluster_ref
.reset(new librados::TestMemCluster());
61 } // namespace librados_test_stub
65 librados::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();
71 return s_class_handler
.get();
74 void do_out_buffer(bufferlist
& outbl
, char **outbuf
, size_t *outbuflen
) {
76 if (outbl
.length() > 0) {
77 *outbuf
= (char *)malloc(outbl
.length());
78 memcpy(*outbuf
, outbl
.c_str(), outbl
.length());
84 *outbuflen
= outbl
.length();
88 void do_out_buffer(string
& outbl
, char **outbuf
, size_t *outbuflen
) {
90 if (outbl
.length() > 0) {
91 *outbuf
= (char *)malloc(outbl
.length());
92 memcpy(*outbuf
, outbl
.c_str(), outbl
.length());
98 *outbuflen
= outbl
.length();
102 librados::TestRadosClient
*create_rados_client() {
103 CephInitParameters
iparams(CEPH_ENTITY_TYPE_CLIENT
);
104 CephContext
*cct
= common_preinit(iparams
, CODE_ENVIRONMENT_LIBRARY
, 0);
105 cct
->_conf
->parse_env();
106 cct
->_conf
->apply_changes(nullptr);
109 librados_test_stub::get_cluster()->create_rados_client(cct
);
114 } // anonymous namespace
116 extern "C" int rados_aio_create_completion(void *cb_arg
,
117 rados_callback_t cb_complete
,
118 rados_callback_t cb_safe
,
119 rados_completion_t
*pc
)
121 librados::AioCompletionImpl
*c
= new librados::AioCompletionImpl
;
123 c
->set_complete_callback(cb_arg
, cb_complete
);
126 c
->set_safe_callback(cb_arg
, cb_safe
);
132 extern "C" int rados_aio_get_return_value(rados_completion_t c
) {
133 return reinterpret_cast<librados::AioCompletionImpl
*>(c
)->get_return_value();
136 extern "C" rados_config_t
rados_cct(rados_t cluster
)
138 librados::TestRadosClient
*client
=
139 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
140 return reinterpret_cast<rados_config_t
>(client
->cct());
143 extern "C" int rados_conf_set(rados_t cluster
, const char *option
,
145 librados::TestRadosClient
*impl
=
146 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
147 CephContext
*cct
= impl
->cct();
148 return cct
->_conf
->set_val(option
, value
);
151 extern "C" int rados_conf_parse_env(rados_t cluster
, const char *var
) {
152 librados::TestRadosClient
*client
=
153 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
154 md_config_t
*conf
= client
->cct()->_conf
;
155 std::vector
<const char*> args
;
156 env_to_vec(args
, var
);
157 int ret
= conf
->parse_argv(args
);
159 conf
->apply_changes(NULL
);
164 extern "C" int rados_conf_read_file(rados_t cluster
, const char *path
) {
165 librados::TestRadosClient
*client
=
166 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
167 md_config_t
*conf
= client
->cct()->_conf
;
168 int ret
= conf
->parse_config_files(path
, NULL
, 0);
171 conf
->apply_changes(NULL
);
172 conf
->complain_about_parse_errors(client
->cct());
173 } else if (ret
== -ENOENT
) {
174 // ignore missing client config
180 extern "C" int rados_connect(rados_t cluster
) {
181 librados::TestRadosClient
*client
=
182 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
183 return client
->connect();
186 extern "C" int rados_create(rados_t
*cluster
, const char * const id
) {
187 *cluster
= create_rados_client();
191 extern "C" rados_config_t
rados_ioctx_cct(rados_ioctx_t ioctx
)
193 librados::TestIoCtxImpl
*ctx
=
194 reinterpret_cast<librados::TestIoCtxImpl
*>(ioctx
);
195 return reinterpret_cast<rados_config_t
>(ctx
->get_rados_client()->cct());
198 extern "C" int rados_ioctx_create(rados_t cluster
, const char *pool_name
,
199 rados_ioctx_t
*ioctx
) {
200 librados::TestRadosClient
*client
=
201 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
203 int64_t pool_id
= client
->pool_lookup(pool_name
);
205 return static_cast<int>(pool_id
);
208 *ioctx
= reinterpret_cast<rados_ioctx_t
>(
209 client
->create_ioctx(pool_id
, pool_name
));
213 extern "C" int rados_ioctx_create2(rados_t cluster
, int64_t pool_id
,
214 rados_ioctx_t
*ioctx
)
216 librados::TestRadosClient
*client
=
217 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
219 std::list
<std::pair
<int64_t, std::string
> > pools
;
220 int r
= client
->pool_list(pools
);
225 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
=
226 pools
.begin(); it
!= pools
.end(); ++it
) {
227 if (it
->first
== pool_id
) {
228 *ioctx
= reinterpret_cast<rados_ioctx_t
>(
229 client
->create_ioctx(pool_id
, it
->second
));
236 extern "C" void rados_ioctx_destroy(rados_ioctx_t io
) {
237 librados::TestIoCtxImpl
*ctx
=
238 reinterpret_cast<librados::TestIoCtxImpl
*>(io
);
242 extern "C" rados_t
rados_ioctx_get_cluster(rados_ioctx_t io
) {
243 librados::TestIoCtxImpl
*ctx
=
244 reinterpret_cast<librados::TestIoCtxImpl
*>(io
);
245 return reinterpret_cast<rados_t
>(ctx
->get_rados_client());
248 extern "C" int rados_mon_command(rados_t cluster
, const char **cmd
,
249 size_t cmdlen
, const char *inbuf
,
250 size_t inbuflen
, char **outbuf
,
251 size_t *outbuflen
, char **outs
,
253 librados::TestRadosClient
*client
=
254 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
256 vector
<string
> cmdvec
;
257 for (size_t i
= 0; i
< cmdlen
; i
++) {
258 cmdvec
.push_back(cmd
[i
]);
262 inbl
.append(inbuf
, inbuflen
);
266 int ret
= client
->mon_command(cmdvec
, inbl
, &outbl
, &outstring
);
268 do_out_buffer(outbl
, outbuf
, outbuflen
);
269 do_out_buffer(outstring
, outs
, outslen
);
273 extern "C" int rados_nobjects_list_open(rados_ioctx_t io
,
274 rados_list_ctx_t
*ctx
) {
275 librados::TestIoCtxImpl
*io_ctx
=
276 reinterpret_cast<librados::TestIoCtxImpl
*>(io
);
277 librados::TestRadosClient
*client
= io_ctx
->get_rados_client();
279 std::list
<librados::TestRadosClient::Object
> *list
=
280 new std::list
<librados::TestRadosClient::Object
>();
282 client
->object_list(io_ctx
->get_id(), list
);
283 list
->push_front(librados::TestRadosClient::Object());
284 *ctx
= reinterpret_cast<rados_list_ctx_t
>(list
);
288 extern "C" int rados_nobjects_list_next(rados_list_ctx_t ctx
,
291 const char **nspace
) {
292 std::list
<librados::TestRadosClient::Object
> *list
=
293 reinterpret_cast<std::list
<librados::TestRadosClient::Object
> *>(ctx
);
294 if (!list
->empty()) {
301 librados::TestRadosClient::Object
&obj
= list
->front();
303 *entry
= obj
.oid
.c_str();
306 *key
= obj
.locator
.c_str();
308 if (nspace
!= NULL
) {
309 *nspace
= obj
.nspace
.c_str();
314 extern "C" void rados_nobjects_list_close(rados_list_ctx_t ctx
) {
315 std::list
<librados::TestRadosClient::Object
> *list
=
316 reinterpret_cast<std::list
<librados::TestRadosClient::Object
> *>(ctx
);
320 extern "C" int rados_pool_create(rados_t cluster
, const char *pool_name
) {
321 librados::TestRadosClient
*client
=
322 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
323 return client
->pool_create(pool_name
);
326 extern "C" int rados_pool_delete(rados_t cluster
, const char *pool_name
) {
327 librados::TestRadosClient
*client
=
328 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
329 return client
->pool_delete(pool_name
);
332 extern "C" void rados_shutdown(rados_t cluster
) {
333 librados::TestRadosClient
*client
=
334 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
338 extern "C" int rados_wait_for_latest_osdmap(rados_t cluster
) {
339 librados::TestRadosClient
*client
=
340 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
341 return client
->wait_for_latest_osdmap();
346 void AioCompletion::release() {
347 AioCompletionImpl
*c
= reinterpret_cast<AioCompletionImpl
*>(pc
);
352 IoCtx::IoCtx() : io_ctx_impl(NULL
) {
359 IoCtx::IoCtx(const IoCtx
& rhs
) {
360 io_ctx_impl
= rhs
.io_ctx_impl
;
362 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
367 IoCtx
& IoCtx::operator=(const IoCtx
& rhs
) {
369 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
373 io_ctx_impl
= rhs
.io_ctx_impl
;
375 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
381 int IoCtx::aio_flush() {
382 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
387 int IoCtx::aio_flush_async(AioCompletion
*c
) {
388 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
389 ctx
->aio_flush_async(c
->pc
);
393 int IoCtx::aio_notify(const std::string
& oid
, AioCompletion
*c
, bufferlist
& bl
,
394 uint64_t timeout_ms
, bufferlist
*pbl
) {
395 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
396 ctx
->aio_notify(oid
, c
->pc
, bl
, timeout_ms
, pbl
);
400 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
401 ObjectReadOperation
*op
, bufferlist
*pbl
) {
402 return aio_operate(oid
, c
, op
, 0, pbl
);
405 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
406 ObjectReadOperation
*op
, int flags
,
408 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
409 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
410 return ctx
->aio_operate_read(oid
, *ops
, c
->pc
, flags
, pbl
);
413 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
414 ObjectReadOperation
*op
, int flags
,
415 bufferlist
*pbl
, const blkin_trace_info
*trace_info
) {
416 return aio_operate(oid
, c
, op
, flags
, pbl
);
419 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
420 ObjectWriteOperation
*op
) {
421 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
422 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
423 return ctx
->aio_operate(oid
, *ops
, c
->pc
, NULL
, 0);
426 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
427 ObjectWriteOperation
*op
, snap_t seq
,
428 std::vector
<snap_t
>& snaps
) {
429 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
430 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
432 std::vector
<snapid_t
> snv
;
433 snv
.resize(snaps
.size());
434 for (size_t i
= 0; i
< snaps
.size(); ++i
)
436 SnapContext
snapc(seq
, snv
);
438 return ctx
->aio_operate(oid
, *ops
, c
->pc
, &snapc
, 0);
441 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
442 ObjectWriteOperation
*op
, snap_t seq
,
443 std::vector
<snap_t
>& snaps
,
444 const blkin_trace_info
*trace_info
) {
445 return aio_operate(oid
, c
, op
, seq
, snaps
);
448 int IoCtx::aio_remove(const std::string
& oid
, AioCompletion
*c
) {
449 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
450 return ctx
->aio_remove(oid
, c
->pc
);
453 int IoCtx::aio_watch(const std::string
& o
, AioCompletion
*c
, uint64_t *handle
,
454 librados::WatchCtx2
*watch_ctx
) {
455 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
456 return ctx
->aio_watch(o
, c
->pc
, handle
, watch_ctx
);
459 int IoCtx::aio_unwatch(uint64_t handle
, AioCompletion
*c
) {
460 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
461 return ctx
->aio_unwatch(handle
, c
->pc
);
464 config_t
IoCtx::cct() {
465 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
466 return reinterpret_cast<config_t
>(ctx
->get_rados_client()->cct());
469 void IoCtx::close() {
471 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
477 int IoCtx::create(const std::string
& oid
, bool exclusive
) {
478 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
479 return ctx
->execute_operation(
480 oid
, boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
483 void IoCtx::dup(const IoCtx
& rhs
) {
485 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(rhs
.io_ctx_impl
);
486 io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(ctx
->clone());
489 int IoCtx::exec(const std::string
& oid
, const char *cls
, const char *method
,
490 bufferlist
& inbl
, bufferlist
& outbl
) {
491 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
492 return ctx
->execute_operation(
493 oid
, boost::bind(&TestIoCtxImpl::exec
, _1
, _2
, get_class_handler(), cls
,
494 method
, inbl
, &outbl
, ctx
->get_snap_context()));
497 void IoCtx::from_rados_ioctx_t(rados_ioctx_t p
, IoCtx
&io
) {
498 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(p
);
502 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(ctx
);
505 uint64_t IoCtx::get_instance_id() const {
506 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
507 return ctx
->get_instance_id();
510 int64_t IoCtx::get_id() {
511 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
512 return ctx
->get_id();
515 uint64_t IoCtx::get_last_version() {
516 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
517 return ctx
->get_last_version();
520 std::string
IoCtx::get_pool_name() {
521 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
522 return ctx
->get_pool_name();
525 int IoCtx::list_snaps(const std::string
& o
, snap_set_t
*out_snaps
) {
526 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
527 return ctx
->execute_operation(
528 o
, boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
, out_snaps
));
531 int IoCtx::list_watchers(const std::string
& o
,
532 std::list
<obj_watch_t
> *out_watchers
) {
533 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
534 return ctx
->execute_operation(
535 o
, boost::bind(&TestIoCtxImpl::list_watchers
, _1
, _2
, out_watchers
));
538 int IoCtx::notify(const std::string
& o
, uint64_t ver
, bufferlist
& bl
) {
539 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
540 return ctx
->notify(o
, bl
, 0, NULL
);
543 int IoCtx::notify2(const std::string
& o
, bufferlist
& bl
,
544 uint64_t timeout_ms
, bufferlist
*pbl
) {
545 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
546 return ctx
->notify(o
, bl
, timeout_ms
, pbl
);
549 void IoCtx::notify_ack(const std::string
& o
, uint64_t notify_id
,
550 uint64_t handle
, bufferlist
& bl
) {
551 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
552 ctx
->notify_ack(o
, notify_id
, handle
, bl
);
555 int IoCtx::omap_get_vals(const std::string
& oid
,
556 const std::string
& start_after
,
558 std::map
<std::string
, bufferlist
> *out_vals
) {
559 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
560 return ctx
->execute_operation(
561 oid
, boost::bind(&TestIoCtxImpl::omap_get_vals
, _1
, _2
, start_after
, "",
562 max_return
, out_vals
));
565 int IoCtx::operate(const std::string
& oid
, ObjectWriteOperation
*op
) {
566 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
567 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
568 return ctx
->operate(oid
, *ops
);
571 int IoCtx::operate(const std::string
& oid
, ObjectReadOperation
*op
,
573 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
574 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
575 return ctx
->operate_read(oid
, *ops
, pbl
);
578 int IoCtx::read(const std::string
& oid
, bufferlist
& bl
, size_t len
,
580 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
581 return ctx
->execute_operation(
582 oid
, boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, &bl
));
585 int IoCtx::remove(const std::string
& oid
) {
586 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
587 return ctx
->execute_operation(
588 oid
, boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, ctx
->get_snap_context()));
591 int IoCtx::selfmanaged_snap_create(uint64_t *snapid
) {
592 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
593 return ctx
->selfmanaged_snap_create(snapid
);
596 void IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid
, AioCompletion
* c
) {
597 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
598 return ctx
->aio_selfmanaged_snap_create(snapid
, c
->pc
);
601 int IoCtx::selfmanaged_snap_remove(uint64_t snapid
) {
602 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
603 return ctx
->selfmanaged_snap_remove(snapid
);
606 void IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid
, AioCompletion
* c
) {
607 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
608 ctx
->aio_selfmanaged_snap_remove(snapid
, c
->pc
);
611 int IoCtx::selfmanaged_snap_rollback(const std::string
& oid
,
613 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
614 return ctx
->selfmanaged_snap_rollback(oid
, snapid
);
617 int IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq
,
618 std::vector
<snap_t
>& snaps
) {
619 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
620 return ctx
->selfmanaged_snap_set_write_ctx(seq
, snaps
);
623 void IoCtx::snap_set_read(snap_t seq
) {
624 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
625 ctx
->set_snap_read(seq
);
628 int IoCtx::stat(const std::string
& oid
, uint64_t *psize
, time_t *pmtime
) {
629 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
630 return ctx
->execute_operation(
631 oid
, boost::bind(&TestIoCtxImpl::stat
, _1
, _2
, psize
, pmtime
));
634 int IoCtx::tmap_update(const std::string
& oid
, bufferlist
& cmdbl
) {
635 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
636 return ctx
->execute_operation(
637 oid
, boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
, cmdbl
));
640 int IoCtx::trunc(const std::string
& oid
, uint64_t off
) {
641 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
642 return ctx
->execute_operation(
643 oid
, boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
,
644 ctx
->get_snap_context()));
647 int IoCtx::unwatch2(uint64_t handle
) {
648 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
649 return ctx
->unwatch(handle
);
652 int IoCtx::unwatch(const std::string
& o
, uint64_t handle
) {
653 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
654 return ctx
->unwatch(handle
);
657 int IoCtx::watch(const std::string
& o
, uint64_t ver
, uint64_t *handle
,
658 librados::WatchCtx
*wctx
) {
659 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
660 return ctx
->watch(o
, handle
, wctx
, NULL
);
663 int IoCtx::watch2(const std::string
& o
, uint64_t *handle
,
664 librados::WatchCtx2
*wctx
) {
665 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
666 return ctx
->watch(o
, handle
, NULL
, wctx
);
669 int IoCtx::write(const std::string
& oid
, bufferlist
& bl
, size_t len
,
671 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
672 return ctx
->execute_operation(
673 oid
, boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, len
, off
,
674 ctx
->get_snap_context()));
677 int IoCtx::write_full(const std::string
& oid
, bufferlist
& bl
) {
678 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
679 return ctx
->execute_operation(
680 oid
, boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
,
681 ctx
->get_snap_context()));
684 int IoCtx::writesame(const std::string
& oid
, bufferlist
& bl
, size_t len
,
686 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
687 return ctx
->execute_operation(
688 oid
, boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
, off
,
689 ctx
->get_snap_context()));
692 static int save_operation_result(int result
, int *pval
) {
699 ObjectOperation::ObjectOperation() {
700 TestObjectOperationImpl
*o
= new TestObjectOperationImpl();
702 impl
= reinterpret_cast<ObjectOperationImpl
*>(o
);
705 ObjectOperation::~ObjectOperation() {
706 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
713 void ObjectOperation::assert_exists() {
714 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
715 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::assert_exists
, _1
, _2
));
718 void ObjectOperation::exec(const char *cls
, const char *method
,
720 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
721 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::exec
, _1
, _2
,
722 get_class_handler(), cls
, method
, inbl
, _3
, _4
));
725 void ObjectOperation::set_op_flags2(int flags
) {
728 size_t ObjectOperation::size() {
729 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
730 return o
->ops
.size();
733 void ObjectReadOperation::list_snaps(snap_set_t
*out_snaps
, int *prval
) {
734 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
736 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
,
739 op
= boost::bind(save_operation_result
,
740 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
742 o
->ops
.push_back(op
);
745 void ObjectReadOperation::list_watchers(std::list
<obj_watch_t
> *out_watchers
,
747 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
749 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_watchers
, _1
,
752 op
= boost::bind(save_operation_result
,
753 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
755 o
->ops
.push_back(op
);
758 void ObjectReadOperation::read(size_t off
, uint64_t len
, bufferlist
*pbl
,
760 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
762 ObjectOperationTestImpl op
;
764 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, pbl
);
766 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, _3
);
770 op
= boost::bind(save_operation_result
,
771 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
773 o
->ops
.push_back(op
);
776 void ObjectReadOperation::sparse_read(uint64_t off
, uint64_t len
,
777 std::map
<uint64_t,uint64_t> *m
,
778 bufferlist
*pbl
, int *prval
) {
779 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
781 ObjectOperationTestImpl op
;
783 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, pbl
);
785 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, _3
);
789 op
= boost::bind(save_operation_result
,
790 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
792 o
->ops
.push_back(op
);
795 void ObjectReadOperation::stat(uint64_t *psize
, time_t *pmtime
, int *prval
) {
796 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
798 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::stat
, _1
, _2
,
802 op
= boost::bind(save_operation_result
,
803 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
805 o
->ops
.push_back(op
);
808 void ObjectWriteOperation::append(const bufferlist
&bl
) {
809 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
810 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::append
, _1
, _2
, bl
, _4
));
813 void ObjectWriteOperation::create(bool exclusive
) {
814 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
815 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
818 void ObjectWriteOperation::omap_set(const std::map
<std::string
, bufferlist
> &map
) {
819 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
820 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::omap_set
, _1
, _2
, boost::ref(map
)));
823 void ObjectWriteOperation::remove() {
824 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
825 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, _4
));
828 void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid
) {
829 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
830 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::selfmanaged_snap_rollback
,
834 void ObjectWriteOperation::set_alloc_hint(uint64_t expected_object_size
,
835 uint64_t expected_write_size
) {
836 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
837 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::set_alloc_hint
, _1
, _2
,
838 expected_object_size
, expected_write_size
));
842 void ObjectWriteOperation::tmap_update(const bufferlist
& cmdbl
) {
843 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
844 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
,
848 void ObjectWriteOperation::truncate(uint64_t off
) {
849 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
850 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
, _4
));
853 void ObjectWriteOperation::write(uint64_t off
, const bufferlist
& bl
) {
854 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
855 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, bl
.length(),
859 void ObjectWriteOperation::write_full(const bufferlist
& bl
) {
860 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
861 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
, _4
));
864 void ObjectWriteOperation::writesame(uint64_t off
, uint64_t len
, const bufferlist
& bl
) {
865 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
866 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
,
870 void ObjectWriteOperation::zero(uint64_t off
, uint64_t len
) {
871 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
872 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::zero
, _1
, _2
, off
, len
));
875 Rados::Rados() : client(NULL
) {
878 Rados::Rados(IoCtx
& ioctx
) {
879 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(ioctx
.io_ctx_impl
);
880 TestRadosClient
*impl
= ctx
->get_rados_client();
883 client
= reinterpret_cast<RadosClient
*>(impl
);
884 assert(client
!= NULL
);
891 AioCompletion
*Rados::aio_create_completion(void *cb_arg
,
892 callback_t cb_complete
,
893 callback_t cb_safe
) {
894 AioCompletionImpl
*c
;
895 int r
= rados_aio_create_completion(cb_arg
, cb_complete
, cb_safe
,
896 reinterpret_cast<void**>(&c
));
898 return new AioCompletion(c
);
901 int Rados::aio_watch_flush(AioCompletion
* c
) {
902 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
903 return impl
->aio_watch_flush(c
->pc
);
906 int Rados::blacklist_add(const std::string
& client_address
,
907 uint32_t expire_seconds
) {
908 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
909 return impl
->blacklist_add(client_address
, expire_seconds
);
912 config_t
Rados::cct() {
913 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
914 return reinterpret_cast<config_t
>(impl
->cct());
917 int Rados::cluster_fsid(std::string
* fsid
) {
918 *fsid
= "00000000-1111-2222-3333-444444444444";
922 int Rados::conf_set(const char *option
, const char *value
) {
923 return rados_conf_set(reinterpret_cast<rados_t
>(client
), option
, value
);
926 int Rados::conf_get(const char *option
, std::string
&val
) {
927 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
928 CephContext
*cct
= impl
->cct();
931 int ret
= cct
->_conf
->get_val(option
, &str
, -1);
942 int Rados::conf_parse_env(const char *env
) const {
943 return rados_conf_parse_env(reinterpret_cast<rados_t
>(client
), env
);
946 int Rados::conf_read_file(const char * const path
) const {
947 return rados_conf_read_file(reinterpret_cast<rados_t
>(client
), path
);
950 int Rados::connect() {
951 return rados_connect(reinterpret_cast<rados_t
>(client
));
954 uint64_t Rados::get_instance_id() {
955 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
956 return impl
->get_instance_id();
959 int Rados::init(const char * const id
) {
960 return rados_create(reinterpret_cast<rados_t
*>(&client
), id
);
963 int Rados::ioctx_create(const char *name
, IoCtx
&io
) {
965 int ret
= rados_ioctx_create(reinterpret_cast<rados_t
>(client
), name
, &p
);
971 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
975 int Rados::ioctx_create2(int64_t pool_id
, IoCtx
&io
)
978 int ret
= rados_ioctx_create2(reinterpret_cast<rados_t
>(client
), pool_id
, &p
);
984 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
988 int Rados::mon_command(std::string cmd
, const bufferlist
& inbl
,
989 bufferlist
*outbl
, std::string
*outs
) {
990 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
992 std::vector
<std::string
> cmds
;
994 return impl
->mon_command(cmds
, inbl
, outbl
, outs
);
997 int Rados::pool_create(const char *name
) {
998 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
999 return impl
->pool_create(name
);
1002 int Rados::pool_delete(const char *name
) {
1003 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1004 return impl
->pool_delete(name
);
1007 int Rados::pool_get_base_tier(int64_t pool
, int64_t* base_tier
) {
1008 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1009 return impl
->pool_get_base_tier(pool
, base_tier
);
1012 int Rados::pool_list(std::list
<std::string
>& v
) {
1013 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1014 std::list
<std::pair
<int64_t, std::string
> > pools
;
1015 int r
= impl
->pool_list(pools
);
1021 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
= pools
.begin();
1022 it
!= pools
.end(); ++it
) {
1023 v
.push_back(it
->second
);
1028 int Rados::pool_list2(std::list
<std::pair
<int64_t, std::string
> >& v
)
1030 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1031 return impl
->pool_list(v
);
1034 int64_t Rados::pool_lookup(const char *name
) {
1035 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1036 return impl
->pool_lookup(name
);
1039 int Rados::pool_reverse_lookup(int64_t id
, std::string
*name
) {
1040 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1041 return impl
->pool_reverse_lookup(id
, name
);
1044 void Rados::shutdown() {
1045 if (client
== NULL
) {
1048 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1053 void Rados::test_blacklist_self(bool set
) {
1056 int Rados::wait_for_latest_osdmap() {
1057 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1058 return impl
->wait_for_latest_osdmap();
1061 int Rados::watch_flush() {
1062 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1063 return impl
->watch_flush();
1066 WatchCtx::~WatchCtx() {
1069 WatchCtx2::~WatchCtx2() {
1072 } // namespace librados
1074 int cls_cxx_create(cls_method_context_t hctx
, bool exclusive
) {
1075 librados::TestClassHandler::MethodContext
*ctx
=
1076 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1077 return ctx
->io_ctx_impl
->create(ctx
->oid
, exclusive
);
1080 int cls_get_request_origin(cls_method_context_t hctx
, entity_inst_t
*origin
) {
1081 librados::TestClassHandler::MethodContext
*ctx
=
1082 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1084 librados::TestRadosClient
*rados_client
=
1085 ctx
->io_ctx_impl
->get_rados_client();
1087 struct sockaddr_in sin
;
1088 sin
.sin_family
= AF_INET
;
1090 inet_pton(AF_INET
, "127.0.0.1", &sin
.sin_addr
);
1092 entity_addr_t
entity_addr(entity_addr_t::TYPE_DEFAULT
,
1093 rados_client
->get_nonce());
1094 entity_addr
.in4_addr() = sin
;
1096 *origin
= entity_inst_t(
1097 entity_name_t::CLIENT(rados_client
->get_instance_id()),
1102 int cls_cxx_getxattr(cls_method_context_t hctx
, const char *name
,
1103 bufferlist
*outbl
) {
1104 std::map
<string
, bufferlist
> attrs
;
1105 int r
= cls_cxx_getxattrs(hctx
, &attrs
);
1110 std::map
<string
, bufferlist
>::iterator it
= attrs
.find(name
);
1111 if (it
== attrs
.end()) {
1114 *outbl
= it
->second
;
1118 int cls_cxx_getxattrs(cls_method_context_t hctx
, std::map
<string
, bufferlist
> *attrset
) {
1119 librados::TestClassHandler::MethodContext
*ctx
=
1120 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1121 return ctx
->io_ctx_impl
->xattr_get(ctx
->oid
, attrset
);
1124 int cls_cxx_map_get_keys(cls_method_context_t hctx
, const string
&start_obj
,
1125 uint64_t max_to_get
, std::set
<string
> *keys
) {
1126 librados::TestClassHandler::MethodContext
*ctx
=
1127 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1130 std::map
<string
, bufferlist
> vals
;
1131 std::string last_key
= start_obj
;
1134 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, last_key
, "", 1024,
1140 for (std::map
<string
, bufferlist
>::iterator it
= vals
.begin();
1141 it
!= vals
.end(); ++it
) {
1142 last_key
= it
->first
;
1143 keys
->insert(last_key
);
1145 } while (!vals
.empty());
1146 return keys
->size();
1149 int cls_cxx_map_get_val(cls_method_context_t hctx
, const string
&key
,
1150 bufferlist
*outbl
) {
1151 librados::TestClassHandler::MethodContext
*ctx
=
1152 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1154 std::map
<string
, bufferlist
> vals
;
1155 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, "", key
, 1024, &vals
);
1160 std::map
<string
, bufferlist
>::iterator it
= vals
.find(key
);
1161 if (it
== vals
.end()) {
1165 *outbl
= it
->second
;
1169 int cls_cxx_map_get_vals(cls_method_context_t hctx
, const string
&start_obj
,
1170 const string
&filter_prefix
, uint64_t max_to_get
,
1171 std::map
<string
, bufferlist
> *vals
) {
1172 librados::TestClassHandler::MethodContext
*ctx
=
1173 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1174 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, start_obj
, filter_prefix
,
1179 return vals
->size();
1182 int cls_cxx_map_remove_key(cls_method_context_t hctx
, const string
&key
) {
1183 std::set
<std::string
> keys
;
1186 librados::TestClassHandler::MethodContext
*ctx
=
1187 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1188 return ctx
->io_ctx_impl
->omap_rm_keys(ctx
->oid
, keys
);
1191 int cls_cxx_map_set_val(cls_method_context_t hctx
, const string
&key
,
1193 std::map
<std::string
, bufferlist
> m
;
1195 return cls_cxx_map_set_vals(hctx
, &m
);
1198 int cls_cxx_map_set_vals(cls_method_context_t hctx
,
1199 const std::map
<string
, bufferlist
> *map
) {
1200 librados::TestClassHandler::MethodContext
*ctx
=
1201 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1202 return ctx
->io_ctx_impl
->omap_set(ctx
->oid
, *map
);
1205 int cls_cxx_read(cls_method_context_t hctx
, int ofs
, int len
,
1206 bufferlist
*outbl
) {
1207 return cls_cxx_read2(hctx
, ofs
, len
, outbl
, 0);
1210 int cls_cxx_read2(cls_method_context_t hctx
, int ofs
, int len
,
1211 bufferlist
*outbl
, uint32_t op_flags
) {
1212 librados::TestClassHandler::MethodContext
*ctx
=
1213 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1214 return ctx
->io_ctx_impl
->read(ctx
->oid
, len
, ofs
, outbl
);
1217 int cls_cxx_setxattr(cls_method_context_t hctx
, const char *name
,
1219 librados::TestClassHandler::MethodContext
*ctx
=
1220 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1221 return ctx
->io_ctx_impl
->xattr_set(ctx
->oid
, name
, *inbl
);
1224 int cls_cxx_stat(cls_method_context_t hctx
, uint64_t *size
, time_t *mtime
) {
1225 librados::TestClassHandler::MethodContext
*ctx
=
1226 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1227 return ctx
->io_ctx_impl
->stat(ctx
->oid
, size
, mtime
);
1230 int cls_cxx_write(cls_method_context_t hctx
, int ofs
, int len
,
1232 return cls_cxx_write2(hctx
, ofs
, len
, inbl
, 0);
1235 int cls_cxx_write2(cls_method_context_t hctx
, int ofs
, int len
,
1236 bufferlist
*inbl
, uint32_t op_flags
) {
1237 librados::TestClassHandler::MethodContext
*ctx
=
1238 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1239 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1242 int cls_cxx_write_full(cls_method_context_t hctx
, bufferlist
*inbl
) {
1243 librados::TestClassHandler::MethodContext
*ctx
=
1244 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1245 return ctx
->io_ctx_impl
->write_full(ctx
->oid
, *inbl
, ctx
->snapc
);
1248 int cls_cxx_list_watchers(cls_method_context_t hctx
,
1249 obj_list_watch_response_t
*watchers
) {
1250 librados::TestClassHandler::MethodContext
*ctx
=
1251 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1253 std::list
<obj_watch_t
> obj_watchers
;
1254 int r
= ctx
->io_ctx_impl
->list_watchers(ctx
->oid
, &obj_watchers
);
1259 for (auto &w
: obj_watchers
) {
1260 watch_item_t watcher
;
1261 watcher
.name
= entity_name_t::CLIENT(w
.watcher_id
);
1262 watcher
.cookie
= w
.cookie
;
1263 watcher
.timeout_seconds
= w
.timeout_seconds
;
1264 watcher
.addr
.parse(w
.addr
, 0);
1265 watchers
->entries
.push_back(watcher
);
1271 uint64_t cls_get_features(cls_method_context_t hctx
) {
1272 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1275 uint64_t cls_get_client_features(cls_method_context_t hctx
) {
1276 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1279 int cls_log(int level
, const char *format
, ...) {
1284 va_start(ap
, format
);
1285 int n
= vsnprintf(buf
, size
, format
, ap
);
1287 if ((n
> -1 && n
< size
) || size
> 8196) {
1288 dout(level
) << buf
<< dendl
;
1296 int cls_register(const char *name
, cls_handle_t
*handle
) {
1297 librados::TestClassHandler
*cls
= get_class_handler();
1298 return cls
->create(name
, handle
);
1301 int cls_register_cxx_method(cls_handle_t hclass
, const char *method
,
1303 cls_method_cxx_call_t class_call
,
1304 cls_method_handle_t
*handle
) {
1305 librados::TestClassHandler
*cls
= get_class_handler();
1306 return cls
->create_method(hclass
, method
, class_call
, handle
);
1309 int cls_register_cxx_filter(cls_handle_t hclass
,
1310 const std::string
&filter_name
,
1311 cls_cxx_filter_factory_t fn
,
1312 cls_filter_handle_t
*)
1314 librados::TestClassHandler
*cls
= get_class_handler();
1315 return cls
->create_filter(hclass
, filter_name
, fn
);