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 ObjectWriteOperation
*op
) {
415 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
416 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
417 return ctx
->aio_operate(oid
, *ops
, c
->pc
, NULL
, 0);
420 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
421 ObjectWriteOperation
*op
, snap_t seq
,
422 std::vector
<snap_t
>& snaps
) {
423 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
424 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
426 std::vector
<snapid_t
> snv
;
427 snv
.resize(snaps
.size());
428 for (size_t i
= 0; i
< snaps
.size(); ++i
)
430 SnapContext
snapc(seq
, snv
);
432 return ctx
->aio_operate(oid
, *ops
, c
->pc
, &snapc
, 0);
435 int IoCtx::aio_remove(const std::string
& oid
, AioCompletion
*c
) {
436 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
437 return ctx
->aio_remove(oid
, c
->pc
);
440 int IoCtx::aio_watch(const std::string
& o
, AioCompletion
*c
, uint64_t *handle
,
441 librados::WatchCtx2
*watch_ctx
) {
442 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
443 return ctx
->aio_watch(o
, c
->pc
, handle
, watch_ctx
);
446 int IoCtx::aio_unwatch(uint64_t handle
, AioCompletion
*c
) {
447 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
448 return ctx
->aio_unwatch(handle
, c
->pc
);
451 config_t
IoCtx::cct() {
452 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
453 return reinterpret_cast<config_t
>(ctx
->get_rados_client()->cct());
456 void IoCtx::close() {
458 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
464 int IoCtx::create(const std::string
& oid
, bool exclusive
) {
465 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
466 return ctx
->execute_operation(
467 oid
, boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
470 void IoCtx::dup(const IoCtx
& rhs
) {
472 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(rhs
.io_ctx_impl
);
473 io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(ctx
->clone());
476 int IoCtx::exec(const std::string
& oid
, const char *cls
, const char *method
,
477 bufferlist
& inbl
, bufferlist
& outbl
) {
478 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
479 return ctx
->execute_operation(
480 oid
, boost::bind(&TestIoCtxImpl::exec
, _1
, _2
, get_class_handler(), cls
,
481 method
, inbl
, &outbl
, ctx
->get_snap_context()));
484 void IoCtx::from_rados_ioctx_t(rados_ioctx_t p
, IoCtx
&io
) {
485 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(p
);
489 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(ctx
);
492 uint64_t IoCtx::get_instance_id() const {
493 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
494 return ctx
->get_instance_id();
497 int64_t IoCtx::get_id() {
498 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
499 return ctx
->get_id();
502 uint64_t IoCtx::get_last_version() {
503 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
504 return ctx
->get_last_version();
507 std::string
IoCtx::get_pool_name() {
508 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
509 return ctx
->get_pool_name();
512 int IoCtx::list_snaps(const std::string
& o
, snap_set_t
*out_snaps
) {
513 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
514 return ctx
->execute_operation(
515 o
, boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
, out_snaps
));
518 int IoCtx::list_watchers(const std::string
& o
,
519 std::list
<obj_watch_t
> *out_watchers
) {
520 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
521 return ctx
->execute_operation(
522 o
, boost::bind(&TestIoCtxImpl::list_watchers
, _1
, _2
, out_watchers
));
525 int IoCtx::notify(const std::string
& o
, uint64_t ver
, bufferlist
& bl
) {
526 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
527 return ctx
->notify(o
, bl
, 0, NULL
);
530 int IoCtx::notify2(const std::string
& o
, bufferlist
& bl
,
531 uint64_t timeout_ms
, bufferlist
*pbl
) {
532 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
533 return ctx
->notify(o
, bl
, timeout_ms
, pbl
);
536 void IoCtx::notify_ack(const std::string
& o
, uint64_t notify_id
,
537 uint64_t handle
, bufferlist
& bl
) {
538 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
539 ctx
->notify_ack(o
, notify_id
, handle
, bl
);
542 int IoCtx::omap_get_vals(const std::string
& oid
,
543 const std::string
& start_after
,
545 std::map
<std::string
, bufferlist
> *out_vals
) {
546 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
547 return ctx
->execute_operation(
548 oid
, boost::bind(&TestIoCtxImpl::omap_get_vals
, _1
, _2
, start_after
, "",
549 max_return
, out_vals
));
552 int IoCtx::operate(const std::string
& oid
, ObjectWriteOperation
*op
) {
553 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
554 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
555 return ctx
->operate(oid
, *ops
);
558 int IoCtx::operate(const std::string
& oid
, ObjectReadOperation
*op
,
560 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
561 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
562 return ctx
->operate_read(oid
, *ops
, pbl
);
565 int IoCtx::read(const std::string
& oid
, bufferlist
& bl
, size_t len
,
567 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
568 return ctx
->execute_operation(
569 oid
, boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, &bl
));
572 int IoCtx::remove(const std::string
& oid
) {
573 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
574 return ctx
->execute_operation(
575 oid
, boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, ctx
->get_snap_context()));
578 int IoCtx::selfmanaged_snap_create(uint64_t *snapid
) {
579 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
580 return ctx
->selfmanaged_snap_create(snapid
);
583 void IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid
, AioCompletion
* c
) {
584 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
585 return ctx
->aio_selfmanaged_snap_create(snapid
, c
->pc
);
588 int IoCtx::selfmanaged_snap_remove(uint64_t snapid
) {
589 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
590 return ctx
->selfmanaged_snap_remove(snapid
);
593 void IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid
, AioCompletion
* c
) {
594 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
595 ctx
->aio_selfmanaged_snap_remove(snapid
, c
->pc
);
598 int IoCtx::selfmanaged_snap_rollback(const std::string
& oid
,
600 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
601 return ctx
->selfmanaged_snap_rollback(oid
, snapid
);
604 int IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq
,
605 std::vector
<snap_t
>& snaps
) {
606 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
607 return ctx
->selfmanaged_snap_set_write_ctx(seq
, snaps
);
610 void IoCtx::snap_set_read(snap_t seq
) {
611 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
612 ctx
->set_snap_read(seq
);
615 int IoCtx::stat(const std::string
& oid
, uint64_t *psize
, time_t *pmtime
) {
616 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
617 return ctx
->execute_operation(
618 oid
, boost::bind(&TestIoCtxImpl::stat
, _1
, _2
, psize
, pmtime
));
621 int IoCtx::tmap_update(const std::string
& oid
, bufferlist
& cmdbl
) {
622 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
623 return ctx
->execute_operation(
624 oid
, boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
, cmdbl
));
627 int IoCtx::trunc(const std::string
& oid
, uint64_t off
) {
628 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
629 return ctx
->execute_operation(
630 oid
, boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
,
631 ctx
->get_snap_context()));
634 int IoCtx::unwatch2(uint64_t handle
) {
635 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
636 return ctx
->unwatch(handle
);
639 int IoCtx::unwatch(const std::string
& o
, uint64_t handle
) {
640 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
641 return ctx
->unwatch(handle
);
644 int IoCtx::watch(const std::string
& o
, uint64_t ver
, uint64_t *handle
,
645 librados::WatchCtx
*wctx
) {
646 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
647 return ctx
->watch(o
, handle
, wctx
, NULL
);
650 int IoCtx::watch2(const std::string
& o
, uint64_t *handle
,
651 librados::WatchCtx2
*wctx
) {
652 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
653 return ctx
->watch(o
, handle
, NULL
, wctx
);
656 int IoCtx::write(const std::string
& oid
, bufferlist
& bl
, size_t len
,
658 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
659 return ctx
->execute_operation(
660 oid
, boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, len
, off
,
661 ctx
->get_snap_context()));
664 int IoCtx::write_full(const std::string
& oid
, bufferlist
& bl
) {
665 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
666 return ctx
->execute_operation(
667 oid
, boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
,
668 ctx
->get_snap_context()));
671 int IoCtx::writesame(const std::string
& oid
, bufferlist
& bl
, size_t len
,
673 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
674 return ctx
->execute_operation(
675 oid
, boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
, off
,
676 ctx
->get_snap_context()));
679 static int save_operation_result(int result
, int *pval
) {
686 ObjectOperation::ObjectOperation() {
687 TestObjectOperationImpl
*o
= new TestObjectOperationImpl();
689 impl
= reinterpret_cast<ObjectOperationImpl
*>(o
);
692 ObjectOperation::~ObjectOperation() {
693 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
700 void ObjectOperation::assert_exists() {
701 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
702 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::assert_exists
, _1
, _2
));
705 void ObjectOperation::exec(const char *cls
, const char *method
,
707 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
708 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::exec
, _1
, _2
,
709 get_class_handler(), cls
, method
, inbl
, _3
, _4
));
712 void ObjectOperation::set_op_flags2(int flags
) {
715 size_t ObjectOperation::size() {
716 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
717 return o
->ops
.size();
720 void ObjectReadOperation::list_snaps(snap_set_t
*out_snaps
, int *prval
) {
721 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
723 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
,
726 op
= boost::bind(save_operation_result
,
727 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
729 o
->ops
.push_back(op
);
732 void ObjectReadOperation::list_watchers(std::list
<obj_watch_t
> *out_watchers
,
734 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
736 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_watchers
, _1
,
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::read(size_t off
, uint64_t len
, bufferlist
*pbl
,
747 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
749 ObjectOperationTestImpl op
;
751 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, pbl
);
753 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, _3
);
757 op
= boost::bind(save_operation_result
,
758 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
760 o
->ops
.push_back(op
);
763 void ObjectReadOperation::sparse_read(uint64_t off
, uint64_t len
,
764 std::map
<uint64_t,uint64_t> *m
,
765 bufferlist
*pbl
, int *prval
) {
766 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
768 ObjectOperationTestImpl op
;
770 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, pbl
);
772 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, _3
);
776 op
= boost::bind(save_operation_result
,
777 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
779 o
->ops
.push_back(op
);
782 void ObjectReadOperation::stat(uint64_t *psize
, time_t *pmtime
, int *prval
) {
783 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
785 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::stat
, _1
, _2
,
789 op
= boost::bind(save_operation_result
,
790 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
792 o
->ops
.push_back(op
);
795 void ObjectWriteOperation::append(const bufferlist
&bl
) {
796 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
797 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::append
, _1
, _2
, bl
, _4
));
800 void ObjectWriteOperation::create(bool exclusive
) {
801 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
802 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
805 void ObjectWriteOperation::omap_set(const std::map
<std::string
, bufferlist
> &map
) {
806 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
807 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::omap_set
, _1
, _2
, boost::ref(map
)));
810 void ObjectWriteOperation::remove() {
811 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
812 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, _4
));
815 void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid
) {
816 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
817 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::selfmanaged_snap_rollback
,
821 void ObjectWriteOperation::set_alloc_hint(uint64_t expected_object_size
,
822 uint64_t expected_write_size
) {
823 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
824 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::set_alloc_hint
, _1
, _2
,
825 expected_object_size
, expected_write_size
));
829 void ObjectWriteOperation::tmap_update(const bufferlist
& cmdbl
) {
830 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
831 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
,
835 void ObjectWriteOperation::truncate(uint64_t off
) {
836 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
837 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
, _4
));
840 void ObjectWriteOperation::write(uint64_t off
, const bufferlist
& bl
) {
841 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
842 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, bl
.length(),
846 void ObjectWriteOperation::write_full(const bufferlist
& bl
) {
847 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
848 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
, _4
));
851 void ObjectWriteOperation::writesame(uint64_t off
, uint64_t len
, const bufferlist
& bl
) {
852 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
853 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
,
857 void ObjectWriteOperation::zero(uint64_t off
, uint64_t len
) {
858 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
859 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::zero
, _1
, _2
, off
, len
));
862 Rados::Rados() : client(NULL
) {
865 Rados::Rados(IoCtx
& ioctx
) {
866 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(ioctx
.io_ctx_impl
);
867 TestRadosClient
*impl
= ctx
->get_rados_client();
870 client
= reinterpret_cast<RadosClient
*>(impl
);
871 assert(client
!= NULL
);
878 AioCompletion
*Rados::aio_create_completion(void *cb_arg
,
879 callback_t cb_complete
,
880 callback_t cb_safe
) {
881 AioCompletionImpl
*c
;
882 int r
= rados_aio_create_completion(cb_arg
, cb_complete
, cb_safe
,
883 reinterpret_cast<void**>(&c
));
885 return new AioCompletion(c
);
888 int Rados::aio_watch_flush(AioCompletion
* c
) {
889 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
890 return impl
->aio_watch_flush(c
->pc
);
893 int Rados::blacklist_add(const std::string
& client_address
,
894 uint32_t expire_seconds
) {
895 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
896 return impl
->blacklist_add(client_address
, expire_seconds
);
899 config_t
Rados::cct() {
900 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
901 return reinterpret_cast<config_t
>(impl
->cct());
904 int Rados::cluster_fsid(std::string
* fsid
) {
905 *fsid
= "00000000-1111-2222-3333-444444444444";
909 int Rados::conf_set(const char *option
, const char *value
) {
910 return rados_conf_set(reinterpret_cast<rados_t
>(client
), option
, value
);
913 int Rados::conf_get(const char *option
, std::string
&val
) {
914 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
915 CephContext
*cct
= impl
->cct();
918 int ret
= cct
->_conf
->get_val(option
, &str
, -1);
929 int Rados::conf_parse_env(const char *env
) const {
930 return rados_conf_parse_env(reinterpret_cast<rados_t
>(client
), env
);
933 int Rados::conf_read_file(const char * const path
) const {
934 return rados_conf_read_file(reinterpret_cast<rados_t
>(client
), path
);
937 int Rados::connect() {
938 return rados_connect(reinterpret_cast<rados_t
>(client
));
941 uint64_t Rados::get_instance_id() {
942 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
943 return impl
->get_instance_id();
946 int Rados::init(const char * const id
) {
947 return rados_create(reinterpret_cast<rados_t
*>(&client
), id
);
950 int Rados::ioctx_create(const char *name
, IoCtx
&io
) {
952 int ret
= rados_ioctx_create(reinterpret_cast<rados_t
>(client
), name
, &p
);
958 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
962 int Rados::ioctx_create2(int64_t pool_id
, IoCtx
&io
)
965 int ret
= rados_ioctx_create2(reinterpret_cast<rados_t
>(client
), pool_id
, &p
);
971 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
975 int Rados::mon_command(std::string cmd
, const bufferlist
& inbl
,
976 bufferlist
*outbl
, std::string
*outs
) {
977 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
979 std::vector
<std::string
> cmds
;
981 return impl
->mon_command(cmds
, inbl
, outbl
, outs
);
984 int Rados::pool_create(const char *name
) {
985 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
986 return impl
->pool_create(name
);
989 int Rados::pool_delete(const char *name
) {
990 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
991 return impl
->pool_delete(name
);
994 int Rados::pool_get_base_tier(int64_t pool
, int64_t* base_tier
) {
995 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
996 return impl
->pool_get_base_tier(pool
, base_tier
);
999 int Rados::pool_list(std::list
<std::string
>& v
) {
1000 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1001 std::list
<std::pair
<int64_t, std::string
> > pools
;
1002 int r
= impl
->pool_list(pools
);
1008 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
= pools
.begin();
1009 it
!= pools
.end(); ++it
) {
1010 v
.push_back(it
->second
);
1015 int Rados::pool_list2(std::list
<std::pair
<int64_t, std::string
> >& v
)
1017 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1018 return impl
->pool_list(v
);
1021 int64_t Rados::pool_lookup(const char *name
) {
1022 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1023 return impl
->pool_lookup(name
);
1026 int Rados::pool_reverse_lookup(int64_t id
, std::string
*name
) {
1027 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1028 return impl
->pool_reverse_lookup(id
, name
);
1031 void Rados::shutdown() {
1032 if (client
== NULL
) {
1035 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1040 void Rados::test_blacklist_self(bool set
) {
1043 int Rados::wait_for_latest_osdmap() {
1044 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1045 return impl
->wait_for_latest_osdmap();
1048 int Rados::watch_flush() {
1049 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1050 return impl
->watch_flush();
1053 WatchCtx::~WatchCtx() {
1056 WatchCtx2::~WatchCtx2() {
1059 } // namespace librados
1061 int cls_cxx_create(cls_method_context_t hctx
, bool exclusive
) {
1062 librados::TestClassHandler::MethodContext
*ctx
=
1063 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1064 return ctx
->io_ctx_impl
->create(ctx
->oid
, exclusive
);
1067 int cls_get_request_origin(cls_method_context_t hctx
, entity_inst_t
*origin
) {
1068 librados::TestClassHandler::MethodContext
*ctx
=
1069 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1071 librados::TestRadosClient
*rados_client
=
1072 ctx
->io_ctx_impl
->get_rados_client();
1074 struct sockaddr_in sin
;
1075 sin
.sin_family
= AF_INET
;
1077 inet_pton(AF_INET
, "127.0.0.1", &sin
.sin_addr
);
1079 entity_addr_t
entity_addr(entity_addr_t::TYPE_DEFAULT
,
1080 rados_client
->get_nonce());
1081 entity_addr
.in4_addr() = sin
;
1083 *origin
= entity_inst_t(
1084 entity_name_t::CLIENT(rados_client
->get_instance_id()),
1089 int cls_cxx_getxattr(cls_method_context_t hctx
, const char *name
,
1090 bufferlist
*outbl
) {
1091 std::map
<string
, bufferlist
> attrs
;
1092 int r
= cls_cxx_getxattrs(hctx
, &attrs
);
1097 std::map
<string
, bufferlist
>::iterator it
= attrs
.find(name
);
1098 if (it
== attrs
.end()) {
1101 *outbl
= it
->second
;
1105 int cls_cxx_getxattrs(cls_method_context_t hctx
, std::map
<string
, bufferlist
> *attrset
) {
1106 librados::TestClassHandler::MethodContext
*ctx
=
1107 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1108 return ctx
->io_ctx_impl
->xattr_get(ctx
->oid
, attrset
);
1111 int cls_cxx_map_get_keys(cls_method_context_t hctx
, const string
&start_obj
,
1112 uint64_t max_to_get
, std::set
<string
> *keys
) {
1113 librados::TestClassHandler::MethodContext
*ctx
=
1114 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1117 std::map
<string
, bufferlist
> vals
;
1118 std::string last_key
= start_obj
;
1121 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, last_key
, "", 1024,
1127 for (std::map
<string
, bufferlist
>::iterator it
= vals
.begin();
1128 it
!= vals
.end(); ++it
) {
1129 last_key
= it
->first
;
1130 keys
->insert(last_key
);
1132 } while (!vals
.empty());
1133 return keys
->size();
1136 int cls_cxx_map_get_val(cls_method_context_t hctx
, const string
&key
,
1137 bufferlist
*outbl
) {
1138 librados::TestClassHandler::MethodContext
*ctx
=
1139 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1141 std::map
<string
, bufferlist
> vals
;
1142 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, "", key
, 1024, &vals
);
1147 std::map
<string
, bufferlist
>::iterator it
= vals
.find(key
);
1148 if (it
== vals
.end()) {
1152 *outbl
= it
->second
;
1156 int cls_cxx_map_get_vals(cls_method_context_t hctx
, const string
&start_obj
,
1157 const string
&filter_prefix
, uint64_t max_to_get
,
1158 std::map
<string
, bufferlist
> *vals
) {
1159 librados::TestClassHandler::MethodContext
*ctx
=
1160 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1161 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, start_obj
, filter_prefix
,
1166 return vals
->size();
1169 int cls_cxx_map_remove_key(cls_method_context_t hctx
, const string
&key
) {
1170 std::set
<std::string
> keys
;
1173 librados::TestClassHandler::MethodContext
*ctx
=
1174 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1175 return ctx
->io_ctx_impl
->omap_rm_keys(ctx
->oid
, keys
);
1178 int cls_cxx_map_set_val(cls_method_context_t hctx
, const string
&key
,
1180 std::map
<std::string
, bufferlist
> m
;
1182 return cls_cxx_map_set_vals(hctx
, &m
);
1185 int cls_cxx_map_set_vals(cls_method_context_t hctx
,
1186 const std::map
<string
, bufferlist
> *map
) {
1187 librados::TestClassHandler::MethodContext
*ctx
=
1188 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1189 return ctx
->io_ctx_impl
->omap_set(ctx
->oid
, *map
);
1192 int cls_cxx_read(cls_method_context_t hctx
, int ofs
, int len
,
1193 bufferlist
*outbl
) {
1194 return cls_cxx_read2(hctx
, ofs
, len
, outbl
, 0);
1197 int cls_cxx_read2(cls_method_context_t hctx
, int ofs
, int len
,
1198 bufferlist
*outbl
, uint32_t op_flags
) {
1199 librados::TestClassHandler::MethodContext
*ctx
=
1200 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1201 return ctx
->io_ctx_impl
->read(ctx
->oid
, len
, ofs
, outbl
);
1204 int cls_cxx_setxattr(cls_method_context_t hctx
, const char *name
,
1206 librados::TestClassHandler::MethodContext
*ctx
=
1207 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1208 return ctx
->io_ctx_impl
->xattr_set(ctx
->oid
, name
, *inbl
);
1211 int cls_cxx_stat(cls_method_context_t hctx
, uint64_t *size
, time_t *mtime
) {
1212 librados::TestClassHandler::MethodContext
*ctx
=
1213 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1214 return ctx
->io_ctx_impl
->stat(ctx
->oid
, size
, mtime
);
1217 int cls_cxx_write(cls_method_context_t hctx
, int ofs
, int len
,
1219 return cls_cxx_write2(hctx
, ofs
, len
, inbl
, 0);
1222 int cls_cxx_write2(cls_method_context_t hctx
, int ofs
, int len
,
1223 bufferlist
*inbl
, uint32_t op_flags
) {
1224 librados::TestClassHandler::MethodContext
*ctx
=
1225 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1226 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1229 int cls_cxx_write_full(cls_method_context_t hctx
, bufferlist
*inbl
) {
1230 librados::TestClassHandler::MethodContext
*ctx
=
1231 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1232 return ctx
->io_ctx_impl
->write_full(ctx
->oid
, *inbl
, ctx
->snapc
);
1235 int cls_cxx_list_watchers(cls_method_context_t hctx
,
1236 obj_list_watch_response_t
*watchers
) {
1237 librados::TestClassHandler::MethodContext
*ctx
=
1238 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1240 std::list
<obj_watch_t
> obj_watchers
;
1241 int r
= ctx
->io_ctx_impl
->list_watchers(ctx
->oid
, &obj_watchers
);
1246 for (auto &w
: obj_watchers
) {
1247 watch_item_t watcher
;
1248 watcher
.name
= entity_name_t::CLIENT(w
.watcher_id
);
1249 watcher
.cookie
= w
.cookie
;
1250 watcher
.timeout_seconds
= w
.timeout_seconds
;
1251 watcher
.addr
.parse(w
.addr
, 0);
1252 watchers
->entries
.push_back(watcher
);
1258 uint64_t cls_get_features(cls_method_context_t hctx
) {
1259 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1262 uint64_t cls_get_client_features(cls_method_context_t hctx
) {
1263 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1266 int cls_log(int level
, const char *format
, ...) {
1271 va_start(ap
, format
);
1272 int n
= vsnprintf(buf
, size
, format
, ap
);
1274 if ((n
> -1 && n
< size
) || size
> 8196) {
1275 dout(level
) << buf
<< dendl
;
1283 int cls_register(const char *name
, cls_handle_t
*handle
) {
1284 librados::TestClassHandler
*cls
= get_class_handler();
1285 return cls
->create(name
, handle
);
1288 int cls_register_cxx_method(cls_handle_t hclass
, const char *method
,
1290 cls_method_cxx_call_t class_call
,
1291 cls_method_handle_t
*handle
) {
1292 librados::TestClassHandler
*cls
= get_class_handler();
1293 return cls
->create_method(hclass
, method
, class_call
, handle
);
1296 int cls_register_cxx_filter(cls_handle_t hclass
,
1297 const std::string
&filter_name
,
1298 cls_cxx_filter_factory_t fn
,
1299 cls_filter_handle_t
*)
1301 librados::TestClassHandler
*cls
= get_class_handler();
1302 return cls
->create_filter(hclass
, filter_name
, fn
);