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
, 0,
944 void ObjectWriteOperation::set_alloc_hint2(uint64_t expected_object_size
,
945 uint64_t expected_write_size
,
947 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
948 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::set_alloc_hint
, _1
, _2
,
949 expected_object_size
, expected_write_size
, flags
,
953 void ObjectWriteOperation::tmap_update(const bufferlist
& cmdbl
) {
954 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
955 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::tmap_update
, _1
, _2
,
959 void ObjectWriteOperation::truncate(uint64_t off
) {
960 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
961 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::truncate
, _1
, _2
, off
, _4
));
964 void ObjectWriteOperation::write(uint64_t off
, const bufferlist
& bl
) {
965 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
966 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write
, _1
, _2
, bl
, bl
.length(),
970 void ObjectWriteOperation::write_full(const bufferlist
& bl
) {
971 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
972 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::write_full
, _1
, _2
, bl
, _4
));
975 void ObjectWriteOperation::writesame(uint64_t off
, uint64_t len
, const bufferlist
& bl
) {
976 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
977 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::writesame
, _1
, _2
, bl
, len
,
981 void ObjectWriteOperation::zero(uint64_t off
, uint64_t len
) {
982 TestObjectOperationImpl
*o
= reinterpret_cast<TestObjectOperationImpl
*>(impl
);
983 o
->ops
.push_back(boost::bind(&TestIoCtxImpl::zero
, _1
, _2
, off
, len
, _4
));
986 Rados::Rados() : client(NULL
) {
989 Rados::Rados(IoCtx
& ioctx
) {
990 TestIoCtxImpl
*ctx
= reinterpret_cast<TestIoCtxImpl
*>(ioctx
.io_ctx_impl
);
991 TestRadosClient
*impl
= ctx
->get_rados_client();
994 client
= reinterpret_cast<RadosClient
*>(impl
);
995 ceph_assert(client
!= NULL
);
1002 void Rados::from_rados_t(rados_t p
, Rados
&rados
) {
1003 if (rados
.client
!= nullptr) {
1004 reinterpret_cast<TestRadosClient
*>(rados
.client
)->put();
1005 rados
.client
= nullptr;
1008 auto impl
= reinterpret_cast<TestRadosClient
*>(p
);
1011 rados
.client
= reinterpret_cast<RadosClient
*>(impl
);
1015 AioCompletion
*Rados::aio_create_completion(void *cb_arg
,
1016 callback_t cb_complete
,
1017 callback_t cb_safe
) {
1018 AioCompletionImpl
*c
;
1019 int r
= rados_aio_create_completion(cb_arg
, cb_complete
, cb_safe
,
1020 reinterpret_cast<void**>(&c
));
1021 ceph_assert(r
== 0);
1022 return new AioCompletion(c
);
1025 int Rados::aio_watch_flush(AioCompletion
* c
) {
1026 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1027 return impl
->aio_watch_flush(c
->pc
);
1030 int Rados::blacklist_add(const std::string
& client_address
,
1031 uint32_t expire_seconds
) {
1032 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1033 return impl
->blacklist_add(client_address
, expire_seconds
);
1036 config_t
Rados::cct() {
1037 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1038 return reinterpret_cast<config_t
>(impl
->cct());
1041 int Rados::cluster_fsid(std::string
* fsid
) {
1042 *fsid
= "00000000-1111-2222-3333-444444444444";
1046 int Rados::conf_set(const char *option
, const char *value
) {
1047 return rados_conf_set(reinterpret_cast<rados_t
>(client
), option
, value
);
1050 int Rados::conf_get(const char *option
, std::string
&val
) {
1051 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1052 CephContext
*cct
= impl
->cct();
1055 int ret
= cct
->_conf
.get_val(option
, &str
, -1);
1066 int Rados::conf_parse_env(const char *env
) const {
1067 return rados_conf_parse_env(reinterpret_cast<rados_t
>(client
), env
);
1070 int Rados::conf_read_file(const char * const path
) const {
1071 return rados_conf_read_file(reinterpret_cast<rados_t
>(client
), path
);
1074 int Rados::connect() {
1075 return rados_connect(reinterpret_cast<rados_t
>(client
));
1078 uint64_t Rados::get_instance_id() {
1079 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1080 return impl
->get_instance_id();
1083 int Rados::get_min_compatible_osd(int8_t* require_osd_release
) {
1084 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1085 return impl
->get_min_compatible_osd(require_osd_release
);
1088 int Rados::get_min_compatible_client(int8_t* min_compat_client
,
1089 int8_t* require_min_compat_client
) {
1090 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1091 return impl
->get_min_compatible_client(min_compat_client
,
1092 require_min_compat_client
);
1095 int Rados::init(const char * const id
) {
1096 return rados_create(reinterpret_cast<rados_t
*>(&client
), id
);
1099 int Rados::init_with_context(config_t cct_
) {
1100 return rados_create_with_context(reinterpret_cast<rados_t
*>(&client
), cct_
);
1103 int Rados::ioctx_create(const char *name
, IoCtx
&io
) {
1105 int ret
= rados_ioctx_create(reinterpret_cast<rados_t
>(client
), name
, &p
);
1111 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
1115 int Rados::ioctx_create2(int64_t pool_id
, IoCtx
&io
)
1118 int ret
= rados_ioctx_create2(reinterpret_cast<rados_t
>(client
), pool_id
, &p
);
1124 io
.io_ctx_impl
= reinterpret_cast<IoCtxImpl
*>(p
);
1128 int Rados::mon_command(std::string cmd
, const bufferlist
& inbl
,
1129 bufferlist
*outbl
, std::string
*outs
) {
1130 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1132 std::vector
<std::string
> cmds
;
1133 cmds
.push_back(cmd
);
1134 return impl
->mon_command(cmds
, inbl
, outbl
, outs
);
1137 int Rados::service_daemon_register(const std::string
& service
,
1138 const std::string
& name
,
1139 const std::map
<std::string
,std::string
>& metadata
) {
1140 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1141 return impl
->service_daemon_register(service
, name
, metadata
);
1144 int Rados::service_daemon_update_status(std::map
<std::string
,std::string
>&& status
) {
1145 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1146 return impl
->service_daemon_update_status(std::move(status
));
1149 int Rados::pool_create(const char *name
) {
1150 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1151 return impl
->pool_create(name
);
1154 int Rados::pool_delete(const char *name
) {
1155 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1156 return impl
->pool_delete(name
);
1159 int Rados::pool_get_base_tier(int64_t pool
, int64_t* base_tier
) {
1160 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1161 return impl
->pool_get_base_tier(pool
, base_tier
);
1164 int Rados::pool_list(std::list
<std::string
>& v
) {
1165 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1166 std::list
<std::pair
<int64_t, std::string
> > pools
;
1167 int r
= impl
->pool_list(pools
);
1173 for (std::list
<std::pair
<int64_t, std::string
> >::iterator it
= pools
.begin();
1174 it
!= pools
.end(); ++it
) {
1175 v
.push_back(it
->second
);
1180 int Rados::pool_list2(std::list
<std::pair
<int64_t, std::string
> >& v
)
1182 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1183 return impl
->pool_list(v
);
1186 int64_t Rados::pool_lookup(const char *name
) {
1187 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1188 return impl
->pool_lookup(name
);
1191 int Rados::pool_reverse_lookup(int64_t id
, std::string
*name
) {
1192 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1193 return impl
->pool_reverse_lookup(id
, name
);
1196 void Rados::shutdown() {
1197 if (client
== NULL
) {
1200 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1205 void Rados::test_blacklist_self(bool set
) {
1208 int Rados::wait_for_latest_osdmap() {
1209 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1210 return impl
->wait_for_latest_osdmap();
1213 int Rados::watch_flush() {
1214 TestRadosClient
*impl
= reinterpret_cast<TestRadosClient
*>(client
);
1215 return impl
->watch_flush();
1218 WatchCtx::~WatchCtx() {
1221 WatchCtx2::~WatchCtx2() {
1224 } // namespace librados
1226 int cls_cxx_create(cls_method_context_t hctx
, bool exclusive
) {
1227 librados::TestClassHandler::MethodContext
*ctx
=
1228 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1229 return ctx
->io_ctx_impl
->create(ctx
->oid
, exclusive
);
1232 int cls_cxx_remove(cls_method_context_t hctx
) {
1233 librados::TestClassHandler::MethodContext
*ctx
=
1234 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1235 return ctx
->io_ctx_impl
->remove(ctx
->oid
, ctx
->io_ctx_impl
->get_snap_context());
1238 int cls_get_request_origin(cls_method_context_t hctx
, entity_inst_t
*origin
) {
1239 librados::TestClassHandler::MethodContext
*ctx
=
1240 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1242 librados::TestRadosClient
*rados_client
=
1243 ctx
->io_ctx_impl
->get_rados_client();
1245 struct sockaddr_in sin
;
1246 memset(&sin
, 0, sizeof(sin
));
1247 sin
.sin_family
= AF_INET
;
1249 inet_pton(AF_INET
, "127.0.0.1", &sin
.sin_addr
);
1251 entity_addr_t
entity_addr(entity_addr_t::TYPE_DEFAULT
,
1252 rados_client
->get_nonce());
1253 entity_addr
.in4_addr() = sin
;
1255 *origin
= entity_inst_t(
1256 entity_name_t::CLIENT(rados_client
->get_instance_id()),
1261 int cls_cxx_getxattr(cls_method_context_t hctx
, const char *name
,
1262 bufferlist
*outbl
) {
1263 std::map
<string
, bufferlist
> attrs
;
1264 int r
= cls_cxx_getxattrs(hctx
, &attrs
);
1269 std::map
<string
, bufferlist
>::iterator it
= attrs
.find(name
);
1270 if (it
== attrs
.end()) {
1273 *outbl
= it
->second
;
1277 int cls_cxx_getxattrs(cls_method_context_t hctx
, std::map
<string
, bufferlist
> *attrset
) {
1278 librados::TestClassHandler::MethodContext
*ctx
=
1279 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1280 return ctx
->io_ctx_impl
->xattr_get(ctx
->oid
, attrset
);
1283 int cls_cxx_map_get_keys(cls_method_context_t hctx
, const string
&start_obj
,
1284 uint64_t max_to_get
, std::set
<string
> *keys
, bool *more
) {
1285 librados::TestClassHandler::MethodContext
*ctx
=
1286 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1289 std::map
<string
, bufferlist
> vals
;
1290 int r
= ctx
->io_ctx_impl
->omap_get_vals2(ctx
->oid
, start_obj
, "", max_to_get
,
1296 for (std::map
<string
, bufferlist
>::iterator it
= vals
.begin();
1297 it
!= vals
.end(); ++it
) {
1298 keys
->insert(it
->first
);
1300 return keys
->size();
1303 int cls_cxx_map_get_val(cls_method_context_t hctx
, const string
&key
,
1304 bufferlist
*outbl
) {
1305 librados::TestClassHandler::MethodContext
*ctx
=
1306 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1308 std::map
<string
, bufferlist
> vals
;
1309 int r
= ctx
->io_ctx_impl
->omap_get_vals(ctx
->oid
, "", key
, 1024, &vals
);
1314 std::map
<string
, bufferlist
>::iterator it
= vals
.find(key
);
1315 if (it
== vals
.end()) {
1319 *outbl
= it
->second
;
1323 int cls_cxx_map_get_vals(cls_method_context_t hctx
, const string
&start_obj
,
1324 const string
&filter_prefix
, uint64_t max_to_get
,
1325 std::map
<string
, bufferlist
> *vals
, bool *more
) {
1326 librados::TestClassHandler::MethodContext
*ctx
=
1327 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1328 int r
= ctx
->io_ctx_impl
->omap_get_vals2(ctx
->oid
, start_obj
, filter_prefix
,
1329 max_to_get
, vals
, more
);
1333 return vals
->size();
1336 int cls_cxx_map_remove_key(cls_method_context_t hctx
, const string
&key
) {
1337 std::set
<std::string
> keys
;
1340 librados::TestClassHandler::MethodContext
*ctx
=
1341 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1342 return ctx
->io_ctx_impl
->omap_rm_keys(ctx
->oid
, keys
);
1345 int cls_cxx_map_set_val(cls_method_context_t hctx
, const string
&key
,
1347 std::map
<std::string
, bufferlist
> m
;
1349 return cls_cxx_map_set_vals(hctx
, &m
);
1352 int cls_cxx_map_set_vals(cls_method_context_t hctx
,
1353 const std::map
<string
, bufferlist
> *map
) {
1354 librados::TestClassHandler::MethodContext
*ctx
=
1355 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1356 return ctx
->io_ctx_impl
->omap_set(ctx
->oid
, *map
);
1359 int cls_cxx_read(cls_method_context_t hctx
, int ofs
, int len
,
1360 bufferlist
*outbl
) {
1361 return cls_cxx_read2(hctx
, ofs
, len
, outbl
, 0);
1364 int cls_cxx_read2(cls_method_context_t hctx
, int ofs
, int len
,
1365 bufferlist
*outbl
, uint32_t op_flags
) {
1366 librados::TestClassHandler::MethodContext
*ctx
=
1367 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1368 return ctx
->io_ctx_impl
->read(ctx
->oid
, len
, ofs
, outbl
);
1371 int cls_cxx_setxattr(cls_method_context_t hctx
, const char *name
,
1373 librados::TestClassHandler::MethodContext
*ctx
=
1374 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1375 return ctx
->io_ctx_impl
->xattr_set(ctx
->oid
, name
, *inbl
);
1378 int cls_cxx_stat(cls_method_context_t hctx
, uint64_t *size
, time_t *mtime
) {
1379 librados::TestClassHandler::MethodContext
*ctx
=
1380 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1381 return ctx
->io_ctx_impl
->stat(ctx
->oid
, size
, mtime
);
1384 int cls_cxx_write(cls_method_context_t hctx
, int ofs
, int len
,
1386 return cls_cxx_write2(hctx
, ofs
, len
, inbl
, 0);
1389 int cls_cxx_write2(cls_method_context_t hctx
, int ofs
, int len
,
1390 bufferlist
*inbl
, uint32_t op_flags
) {
1391 librados::TestClassHandler::MethodContext
*ctx
=
1392 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1393 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1396 int cls_cxx_write_full(cls_method_context_t hctx
, bufferlist
*inbl
) {
1397 librados::TestClassHandler::MethodContext
*ctx
=
1398 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1399 return ctx
->io_ctx_impl
->write_full(ctx
->oid
, *inbl
, ctx
->snapc
);
1402 int cls_cxx_replace(cls_method_context_t hctx
, int ofs
, int len
,
1404 librados::TestClassHandler::MethodContext
*ctx
=
1405 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1406 int r
= ctx
->io_ctx_impl
->truncate(ctx
->oid
, 0, ctx
->snapc
);
1410 return ctx
->io_ctx_impl
->write(ctx
->oid
, *inbl
, len
, ofs
, ctx
->snapc
);
1413 int cls_cxx_list_watchers(cls_method_context_t hctx
,
1414 obj_list_watch_response_t
*watchers
) {
1415 librados::TestClassHandler::MethodContext
*ctx
=
1416 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1418 std::list
<obj_watch_t
> obj_watchers
;
1419 int r
= ctx
->io_ctx_impl
->list_watchers(ctx
->oid
, &obj_watchers
);
1424 for (auto &w
: obj_watchers
) {
1425 watch_item_t watcher
;
1426 watcher
.name
= entity_name_t::CLIENT(w
.watcher_id
);
1427 watcher
.cookie
= w
.cookie
;
1428 watcher
.timeout_seconds
= w
.timeout_seconds
;
1429 watcher
.addr
.parse(w
.addr
, 0);
1430 watchers
->entries
.push_back(watcher
);
1436 uint64_t cls_get_features(cls_method_context_t hctx
) {
1437 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1440 uint64_t cls_get_client_features(cls_method_context_t hctx
) {
1441 return CEPH_FEATURES_SUPPORTED_DEFAULT
;
1444 int cls_get_snapset_seq(cls_method_context_t hctx
, uint64_t *snap_seq
) {
1445 librados::TestClassHandler::MethodContext
*ctx
=
1446 reinterpret_cast<librados::TestClassHandler::MethodContext
*>(hctx
);
1447 librados::snap_set_t snapset
;
1448 int r
= ctx
->io_ctx_impl
->list_snaps(ctx
->oid
, &snapset
);
1453 *snap_seq
= snapset
.seq
;
1457 int cls_log(int level
, const char *format
, ...) {
1462 va_start(ap
, format
);
1463 int n
= vsnprintf(buf
, size
, format
, ap
);
1465 if ((n
> -1 && n
< size
) || size
> 8196) {
1466 dout(ceph::dout::need_dynamic(level
)) << buf
<< dendl
;
1474 int cls_register(const char *name
, cls_handle_t
*handle
) {
1475 librados::TestClassHandler
*cls
= get_class_handler();
1476 return cls
->create(name
, handle
);
1479 int cls_register_cxx_method(cls_handle_t hclass
, const char *method
,
1481 cls_method_cxx_call_t class_call
,
1482 cls_method_handle_t
*handle
) {
1483 librados::TestClassHandler
*cls
= get_class_handler();
1484 return cls
->create_method(hclass
, method
, class_call
, handle
);
1487 int cls_register_cxx_filter(cls_handle_t hclass
,
1488 const std::string
&filter_name
,
1489 cls_cxx_filter_factory_t fn
,
1490 cls_filter_handle_t
*)
1492 librados::TestClassHandler
*cls
= get_class_handler();
1493 return cls
->create_filter(hclass
, filter_name
, fn
);
1496 int8_t cls_get_required_osd_release(cls_handle_t hclass
) {
1497 return CEPH_FEATURE_SERVER_NAUTILUS
;