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/ceph_context.h"
9 #include "common/common_init.h"
10 #include "common/config.h"
11 #include "common/debug.h"
12 #include "common/snap_types.h"
13 #include "librados/AioCompletionImpl.h"
15 #include "test/librados_test_stub/TestClassHandler.h"
16 #include "test/librados_test_stub/TestIoCtxImpl.h"
17 #include "test/librados_test_stub/TestRadosClient.h"
18 #include "test/librados_test_stub/TestMemCluster.h"
19 #include "test/librados_test_stub/TestMemRadosClient.h"
20 #include "objclass/objclass.h"
21 #include "osd/osd_types.h"
22 #include <arpa/inet.h>
23 #include <boost/bind.hpp>
24 #include <boost/shared_ptr.hpp>
28 #include "include/ceph_assert.h"
29 #include "include/compat.h"
31 #define dout_context g_ceph_context
32 #define dout_subsys ceph_subsys_rados
36 MockTestMemIoCtxImpl
&get_mock_io_ctx(IoCtx
&ioctx
) {
37 MockTestMemIoCtxImpl
**mock
=
38 reinterpret_cast<MockTestMemIoCtxImpl
**>(&ioctx
);
42 } // namespace librados
44 namespace librados_test_stub
{
46 TestClusterRef
&cluster() {
47 static TestClusterRef s_cluster
;
51 void set_cluster(TestClusterRef cluster_ref
) {
52 cluster() = cluster_ref
;
55 TestClusterRef
get_cluster() {
56 auto &cluster_ref
= cluster();
57 if (cluster_ref
.get() == nullptr) {
58 cluster_ref
.reset(new librados::TestMemCluster());
63 } // namespace librados_test_stub
67 librados::TestClassHandler
*get_class_handler() {
68 static boost::shared_ptr
<librados::TestClassHandler
> s_class_handler
;
69 if (!s_class_handler
) {
70 s_class_handler
.reset(new librados::TestClassHandler());
71 s_class_handler
->open_all_classes();
73 return s_class_handler
.get();
76 void do_out_buffer(bufferlist
& outbl
, char **outbuf
, size_t *outbuflen
) {
78 if (outbl
.length() > 0) {
79 *outbuf
= (char *)malloc(outbl
.length());
80 memcpy(*outbuf
, outbl
.c_str(), outbl
.length());
86 *outbuflen
= outbl
.length();
90 void do_out_buffer(string
& outbl
, char **outbuf
, size_t *outbuflen
) {
92 if (outbl
.length() > 0) {
93 *outbuf
= (char *)malloc(outbl
.length());
94 memcpy(*outbuf
, outbl
.c_str(), outbl
.length());
100 *outbuflen
= outbl
.length();
104 librados::TestRadosClient
*create_rados_client() {
105 CephInitParameters
iparams(CEPH_ENTITY_TYPE_CLIENT
);
106 CephContext
*cct
= common_preinit(iparams
, CODE_ENVIRONMENT_LIBRARY
, 0);
107 cct
->_conf
.parse_env(cct
->get_module_type());
108 cct
->_conf
.apply_changes(nullptr);
112 librados_test_stub::get_cluster()->create_rados_client(cct
);
117 } // anonymous namespace
119 extern "C" int rados_aio_create_completion(void *cb_arg
,
120 rados_callback_t cb_complete
,
121 rados_callback_t cb_safe
,
122 rados_completion_t
*pc
)
124 librados::AioCompletionImpl
*c
= new librados::AioCompletionImpl
;
126 c
->set_complete_callback(cb_arg
, cb_complete
);
129 c
->set_safe_callback(cb_arg
, cb_safe
);
135 extern "C" int rados_aio_get_return_value(rados_completion_t c
) {
136 return reinterpret_cast<librados::AioCompletionImpl
*>(c
)->get_return_value();
139 extern "C" rados_config_t
rados_cct(rados_t cluster
)
141 librados::TestRadosClient
*client
=
142 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
143 return reinterpret_cast<rados_config_t
>(client
->cct());
146 extern "C" int rados_conf_set(rados_t cluster
, const char *option
,
148 librados::TestRadosClient
*impl
=
149 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
150 CephContext
*cct
= impl
->cct();
151 return cct
->_conf
.set_val(option
, value
);
154 extern "C" int rados_conf_parse_env(rados_t cluster
, const char *var
) {
155 librados::TestRadosClient
*client
=
156 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
157 auto& conf
= client
->cct()->_conf
;
158 conf
.parse_env(client
->cct()->get_module_type(), var
);
159 conf
.apply_changes(NULL
);
163 extern "C" int rados_conf_read_file(rados_t cluster
, const char *path
) {
164 librados::TestRadosClient
*client
=
165 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
166 auto& conf
= client
->cct()->_conf
;
167 int ret
= conf
.parse_config_files(path
, NULL
, 0);
169 conf
.parse_env(client
->cct()->get_module_type());
170 conf
.apply_changes(NULL
);
171 conf
.complain_about_parse_errors(client
->cct());
172 } else if (ret
== -ENOENT
) {
173 // ignore missing client config
179 extern "C" int rados_connect(rados_t cluster
) {
180 librados::TestRadosClient
*client
=
181 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
182 return client
->connect();
185 extern "C" int rados_create(rados_t
*cluster
, const char * const id
) {
186 *cluster
= create_rados_client();
190 extern "C" int rados_create_with_context(rados_t
*cluster
,
191 rados_config_t cct_
) {
192 auto cct
= reinterpret_cast<CephContext
*>(cct_
);
193 *cluster
= librados_test_stub::get_cluster()->create_rados_client(cct
);
197 extern "C" rados_config_t
rados_ioctx_cct(rados_ioctx_t ioctx
)
199 librados::TestIoCtxImpl
*ctx
=
200 reinterpret_cast<librados::TestIoCtxImpl
*>(ioctx
);
201 return reinterpret_cast<rados_config_t
>(ctx
->get_rados_client()->cct());
204 extern "C" int rados_ioctx_create(rados_t cluster
, const char *pool_name
,
205 rados_ioctx_t
*ioctx
) {
206 librados::TestRadosClient
*client
=
207 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
209 int64_t pool_id
= client
->pool_lookup(pool_name
);
211 return static_cast<int>(pool_id
);
214 *ioctx
= reinterpret_cast<rados_ioctx_t
>(
215 client
->create_ioctx(pool_id
, pool_name
));
219 extern "C" int rados_ioctx_create2(rados_t cluster
, int64_t pool_id
,
220 rados_ioctx_t
*ioctx
)
222 librados::TestRadosClient
*client
=
223 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
225 std::list
<std::pair
<int64_t, std::string
> > pools
;
226 int r
= client
->pool_list(pools
);
231 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
=
232 pools
.begin(); it
!= pools
.end(); ++it
) {
233 if (it
->first
== pool_id
) {
234 *ioctx
= reinterpret_cast<rados_ioctx_t
>(
235 client
->create_ioctx(pool_id
, it
->second
));
242 extern "C" void rados_ioctx_destroy(rados_ioctx_t io
) {
243 librados::TestIoCtxImpl
*ctx
=
244 reinterpret_cast<librados::TestIoCtxImpl
*>(io
);
248 extern "C" rados_t
rados_ioctx_get_cluster(rados_ioctx_t io
) {
249 librados::TestIoCtxImpl
*ctx
=
250 reinterpret_cast<librados::TestIoCtxImpl
*>(io
);
251 return reinterpret_cast<rados_t
>(ctx
->get_rados_client());
254 extern "C" int rados_mon_command(rados_t cluster
, const char **cmd
,
255 size_t cmdlen
, const char *inbuf
,
256 size_t inbuflen
, char **outbuf
,
257 size_t *outbuflen
, char **outs
,
259 librados::TestRadosClient
*client
=
260 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
262 vector
<string
> cmdvec
;
263 for (size_t i
= 0; i
< cmdlen
; i
++) {
264 cmdvec
.push_back(cmd
[i
]);
268 inbl
.append(inbuf
, inbuflen
);
272 int ret
= client
->mon_command(cmdvec
, inbl
, &outbl
, &outstring
);
274 do_out_buffer(outbl
, outbuf
, outbuflen
);
275 do_out_buffer(outstring
, outs
, outslen
);
279 extern "C" int rados_nobjects_list_open(rados_ioctx_t io
,
280 rados_list_ctx_t
*ctx
) {
281 librados::TestIoCtxImpl
*io_ctx
=
282 reinterpret_cast<librados::TestIoCtxImpl
*>(io
);
283 librados::TestRadosClient
*client
= io_ctx
->get_rados_client();
285 std::list
<librados::TestRadosClient::Object
> *list
=
286 new std::list
<librados::TestRadosClient::Object
>();
288 client
->object_list(io_ctx
->get_id(), list
);
289 list
->push_front(librados::TestRadosClient::Object());
290 *ctx
= reinterpret_cast<rados_list_ctx_t
>(list
);
294 extern "C" int rados_nobjects_list_next(rados_list_ctx_t ctx
,
297 const char **nspace
) {
298 std::list
<librados::TestRadosClient::Object
> *list
=
299 reinterpret_cast<std::list
<librados::TestRadosClient::Object
> *>(ctx
);
300 if (!list
->empty()) {
307 librados::TestRadosClient::Object
&obj
= list
->front();
309 *entry
= obj
.oid
.c_str();
312 *key
= obj
.locator
.c_str();
314 if (nspace
!= NULL
) {
315 *nspace
= obj
.nspace
.c_str();
320 extern "C" void rados_nobjects_list_close(rados_list_ctx_t ctx
) {
321 std::list
<librados::TestRadosClient::Object
> *list
=
322 reinterpret_cast<std::list
<librados::TestRadosClient::Object
> *>(ctx
);
326 extern "C" int rados_pool_create(rados_t cluster
, const char *pool_name
) {
327 librados::TestRadosClient
*client
=
328 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
329 return client
->pool_create(pool_name
);
332 extern "C" int rados_pool_delete(rados_t cluster
, const char *pool_name
) {
333 librados::TestRadosClient
*client
=
334 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
335 return client
->pool_delete(pool_name
);
338 extern "C" void rados_shutdown(rados_t cluster
) {
339 librados::TestRadosClient
*client
=
340 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
344 extern "C" int rados_wait_for_latest_osdmap(rados_t cluster
) {
345 librados::TestRadosClient
*client
=
346 reinterpret_cast<librados::TestRadosClient
*>(cluster
);
347 return client
->wait_for_latest_osdmap();
352 void AioCompletion::release() {
353 AioCompletionImpl
*c
= reinterpret_cast<AioCompletionImpl
*>(pc
);
358 IoCtx::IoCtx() : io_ctx_impl(NULL
) {
365 IoCtx::IoCtx(const IoCtx
& rhs
) {
366 io_ctx_impl
= rhs
.io_ctx_impl
;
368 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
373 IoCtx::IoCtx(IoCtx
&& rhs
) noexcept
: io_ctx_impl(std::exchange(rhs
.io_ctx_impl
, nullptr))
377 IoCtx
& IoCtx::operator=(const IoCtx
& rhs
) {
379 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
383 io_ctx_impl
= rhs
.io_ctx_impl
;
385 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
391 librados::IoCtx
& librados::IoCtx::operator=(IoCtx
&& rhs
) noexcept
394 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
398 io_ctx_impl
= std::exchange(rhs
.io_ctx_impl
, nullptr);
402 int IoCtx::aio_flush() {
403 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
408 int IoCtx::aio_flush_async(AioCompletion
*c
) {
409 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
410 ctx
->aio_flush_async(c
->pc
);
414 int IoCtx::aio_notify(const std::string
& oid
, AioCompletion
*c
, bufferlist
& bl
,
415 uint64_t timeout_ms
, bufferlist
*pbl
) {
416 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
417 ctx
->aio_notify(oid
, c
->pc
, bl
, timeout_ms
, pbl
);
421 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
422 ObjectReadOperation
*op
, bufferlist
*pbl
) {
423 return aio_operate(oid
, c
, op
, 0, pbl
);
426 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
427 ObjectReadOperation
*op
, int flags
,
429 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
430 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
431 return ctx
->aio_operate_read(oid
, *ops
, c
->pc
, flags
, pbl
);
434 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
435 ObjectReadOperation
*op
, int flags
,
436 bufferlist
*pbl
, const blkin_trace_info
*trace_info
) {
437 return aio_operate(oid
, c
, op
, flags
, pbl
);
440 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
441 ObjectWriteOperation
*op
) {
442 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
443 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
444 return ctx
->aio_operate(oid
, *ops
, c
->pc
, NULL
, 0);
447 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
448 ObjectWriteOperation
*op
, snap_t seq
,
449 std::vector
<snap_t
>& snaps
, int flags
,
450 const blkin_trace_info
*trace_info
) {
451 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
452 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
454 std::vector
<snapid_t
> snv
;
455 snv
.resize(snaps
.size());
456 for (size_t i
= 0; i
< snaps
.size(); ++i
)
458 SnapContext
snapc(seq
, snv
);
460 return ctx
->aio_operate(oid
, *ops
, c
->pc
, &snapc
, flags
);
463 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
464 ObjectWriteOperation
*op
, snap_t seq
,
465 std::vector
<snap_t
>& snaps
) {
466 return aio_operate(oid
, c
, op
, seq
, snaps
, 0, nullptr);
469 int IoCtx::aio_operate(const std::string
& oid
, AioCompletion
*c
,
470 ObjectWriteOperation
*op
, snap_t seq
,
471 std::vector
<snap_t
>& snaps
,
472 const blkin_trace_info
*trace_info
) {
473 return aio_operate(oid
, c
, op
, seq
, snaps
, 0, trace_info
);
476 int IoCtx::aio_remove(const std::string
& oid
, AioCompletion
*c
) {
477 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
478 return ctx
->aio_remove(oid
, c
->pc
);
481 int IoCtx::aio_remove(const std::string
& oid
, AioCompletion
*c
, int flags
) {
482 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
483 return ctx
->aio_remove(oid
, c
->pc
, flags
);
486 int IoCtx::aio_watch(const std::string
& o
, AioCompletion
*c
, uint64_t *handle
,
487 librados::WatchCtx2
*watch_ctx
) {
488 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
489 return ctx
->aio_watch(o
, c
->pc
, handle
, watch_ctx
);
492 int IoCtx::aio_unwatch(uint64_t handle
, AioCompletion
*c
) {
493 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
494 return ctx
->aio_unwatch(handle
, c
->pc
);
497 config_t
IoCtx::cct() {
498 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
499 return reinterpret_cast<config_t
>(ctx
->get_rados_client()->cct());
502 void IoCtx::close() {
504 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
510 int IoCtx::create(const std::string
& oid
, bool exclusive
) {
511 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
512 return ctx
->execute_operation(
513 oid
, boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
516 void IoCtx::dup(const IoCtx
& rhs
) {
518 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(rhs
.io_ctx_impl
);
519 io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(ctx
->clone());
522 int IoCtx::exec(const std::string
& oid
, const char *cls
, const char *method
,
523 bufferlist
& inbl
, bufferlist
& outbl
) {
524 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
525 return ctx
->execute_operation(
526 oid
, boost::bind(&TestIoCtxImpl::exec
, _1
, _2
, get_class_handler(), cls
,
527 method
, inbl
, &outbl
, ctx
->get_snap_context()));
530 void IoCtx::from_rados_ioctx_t(rados_ioctx_t p
, IoCtx
&io
) {
531 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(p
);
535 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(ctx
);
538 uint64_t IoCtx::get_instance_id() const {
539 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
540 return ctx
->get_instance_id();
543 int64_t IoCtx::get_id() {
544 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
545 return ctx
->get_id();
548 uint64_t IoCtx::get_last_version() {
549 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
550 return ctx
->get_last_version();
553 std::string
IoCtx::get_pool_name() {
554 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
555 return ctx
->get_pool_name();
558 int IoCtx::list_snaps(const std::string
& o
, snap_set_t
*out_snaps
) {
559 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
560 return ctx
->execute_operation(
561 o
, boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
, out_snaps
));
564 int IoCtx::list_watchers(const std::string
& o
,
565 std::list
<obj_watch_t
> *out_watchers
) {
566 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
567 return ctx
->execute_operation(
568 o
, boost::bind(&TestIoCtxImpl::list_watchers
, _1
, _2
, out_watchers
));
571 int IoCtx::notify(const std::string
& o
, uint64_t ver
, bufferlist
& bl
) {
572 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
573 return ctx
->notify(o
, bl
, 0, NULL
);
576 int IoCtx::notify2(const std::string
& o
, bufferlist
& bl
,
577 uint64_t timeout_ms
, bufferlist
*pbl
) {
578 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
579 return ctx
->notify(o
, bl
, timeout_ms
, pbl
);
582 void IoCtx::notify_ack(const std::string
& o
, uint64_t notify_id
,
583 uint64_t handle
, bufferlist
& bl
) {
584 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
585 ctx
->notify_ack(o
, notify_id
, handle
, bl
);
588 int IoCtx::omap_get_vals(const std::string
& oid
,
589 const std::string
& start_after
,
591 std::map
<std::string
, bufferlist
> *out_vals
) {
592 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
593 return ctx
->execute_operation(
594 oid
, boost::bind(&TestIoCtxImpl::omap_get_vals
, _1
, _2
, start_after
, "",
595 max_return
, out_vals
));
598 int IoCtx::operate(const std::string
& oid
, ObjectWriteOperation
*op
) {
599 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
600 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
601 return ctx
->operate(oid
, *ops
);
604 int IoCtx::operate(const std::string
& oid
, ObjectReadOperation
*op
,
606 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
607 TestObjectOperationImpl
*ops
= reinterpret_cast<TestObjectOperationImpl
*>(op
->impl
);
608 return ctx
->operate_read(oid
, *ops
, pbl
);
611 int IoCtx::read(const std::string
& oid
, bufferlist
& bl
, size_t len
,
613 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
614 return ctx
->execute_operation(
615 oid
, boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, &bl
));
618 int IoCtx::remove(const std::string
& oid
) {
619 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
620 return ctx
->execute_operation(
621 oid
, boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, ctx
->get_snap_context()));
624 int IoCtx::selfmanaged_snap_create(uint64_t *snapid
) {
625 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
626 return ctx
->selfmanaged_snap_create(snapid
);
629 void IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid
, AioCompletion
* c
) {
630 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
631 return ctx
->aio_selfmanaged_snap_create(snapid
, c
->pc
);
634 int IoCtx::selfmanaged_snap_remove(uint64_t snapid
) {
635 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
636 return ctx
->selfmanaged_snap_remove(snapid
);
639 void IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid
, AioCompletion
* c
) {
640 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
641 ctx
->aio_selfmanaged_snap_remove(snapid
, c
->pc
);
644 int IoCtx::selfmanaged_snap_rollback(const std::string
& oid
,
646 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
647 return ctx
->selfmanaged_snap_rollback(oid
, snapid
);
650 int IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq
,
651 std::vector
<snap_t
>& snaps
) {
652 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
653 return ctx
->selfmanaged_snap_set_write_ctx(seq
, snaps
);
656 void IoCtx::snap_set_read(snap_t seq
) {
657 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
658 ctx
->set_snap_read(seq
);
661 int IoCtx::sparse_read(const std::string
& oid
, std::map
<uint64_t,uint64_t>& m
,
662 bufferlist
& bl
, size_t len
, uint64_t off
) {
663 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
664 return ctx
->execute_operation(
665 oid
, boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, &m
, &bl
));
668 int IoCtx::stat(const std::string
& oid
, uint64_t *psize
, time_t *pmtime
) {
669 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
670 return ctx
->execute_operation(
671 oid
, boost::bind(&TestIoCtxImpl::stat
, _1
, _2
, psize
, pmtime
));
674 int IoCtx::tmap_update(const std::string
& oid
, bufferlist
& cmdbl
) {
675 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
676 return ctx
->execute_operation(
677 oid
, boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
, cmdbl
));
680 int IoCtx::trunc(const std::string
& oid
, uint64_t off
) {
681 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
682 return ctx
->execute_operation(
683 oid
, boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
,
684 ctx
->get_snap_context()));
687 int IoCtx::unwatch2(uint64_t handle
) {
688 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
689 return ctx
->unwatch(handle
);
692 int IoCtx::unwatch(const std::string
& o
, uint64_t handle
) {
693 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
694 return ctx
->unwatch(handle
);
697 int IoCtx::watch(const std::string
& o
, uint64_t ver
, uint64_t *handle
,
698 librados::WatchCtx
*wctx
) {
699 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
700 return ctx
->watch(o
, handle
, wctx
, NULL
);
703 int IoCtx::watch2(const std::string
& o
, uint64_t *handle
,
704 librados::WatchCtx2
*wctx
) {
705 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
706 return ctx
->watch(o
, handle
, NULL
, wctx
);
709 int IoCtx::write(const std::string
& oid
, bufferlist
& bl
, size_t len
,
711 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
712 return ctx
->execute_operation(
713 oid
, boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, len
, off
,
714 ctx
->get_snap_context()));
717 int IoCtx::write_full(const std::string
& oid
, bufferlist
& bl
) {
718 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
719 return ctx
->execute_operation(
720 oid
, boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
,
721 ctx
->get_snap_context()));
724 int IoCtx::writesame(const std::string
& oid
, bufferlist
& bl
, size_t len
,
726 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
727 return ctx
->execute_operation(
728 oid
, boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
, off
,
729 ctx
->get_snap_context()));
732 int IoCtx::cmpext(const std::string
& oid
, uint64_t off
, bufferlist
& cmp_bl
) {
733 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
734 return ctx
->execute_operation(
735 oid
, boost::bind(&TestIoCtxImpl::cmpext
, _1
, _2
, off
, cmp_bl
));
738 int IoCtx::application_enable(const std::string
& app_name
, bool force
) {
742 int IoCtx::application_enable_async(const std::string
& app_name
,
743 bool force
, PoolAsyncCompletion
*c
) {
747 int IoCtx::application_list(std::set
<std::string
> *app_names
) {
751 int IoCtx::application_metadata_get(const std::string
& app_name
,
752 const std::string
&key
,
753 std::string
*value
) {
757 int IoCtx::application_metadata_set(const std::string
& app_name
,
758 const std::string
&key
,
759 const std::string
& value
) {
763 int IoCtx::application_metadata_remove(const std::string
& app_name
,
764 const std::string
&key
) {
768 int IoCtx::application_metadata_list(const std::string
& app_name
,
769 std::map
<std::string
, std::string
> *values
) {
773 void IoCtx::set_namespace(const std::string
& nspace
) {
774 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
775 ctx
->set_namespace(nspace
);
778 std::string
IoCtx::get_namespace() const {
779 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(io_ctx_impl
);
780 return ctx
->get_namespace();
783 static int save_operation_result(int result
, int *pval
) {
790 ObjectOperation::ObjectOperation() {
791 TestObjectOperationImpl
*o
= new TestObjectOperationImpl();
793 impl
= reinterpret_cast<ObjectOperationImpl
*>(o
);
796 ObjectOperation::~ObjectOperation() {
797 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
804 void ObjectOperation::assert_exists() {
805 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
806 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::assert_exists
, _1
, _2
));
809 void ObjectOperation::exec(const char *cls
, const char *method
,
811 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
812 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::exec
, _1
, _2
,
813 get_class_handler(), cls
, method
, inbl
, _3
, _4
));
816 void ObjectOperation::set_op_flags2(int flags
) {
819 size_t ObjectOperation::size() {
820 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
821 return o
->ops
.size();
824 void ObjectOperation::cmpext(uint64_t off
, const bufferlist
& cmp_bl
,
826 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
827 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::cmpext
, _1
, _2
, off
, cmp_bl
);
829 op
= boost::bind(save_operation_result
,
830 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
832 o
->ops
.push_back(op
);
835 void ObjectReadOperation::list_snaps(snap_set_t
*out_snaps
, int *prval
) {
836 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
838 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_snaps
, _1
, _2
,
841 op
= boost::bind(save_operation_result
,
842 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
844 o
->ops
.push_back(op
);
847 void ObjectReadOperation::list_watchers(std::list
<obj_watch_t
> *out_watchers
,
849 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
851 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::list_watchers
, _1
,
854 op
= boost::bind(save_operation_result
,
855 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
857 o
->ops
.push_back(op
);
860 void ObjectReadOperation::read(size_t off
, uint64_t len
, bufferlist
*pbl
,
862 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
864 ObjectOperationTestImpl op
;
866 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, pbl
);
868 op
= boost::bind(&TestIoCtxImpl::read
, _1
, _2
, len
, off
, _3
);
872 op
= boost::bind(save_operation_result
,
873 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
875 o
->ops
.push_back(op
);
878 void ObjectReadOperation::sparse_read(uint64_t off
, uint64_t len
,
879 std::map
<uint64_t,uint64_t> *m
,
880 bufferlist
*pbl
, int *prval
) {
881 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
883 ObjectOperationTestImpl op
;
885 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, pbl
);
887 op
= boost::bind(&TestIoCtxImpl::sparse_read
, _1
, _2
, off
, len
, m
, _3
);
891 op
= boost::bind(save_operation_result
,
892 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
894 o
->ops
.push_back(op
);
897 void ObjectReadOperation::stat(uint64_t *psize
, time_t *pmtime
, int *prval
) {
898 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
900 ObjectOperationTestImpl op
= boost::bind(&TestIoCtxImpl::stat
, _1
, _2
,
904 op
= boost::bind(save_operation_result
,
905 boost::bind(op
, _1
, _2
, _3
, _4
), prval
);
907 o
->ops
.push_back(op
);
910 void ObjectWriteOperation::append(const bufferlist
&bl
) {
911 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
912 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::append
, _1
, _2
, bl
, _4
));
915 void ObjectWriteOperation::create(bool exclusive
) {
916 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
917 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::create
, _1
, _2
, exclusive
));
920 void ObjectWriteOperation::omap_set(const std::map
<std::string
, bufferlist
> &map
) {
921 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
922 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::omap_set
, _1
, _2
, boost::ref(map
)));
925 void ObjectWriteOperation::remove() {
926 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
927 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::remove
, _1
, _2
, _4
));
930 void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid
) {
931 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
932 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::selfmanaged_snap_rollback
,
936 void ObjectWriteOperation::set_alloc_hint(uint64_t expected_object_size
,
937 uint64_t expected_write_size
) {
938 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
939 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::set_alloc_hint
, _1
, _2
,
940 expected_object_size
, expected_write_size
, _4
));
944 void ObjectWriteOperation::tmap_update(const bufferlist
& cmdbl
) {
945 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
946 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
,
950 void ObjectWriteOperation::truncate(uint64_t off
) {
951 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
952 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
, _4
));
955 void ObjectWriteOperation::write(uint64_t off
, const bufferlist
& bl
) {
956 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
957 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, bl
.length(),
961 void ObjectWriteOperation::write_full(const bufferlist
& bl
) {
962 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
963 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
, _4
));
966 void ObjectWriteOperation::writesame(uint64_t off
, uint64_t len
, const bufferlist
& bl
) {
967 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
968 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
,
972 void ObjectWriteOperation::zero(uint64_t off
, uint64_t len
) {
973 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
974 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::zero
, _1
, _2
, off
, len
, _4
));
977 Rados::Rados() : client(NULL
) {
980 Rados::Rados(IoCtx
& ioctx
) {
981 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(ioctx
.io_ctx_impl
);
982 TestRadosClient
*impl
= ctx
->get_rados_client();
985 client
= reinterpret_cast<RadosClient
*>(impl
);
986 ceph_assert(client
!= NULL
);
993 AioCompletion
*Rados::aio_create_completion(void *cb_arg
,
994 callback_t cb_complete
,
995 callback_t cb_safe
) {
996 AioCompletionImpl
*c
;
997 int r
= rados_aio_create_completion(cb_arg
, cb_complete
, cb_safe
,
998 reinterpret_cast<void**>(&c
));
1000 return new AioCompletion(c
);
1003 int Rados::aio_watch_flush(AioCompletion
* c
) {
1004 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1005 return impl
->aio_watch_flush(c
->pc
);
1008 int Rados::blacklist_add(const std::string
& client_address
,
1009 uint32_t expire_seconds
) {
1010 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1011 return impl
->blacklist_add(client_address
, expire_seconds
);
1014 config_t
Rados::cct() {
1015 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1016 return reinterpret_cast<config_t
>(impl
->cct());
1019 int Rados::cluster_fsid(std::string
* fsid
) {
1020 *fsid
= "00000000-1111-2222-3333-444444444444";
1024 int Rados::conf_set(const char *option
, const char *value
) {
1025 return rados_conf_set(reinterpret_cast<rados_t
>(client
), option
, value
);
1028 int Rados::conf_get(const char *option
, std::string
&val
) {
1029 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1030 CephContext
*cct
= impl
->cct();
1033 int ret
= cct
->_conf
.get_val(option
, &str
, -1);
1044 int Rados::conf_parse_env(const char *env
) const {
1045 return rados_conf_parse_env(reinterpret_cast<rados_t
>(client
), env
);
1048 int Rados::conf_read_file(const char * const path
) const {
1049 return rados_conf_read_file(reinterpret_cast<rados_t
>(client
), path
);
1052 int Rados::connect() {
1053 return rados_connect(reinterpret_cast<rados_t
>(client
));
1056 uint64_t Rados::get_instance_id() {
1057 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1058 return impl
->get_instance_id();
1061 int Rados::get_min_compatible_osd(int8_t* require_osd_release
) {
1062 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1063 return impl
->get_min_compatible_osd(require_osd_release
);
1066 int Rados::get_min_compatible_client(int8_t* min_compat_client
,
1067 int8_t* require_min_compat_client
) {
1068 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1069 return impl
->get_min_compatible_client(min_compat_client
,
1070 require_min_compat_client
);
1073 int Rados::init(const char * const id
) {
1074 return rados_create(reinterpret_cast<rados_t
*>(&client
), id
);
1077 int Rados::init_with_context(config_t cct_
) {
1078 return rados_create_with_context(reinterpret_cast<rados_t
*>(&client
), cct_
);
1081 int Rados::ioctx_create(const char *name
, IoCtx
&io
) {
1083 int ret
= rados_ioctx_create(reinterpret_cast<rados_t
>(client
), name
, &p
);
1089 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
1093 int Rados::ioctx_create2(int64_t pool_id
, IoCtx
&io
)
1096 int ret
= rados_ioctx_create2(reinterpret_cast<rados_t
>(client
), pool_id
, &p
);
1102 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
1106 int Rados::mon_command(std::string cmd
, const bufferlist
& inbl
,
1107 bufferlist
*outbl
, std::string
*outs
) {
1108 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1110 std::vector
<std::string
> cmds
;
1111 cmds
.push_back(cmd
);
1112 return impl
->mon_command(cmds
, inbl
, outbl
, outs
);
1115 int Rados::service_daemon_register(const std::string
& service
,
1116 const std::string
& name
,
1117 const std::map
<std::string
,std::string
>& metadata
) {
1118 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1119 return impl
->service_daemon_register(service
, name
, metadata
);
1122 int Rados::service_daemon_update_status(std::map
<std::string
,std::string
>&& status
) {
1123 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1124 return impl
->service_daemon_update_status(std::move(status
));
1127 int Rados::pool_create(const char *name
) {
1128 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1129 return impl
->pool_create(name
);
1132 int Rados::pool_delete(const char *name
) {
1133 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1134 return impl
->pool_delete(name
);
1137 int Rados::pool_get_base_tier(int64_t pool
, int64_t* base_tier
) {
1138 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1139 return impl
->pool_get_base_tier(pool
, base_tier
);
1142 int Rados::pool_list(std::list
<std::string
>& v
) {
1143 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1144 std::list
<std::pair
<int64_t, std::string
> > pools
;
1145 int r
= impl
->pool_list(pools
);
1151 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
= pools
.begin();
1152 it
!= pools
.end(); ++it
) {
1153 v
.push_back(it
->second
);
1158 int Rados::pool_list2(std::list
<std::pair
<int64_t, std::string
> >& v
)
1160 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1161 return impl
->pool_list(v
);
1164 int64_t Rados::pool_lookup(const char *name
) {
1165 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1166 return impl
->pool_lookup(name
);
1169 int Rados::pool_reverse_lookup(int64_t id
, std::string
*name
) {
1170 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1171 return impl
->pool_reverse_lookup(id
, name
);
1174 void Rados::shutdown() {
1175 if (client
== NULL
) {
1178 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1183 void Rados::test_blacklist_self(bool set
) {
1186 int Rados::wait_for_latest_osdmap() {
1187 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1188 return impl
->wait_for_latest_osdmap();
1191 int Rados::watch_flush() {
1192 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1193 return impl
->watch_flush();
1196 WatchCtx::~WatchCtx() {
1199 WatchCtx2::~WatchCtx2() {
1202 } // namespace librados
1204 int cls_cxx_create(cls_method_context_t hctx
, bool exclusive
) {
1205 librados::TestClassHandler::MethodContext
*ctx
=
1206 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1207 return ctx
->io_ctx_impl
->create(ctx
->oid
, exclusive
);
1210 int cls_cxx_remove(cls_method_context_t hctx
) {
1211 librados::TestClassHandler::MethodContext
*ctx
=
1212 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1213 return ctx
->io_ctx_impl
->remove(ctx
->oid
, ctx
->io_ctx_impl
->get_snap_context());
1216 int cls_get_request_origin(cls_method_context_t hctx
, entity_inst_t
*origin
) {
1217 librados::TestClassHandler::MethodContext
*ctx
=
1218 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1220 librados::TestRadosClient
*rados_client
=
1221 ctx
->io_ctx_impl
->get_rados_client();
1223 struct sockaddr_in sin
;
1224 memset(&sin
, 0, sizeof(sin
));
1225 sin
.sin_family
= AF_INET
;
1227 inet_pton(AF_INET
, "127.0.0.1", &sin
.sin_addr
);
1229 entity_addr_t
entity_addr(entity_addr_t::TYPE_DEFAULT
,
1230 rados_client
->get_nonce());
1231 entity_addr
.in4_addr() = sin
;
1233 *origin
= entity_inst_t(
1234 entity_name_t::CLIENT(rados_client
->get_instance_id()),
1239 int cls_cxx_getxattr(cls_method_context_t hctx
, const char *name
,
1240 bufferlist
*outbl
) {
1241 std::map
<string
, bufferlist
> attrs
;
1242 int r
= cls_cxx_getxattrs(hctx
, &attrs
);
1247 std::map
<string
, bufferlist
>::iterator it
= attrs
.find(name
);
1248 if (it
== attrs
.end()) {
1251 *outbl
= it
->second
;
1255 int cls_cxx_getxattrs(cls_method_context_t hctx
, std::map
<string
, bufferlist
> *attrset
) {
1256 librados::TestClassHandler::MethodContext
*ctx
=
1257 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1258 return ctx
->io_ctx_impl
->xattr_get(ctx
->oid
, attrset
);
1261 int cls_cxx_map_get_keys(cls_method_context_t hctx
, const string
&start_obj
,
1262 uint64_t max_to_get
, std::set
<string
> *keys
, bool *more
) {
1263 librados::TestClassHandler::MethodContext
*ctx
=
1264 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1267 std::map
<string
, bufferlist
> vals
;
1268 int r
= ctx
->io_ctx_impl
->omap_get_vals2(ctx
->oid
, start_obj
, "", max_to_get
,
1274 for (std::map
<string
, bufferlist
>::iterator it
= vals
.begin();
1275 it
!= vals
.end(); ++it
) {
1276 keys
->insert(it
->first
);
1278 return keys
->size();
1281 int cls_cxx_map_get_val(cls_method_context_t hctx
, const string
&key
,
1282 bufferlist
*outbl
) {
1283 librados::TestClassHandler::MethodContext
*ctx
=
1284 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1286 std::map
<string
, bufferlist
> vals
;
1287 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, "", key
, 1024, &vals
);
1292 std::map
<string
, bufferlist
>::iterator it
= vals
.find(key
);
1293 if (it
== vals
.end()) {
1297 *outbl
= it
->second
;
1301 int cls_cxx_map_get_vals(cls_method_context_t hctx
, const string
&start_obj
,
1302 const string
&filter_prefix
, uint64_t max_to_get
,
1303 std::map
<string
, bufferlist
> *vals
, bool *more
) {
1304 librados::TestClassHandler::MethodContext
*ctx
=
1305 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1306 int r
= ctx
->io_ctx_impl
->omap_get_vals2(ctx
->oid
, start_obj
, filter_prefix
,
1307 max_to_get
, vals
, more
);
1311 return vals
->size();
1314 int cls_cxx_map_remove_key(cls_method_context_t hctx
, const string
&key
) {
1315 std::set
<std::string
> keys
;
1318 librados::TestClassHandler::MethodContext
*ctx
=
1319 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1320 return ctx
->io_ctx_impl
->omap_rm_keys(ctx
->oid
, keys
);
1323 int cls_cxx_map_set_val(cls_method_context_t hctx
, const string
&key
,
1325 std::map
<std::string
, bufferlist
> m
;
1327 return cls_cxx_map_set_vals(hctx
, &m
);
1330 int cls_cxx_map_set_vals(cls_method_context_t hctx
,
1331 const std::map
<string
, bufferlist
> *map
) {
1332 librados::TestClassHandler::MethodContext
*ctx
=
1333 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1334 return ctx
->io_ctx_impl
->omap_set(ctx
->oid
, *map
);
1337 int cls_cxx_read(cls_method_context_t hctx
, int ofs
, int len
,
1338 bufferlist
*outbl
) {
1339 return cls_cxx_read2(hctx
, ofs
, len
, outbl
, 0);
1342 int cls_cxx_read2(cls_method_context_t hctx
, int ofs
, int len
,
1343 bufferlist
*outbl
, uint32_t op_flags
) {
1344 librados::TestClassHandler::MethodContext
*ctx
=
1345 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1346 return ctx
->io_ctx_impl
->read(ctx
->oid
, len
, ofs
, outbl
);
1349 int cls_cxx_setxattr(cls_method_context_t hctx
, const char *name
,
1351 librados::TestClassHandler::MethodContext
*ctx
=
1352 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1353 return ctx
->io_ctx_impl
->xattr_set(ctx
->oid
, name
, *inbl
);
1356 int cls_cxx_stat(cls_method_context_t hctx
, uint64_t *size
, time_t *mtime
) {
1357 librados::TestClassHandler::MethodContext
*ctx
=
1358 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1359 return ctx
->io_ctx_impl
->stat(ctx
->oid
, size
, mtime
);
1362 int cls_cxx_write(cls_method_context_t hctx
, int ofs
, int len
,
1364 return cls_cxx_write2(hctx
, ofs
, len
, inbl
, 0);
1367 int cls_cxx_write2(cls_method_context_t hctx
, int ofs
, int len
,
1368 bufferlist
*inbl
, uint32_t op_flags
) {
1369 librados::TestClassHandler::MethodContext
*ctx
=
1370 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1371 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1374 int cls_cxx_write_full(cls_method_context_t hctx
, bufferlist
*inbl
) {
1375 librados::TestClassHandler::MethodContext
*ctx
=
1376 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1377 return ctx
->io_ctx_impl
->write_full(ctx
->oid
, *inbl
, ctx
->snapc
);
1380 int cls_cxx_replace(cls_method_context_t hctx
, int ofs
, int len
,
1382 librados::TestClassHandler::MethodContext
*ctx
=
1383 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1384 int r
= ctx
->io_ctx_impl
->truncate(ctx
->oid
, 0, ctx
->snapc
);
1388 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1391 int cls_cxx_list_watchers(cls_method_context_t hctx
,
1392 obj_list_watch_response_t
*watchers
) {
1393 librados::TestClassHandler::MethodContext
*ctx
=
1394 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1396 std::list
<obj_watch_t
> obj_watchers
;
1397 int r
= ctx
->io_ctx_impl
->list_watchers(ctx
->oid
, &obj_watchers
);
1402 for (auto &w
: obj_watchers
) {
1403 watch_item_t watcher
;
1404 watcher
.name
= entity_name_t::CLIENT(w
.watcher_id
);
1405 watcher
.cookie
= w
.cookie
;
1406 watcher
.timeout_seconds
= w
.timeout_seconds
;
1407 watcher
.addr
.parse(w
.addr
, 0);
1408 watchers
->entries
.push_back(watcher
);
1414 uint64_t cls_get_features(cls_method_context_t hctx
) {
1415 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1418 uint64_t cls_get_client_features(cls_method_context_t hctx
) {
1419 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1422 int cls_get_snapset_seq(cls_method_context_t hctx
, uint64_t *snap_seq
) {
1423 librados::TestClassHandler::MethodContext
*ctx
=
1424 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1425 librados::snap_set_t snapset
;
1426 int r
= ctx
->io_ctx_impl
->list_snaps(ctx
->oid
, &snapset
);
1431 *snap_seq
= snapset
.seq
;
1435 int cls_log(int level
, const char *format
, ...) {
1440 va_start(ap
, format
);
1441 int n
= vsnprintf(buf
, size
, format
, ap
);
1443 if ((n
> -1 && n
< size
) || size
> 8196) {
1444 dout(ceph::dout::need_dynamic(level
)) << buf
<< dendl
;
1452 int cls_register(const char *name
, cls_handle_t
*handle
) {
1453 librados::TestClassHandler
*cls
= get_class_handler();
1454 return cls
->create(name
, handle
);
1457 int cls_register_cxx_method(cls_handle_t hclass
, const char *method
,
1459 cls_method_cxx_call_t class_call
,
1460 cls_method_handle_t
*handle
) {
1461 librados::TestClassHandler
*cls
= get_class_handler();
1462 return cls
->create_method(hclass
, method
, class_call
, handle
);
1465 int cls_register_cxx_filter(cls_handle_t hclass
,
1466 const std::string
&filter_name
,
1467 cls_cxx_filter_factory_t fn
,
1468 cls_filter_handle_t
*)
1470 librados::TestClassHandler
*cls
= get_class_handler();
1471 return cls
->create_filter(hclass
, filter_name
, fn
);
1474 int8_t cls_get_required_osd_release(cls_handle_t hclass
) {
1475 return CEPH_FEATURE_SERVER_NAUTILUS
;