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 int IoCtx::cmpext(const std::string
& oid
, uint64_t off
, bufferlist
& cmp_bl
) {
693 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
694 return ctx
->execute_operation(
695 oid
, boost::bind(&TestIoCtxImpl::cmpext
, _1
, _2
, off
, cmp_bl
));
698 int IoCtx::application_enable(const std::string
& app_name
, bool force
) {
702 int IoCtx::application_enable_async(const std::string
& app_name
,
703 bool force
, PoolAsyncCompletion
*c
) {
707 int IoCtx::application_list(std::set
<std::string
> *app_names
) {
711 int IoCtx::application_metadata_get(const std::string
& app_name
,
712 const std::string
&key
,
713 std::string
*value
) {
717 int IoCtx::application_metadata_set(const std::string
& app_name
,
718 const std::string
&key
,
719 const std::string
& value
) {
723 int IoCtx::application_metadata_remove(const std::string
& app_name
,
724 const std::string
&key
) {
728 int IoCtx::application_metadata_list(const std::string
& app_name
,
729 std::map
<std::string
, std::string
> *values
) {
733 static int save_operation_result(int result
, int *pval
) {
740 ObjectOperation::ObjectOperation() {
741 TestObjectOperationImpl
*o
= new TestObjectOperationImpl();
743 impl
= reinterpret_cast<ObjectOperationImpl
*>(o
);
746 ObjectOperation::~ObjectOperation() {
747 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
754 void ObjectOperation::assert_exists() {
755 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
756 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::assert_exists
, _1
, _2
));
759 void ObjectOperation::exec(const char *cls
, const char *method
,
761 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
762 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::exec
, _1
, _2
,
763 get_class_handler(), cls
, method
, inbl
, _3
, _4
));
766 void ObjectOperation::set_op_flags2(int flags
) {
769 size_t ObjectOperation::size() {
770 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
771 return o
->ops
.size();
774 void ObjectOperation::cmpext(uint64_t off
, bufferlist
& cmp_bl
, int *prval
) {
775 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
776 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::cmpext
, _1
, _2
, off
, cmp_bl
);
778 op
= boost::bind(save_operation_result
,
779 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
781 o
->ops
.push_back(op
);
784 void ObjectReadOperation::list_snaps(snap_set_t
*out_snaps
, int *prval
) {
785 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
787 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
,
790 op
= boost::bind(save_operation_result
,
791 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
793 o
->ops
.push_back(op
);
796 void ObjectReadOperation::list_watchers(std::list
<obj_watch_t
> *out_watchers
,
798 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
800 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_watchers
, _1
,
803 op
= boost::bind(save_operation_result
,
804 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
806 o
->ops
.push_back(op
);
809 void ObjectReadOperation::read(size_t off
, uint64_t len
, bufferlist
*pbl
,
811 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
813 ObjectOperationTestImpl op
;
815 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, pbl
);
817 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, _3
);
821 op
= boost::bind(save_operation_result
,
822 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
824 o
->ops
.push_back(op
);
827 void ObjectReadOperation::sparse_read(uint64_t off
, uint64_t len
,
828 std::map
<uint64_t,uint64_t> *m
,
829 bufferlist
*pbl
, int *prval
) {
830 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
832 ObjectOperationTestImpl op
;
834 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, pbl
);
836 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, _3
);
840 op
= boost::bind(save_operation_result
,
841 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
843 o
->ops
.push_back(op
);
846 void ObjectReadOperation::stat(uint64_t *psize
, time_t *pmtime
, int *prval
) {
847 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
849 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::stat
, _1
, _2
,
853 op
= boost::bind(save_operation_result
,
854 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
856 o
->ops
.push_back(op
);
859 void ObjectWriteOperation::append(const bufferlist
&bl
) {
860 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
861 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::append
, _1
, _2
, bl
, _4
));
864 void ObjectWriteOperation::create(bool exclusive
) {
865 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
866 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
869 void ObjectWriteOperation::omap_set(const std::map
<std::string
, bufferlist
> &map
) {
870 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
871 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::omap_set
, _1
, _2
, boost::ref(map
)));
874 void ObjectWriteOperation::remove() {
875 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
876 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, _4
));
879 void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid
) {
880 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
881 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::selfmanaged_snap_rollback
,
885 void ObjectWriteOperation::set_alloc_hint(uint64_t expected_object_size
,
886 uint64_t expected_write_size
) {
887 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
888 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::set_alloc_hint
, _1
, _2
,
889 expected_object_size
, expected_write_size
));
893 void ObjectWriteOperation::tmap_update(const bufferlist
& cmdbl
) {
894 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
895 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
,
899 void ObjectWriteOperation::truncate(uint64_t off
) {
900 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
901 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
, _4
));
904 void ObjectWriteOperation::write(uint64_t off
, const bufferlist
& bl
) {
905 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
906 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, bl
.length(),
910 void ObjectWriteOperation::write_full(const bufferlist
& bl
) {
911 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
912 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
, _4
));
915 void ObjectWriteOperation::writesame(uint64_t off
, uint64_t len
, const bufferlist
& bl
) {
916 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
917 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
,
921 void ObjectWriteOperation::zero(uint64_t off
, uint64_t len
) {
922 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
923 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::zero
, _1
, _2
, off
, len
));
926 Rados::Rados() : client(NULL
) {
929 Rados::Rados(IoCtx
& ioctx
) {
930 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(ioctx
.io_ctx_impl
);
931 TestRadosClient
*impl
= ctx
->get_rados_client();
934 client
= reinterpret_cast<RadosClient
*>(impl
);
935 assert(client
!= NULL
);
942 AioCompletion
*Rados::aio_create_completion(void *cb_arg
,
943 callback_t cb_complete
,
944 callback_t cb_safe
) {
945 AioCompletionImpl
*c
;
946 int r
= rados_aio_create_completion(cb_arg
, cb_complete
, cb_safe
,
947 reinterpret_cast<void**>(&c
));
949 return new AioCompletion(c
);
952 int Rados::aio_watch_flush(AioCompletion
* c
) {
953 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
954 return impl
->aio_watch_flush(c
->pc
);
957 int Rados::blacklist_add(const std::string
& client_address
,
958 uint32_t expire_seconds
) {
959 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
960 return impl
->blacklist_add(client_address
, expire_seconds
);
963 config_t
Rados::cct() {
964 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
965 return reinterpret_cast<config_t
>(impl
->cct());
968 int Rados::cluster_fsid(std::string
* fsid
) {
969 *fsid
= "00000000-1111-2222-3333-444444444444";
973 int Rados::conf_set(const char *option
, const char *value
) {
974 return rados_conf_set(reinterpret_cast<rados_t
>(client
), option
, value
);
977 int Rados::conf_get(const char *option
, std::string
&val
) {
978 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
979 CephContext
*cct
= impl
->cct();
982 int ret
= cct
->_conf
->get_val(option
, &str
, -1);
993 int Rados::conf_parse_env(const char *env
) const {
994 return rados_conf_parse_env(reinterpret_cast<rados_t
>(client
), env
);
997 int Rados::conf_read_file(const char * const path
) const {
998 return rados_conf_read_file(reinterpret_cast<rados_t
>(client
), path
);
1001 int Rados::connect() {
1002 return rados_connect(reinterpret_cast<rados_t
>(client
));
1005 uint64_t Rados::get_instance_id() {
1006 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1007 return impl
->get_instance_id();
1010 int Rados::init(const char * const id
) {
1011 return rados_create(reinterpret_cast<rados_t
*>(&client
), id
);
1014 int Rados::ioctx_create(const char *name
, IoCtx
&io
) {
1016 int ret
= rados_ioctx_create(reinterpret_cast<rados_t
>(client
), name
, &p
);
1022 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
1026 int Rados::ioctx_create2(int64_t pool_id
, IoCtx
&io
)
1029 int ret
= rados_ioctx_create2(reinterpret_cast<rados_t
>(client
), pool_id
, &p
);
1035 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
1039 int Rados::mon_command(std::string cmd
, const bufferlist
& inbl
,
1040 bufferlist
*outbl
, std::string
*outs
) {
1041 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1043 std::vector
<std::string
> cmds
;
1044 cmds
.push_back(cmd
);
1045 return impl
->mon_command(cmds
, inbl
, outbl
, outs
);
1048 int Rados::service_daemon_register(const std::string
& service
,
1049 const std::string
& name
,
1050 const std::map
<std::string
,std::string
>& metadata
) {
1051 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1052 return impl
->service_daemon_register(service
, name
, metadata
);
1055 int Rados::service_daemon_update_status(const std::map
<std::string
,std::string
>& status
) {
1056 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1057 return impl
->service_daemon_update_status(status
);
1060 int Rados::pool_create(const char *name
) {
1061 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1062 return impl
->pool_create(name
);
1065 int Rados::pool_delete(const char *name
) {
1066 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1067 return impl
->pool_delete(name
);
1070 int Rados::pool_get_base_tier(int64_t pool
, int64_t* base_tier
) {
1071 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1072 return impl
->pool_get_base_tier(pool
, base_tier
);
1075 int Rados::pool_list(std::list
<std::string
>& v
) {
1076 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1077 std::list
<std::pair
<int64_t, std::string
> > pools
;
1078 int r
= impl
->pool_list(pools
);
1084 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
= pools
.begin();
1085 it
!= pools
.end(); ++it
) {
1086 v
.push_back(it
->second
);
1091 int Rados::pool_list2(std::list
<std::pair
<int64_t, std::string
> >& v
)
1093 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1094 return impl
->pool_list(v
);
1097 int64_t Rados::pool_lookup(const char *name
) {
1098 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1099 return impl
->pool_lookup(name
);
1102 int Rados::pool_reverse_lookup(int64_t id
, std::string
*name
) {
1103 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1104 return impl
->pool_reverse_lookup(id
, name
);
1107 void Rados::shutdown() {
1108 if (client
== NULL
) {
1111 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1116 void Rados::test_blacklist_self(bool set
) {
1119 int Rados::wait_for_latest_osdmap() {
1120 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1121 return impl
->wait_for_latest_osdmap();
1124 int Rados::watch_flush() {
1125 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1126 return impl
->watch_flush();
1129 WatchCtx::~WatchCtx() {
1132 WatchCtx2::~WatchCtx2() {
1135 } // namespace librados
1137 int cls_cxx_create(cls_method_context_t hctx
, bool exclusive
) {
1138 librados::TestClassHandler::MethodContext
*ctx
=
1139 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1140 return ctx
->io_ctx_impl
->create(ctx
->oid
, exclusive
);
1143 int cls_get_request_origin(cls_method_context_t hctx
, entity_inst_t
*origin
) {
1144 librados::TestClassHandler::MethodContext
*ctx
=
1145 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1147 librados::TestRadosClient
*rados_client
=
1148 ctx
->io_ctx_impl
->get_rados_client();
1150 struct sockaddr_in sin
;
1151 sin
.sin_family
= AF_INET
;
1153 inet_pton(AF_INET
, "127.0.0.1", &sin
.sin_addr
);
1155 entity_addr_t
entity_addr(entity_addr_t::TYPE_DEFAULT
,
1156 rados_client
->get_nonce());
1157 entity_addr
.in4_addr() = sin
;
1159 *origin
= entity_inst_t(
1160 entity_name_t::CLIENT(rados_client
->get_instance_id()),
1165 int cls_cxx_getxattr(cls_method_context_t hctx
, const char *name
,
1166 bufferlist
*outbl
) {
1167 std::map
<string
, bufferlist
> attrs
;
1168 int r
= cls_cxx_getxattrs(hctx
, &attrs
);
1173 std::map
<string
, bufferlist
>::iterator it
= attrs
.find(name
);
1174 if (it
== attrs
.end()) {
1177 *outbl
= it
->second
;
1181 int cls_cxx_getxattrs(cls_method_context_t hctx
, std::map
<string
, bufferlist
> *attrset
) {
1182 librados::TestClassHandler::MethodContext
*ctx
=
1183 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1184 return ctx
->io_ctx_impl
->xattr_get(ctx
->oid
, attrset
);
1187 int cls_cxx_map_get_keys(cls_method_context_t hctx
, const string
&start_obj
,
1188 uint64_t max_to_get
, std::set
<string
> *keys
, bool *more
) {
1189 librados::TestClassHandler::MethodContext
*ctx
=
1190 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1193 std::map
<string
, bufferlist
> vals
;
1194 int r
= ctx
->io_ctx_impl
->omap_get_vals2(ctx
->oid
, start_obj
, "", max_to_get
,
1200 for (std::map
<string
, bufferlist
>::iterator it
= vals
.begin();
1201 it
!= vals
.end(); ++it
) {
1202 keys
->insert(it
->first
);
1204 return keys
->size();
1207 int cls_cxx_map_get_val(cls_method_context_t hctx
, const string
&key
,
1208 bufferlist
*outbl
) {
1209 librados::TestClassHandler::MethodContext
*ctx
=
1210 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1212 std::map
<string
, bufferlist
> vals
;
1213 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, "", key
, 1024, &vals
);
1218 std::map
<string
, bufferlist
>::iterator it
= vals
.find(key
);
1219 if (it
== vals
.end()) {
1223 *outbl
= it
->second
;
1227 int cls_cxx_map_get_vals(cls_method_context_t hctx
, const string
&start_obj
,
1228 const string
&filter_prefix
, uint64_t max_to_get
,
1229 std::map
<string
, bufferlist
> *vals
, bool *more
) {
1230 librados::TestClassHandler::MethodContext
*ctx
=
1231 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1232 int r
= ctx
->io_ctx_impl
->omap_get_vals2(ctx
->oid
, start_obj
, filter_prefix
,
1233 max_to_get
, vals
, more
);
1237 return vals
->size();
1240 int cls_cxx_map_remove_key(cls_method_context_t hctx
, const string
&key
) {
1241 std::set
<std::string
> keys
;
1244 librados::TestClassHandler::MethodContext
*ctx
=
1245 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1246 return ctx
->io_ctx_impl
->omap_rm_keys(ctx
->oid
, keys
);
1249 int cls_cxx_map_set_val(cls_method_context_t hctx
, const string
&key
,
1251 std::map
<std::string
, bufferlist
> m
;
1253 return cls_cxx_map_set_vals(hctx
, &m
);
1256 int cls_cxx_map_set_vals(cls_method_context_t hctx
,
1257 const std::map
<string
, bufferlist
> *map
) {
1258 librados::TestClassHandler::MethodContext
*ctx
=
1259 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1260 return ctx
->io_ctx_impl
->omap_set(ctx
->oid
, *map
);
1263 int cls_cxx_read(cls_method_context_t hctx
, int ofs
, int len
,
1264 bufferlist
*outbl
) {
1265 return cls_cxx_read2(hctx
, ofs
, len
, outbl
, 0);
1268 int cls_cxx_read2(cls_method_context_t hctx
, int ofs
, int len
,
1269 bufferlist
*outbl
, uint32_t op_flags
) {
1270 librados::TestClassHandler::MethodContext
*ctx
=
1271 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1272 return ctx
->io_ctx_impl
->read(ctx
->oid
, len
, ofs
, outbl
);
1275 int cls_cxx_setxattr(cls_method_context_t hctx
, const char *name
,
1277 librados::TestClassHandler::MethodContext
*ctx
=
1278 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1279 return ctx
->io_ctx_impl
->xattr_set(ctx
->oid
, name
, *inbl
);
1282 int cls_cxx_stat(cls_method_context_t hctx
, uint64_t *size
, time_t *mtime
) {
1283 librados::TestClassHandler::MethodContext
*ctx
=
1284 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1285 return ctx
->io_ctx_impl
->stat(ctx
->oid
, size
, mtime
);
1288 int cls_cxx_write(cls_method_context_t hctx
, int ofs
, int len
,
1290 return cls_cxx_write2(hctx
, ofs
, len
, inbl
, 0);
1293 int cls_cxx_write2(cls_method_context_t hctx
, int ofs
, int len
,
1294 bufferlist
*inbl
, uint32_t op_flags
) {
1295 librados::TestClassHandler::MethodContext
*ctx
=
1296 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1297 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1300 int cls_cxx_write_full(cls_method_context_t hctx
, bufferlist
*inbl
) {
1301 librados::TestClassHandler::MethodContext
*ctx
=
1302 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1303 return ctx
->io_ctx_impl
->write_full(ctx
->oid
, *inbl
, ctx
->snapc
);
1306 int cls_cxx_list_watchers(cls_method_context_t hctx
,
1307 obj_list_watch_response_t
*watchers
) {
1308 librados::TestClassHandler::MethodContext
*ctx
=
1309 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1311 std::list
<obj_watch_t
> obj_watchers
;
1312 int r
= ctx
->io_ctx_impl
->list_watchers(ctx
->oid
, &obj_watchers
);
1317 for (auto &w
: obj_watchers
) {
1318 watch_item_t watcher
;
1319 watcher
.name
= entity_name_t::CLIENT(w
.watcher_id
);
1320 watcher
.cookie
= w
.cookie
;
1321 watcher
.timeout_seconds
= w
.timeout_seconds
;
1322 watcher
.addr
.parse(w
.addr
, 0);
1323 watchers
->entries
.push_back(watcher
);
1329 uint64_t cls_get_features(cls_method_context_t hctx
) {
1330 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1333 uint64_t cls_get_client_features(cls_method_context_t hctx
) {
1334 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1337 int cls_log(int level
, const char *format
, ...) {
1342 va_start(ap
, format
);
1343 int n
= vsnprintf(buf
, size
, format
, ap
);
1345 if ((n
> -1 && n
< size
) || size
> 8196) {
1346 dout(level
) << buf
<< dendl
;
1354 int cls_register(const char *name
, cls_handle_t
*handle
) {
1355 librados::TestClassHandler
*cls
= get_class_handler();
1356 return cls
->create(name
, handle
);
1359 int cls_register_cxx_method(cls_handle_t hclass
, const char *method
,
1361 cls_method_cxx_call_t class_call
,
1362 cls_method_handle_t
*handle
) {
1363 librados::TestClassHandler
*cls
= get_class_handler();
1364 return cls
->create_method(hclass
, method
, class_call
, handle
);
1367 int cls_register_cxx_filter(cls_handle_t hclass
,
1368 const std::string
&filter_name
,
1369 cls_cxx_filter_factory_t fn
,
1370 cls_filter_handle_t
*)
1372 librados::TestClassHandler
*cls
= get_class_handler();
1373 return cls
->create_filter(hclass
, filter_name
, fn
);