]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
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> | |
23 | #include <deque> | |
24 | #include <list> | |
25 | #include <vector> | |
26 | #include "include/assert.h" | |
27 | #include "include/compat.h" | |
28 | ||
29 | #define dout_context g_ceph_context | |
30 | #define dout_subsys ceph_subsys_rados | |
31 | ||
32 | namespace librados { | |
33 | ||
34 | MockTestMemIoCtxImpl &get_mock_io_ctx(IoCtx &ioctx) { | |
35 | MockTestMemIoCtxImpl **mock = | |
36 | reinterpret_cast<MockTestMemIoCtxImpl **>(&ioctx); | |
37 | return **mock; | |
38 | } | |
39 | ||
40 | } // namespace librados | |
41 | ||
42 | namespace librados_test_stub { | |
43 | ||
44 | TestClusterRef &cluster() { | |
45 | static TestClusterRef s_cluster; | |
46 | return s_cluster; | |
47 | } | |
48 | ||
49 | void set_cluster(TestClusterRef cluster_ref) { | |
50 | cluster() = cluster_ref; | |
51 | } | |
52 | ||
53 | TestClusterRef get_cluster() { | |
54 | auto &cluster_ref = cluster(); | |
55 | if (cluster_ref.get() == nullptr) { | |
56 | cluster_ref.reset(new librados::TestMemCluster()); | |
57 | } | |
58 | return cluster_ref; | |
59 | } | |
60 | ||
61 | } // namespace librados_test_stub | |
62 | ||
63 | namespace { | |
64 | ||
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(); | |
70 | } | |
71 | return s_class_handler.get(); | |
72 | } | |
73 | ||
74 | void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen) { | |
75 | if (outbuf) { | |
76 | if (outbl.length() > 0) { | |
77 | *outbuf = (char *)malloc(outbl.length()); | |
78 | memcpy(*outbuf, outbl.c_str(), outbl.length()); | |
79 | } else { | |
80 | *outbuf = NULL; | |
81 | } | |
82 | } | |
83 | if (outbuflen) { | |
84 | *outbuflen = outbl.length(); | |
85 | } | |
86 | } | |
87 | ||
88 | void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen) { | |
89 | if (outbuf) { | |
90 | if (outbl.length() > 0) { | |
91 | *outbuf = (char *)malloc(outbl.length()); | |
92 | memcpy(*outbuf, outbl.c_str(), outbl.length()); | |
93 | } else { | |
94 | *outbuf = NULL; | |
95 | } | |
96 | } | |
97 | if (outbuflen) { | |
98 | *outbuflen = outbl.length(); | |
99 | } | |
100 | } | |
101 | ||
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); | |
107 | ||
108 | auto rados_client = | |
109 | librados_test_stub::get_cluster()->create_rados_client(cct); | |
110 | cct->put(); | |
111 | return rados_client; | |
112 | } | |
113 | ||
114 | } // anonymous namespace | |
115 | ||
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) | |
120 | { | |
121 | librados::AioCompletionImpl *c = new librados::AioCompletionImpl; | |
122 | if (cb_complete) { | |
123 | c->set_complete_callback(cb_arg, cb_complete); | |
124 | } | |
125 | if (cb_safe) { | |
126 | c->set_safe_callback(cb_arg, cb_safe); | |
127 | } | |
128 | *pc = c; | |
129 | return 0; | |
130 | } | |
131 | ||
132 | extern "C" int rados_aio_get_return_value(rados_completion_t c) { | |
133 | return reinterpret_cast<librados::AioCompletionImpl*>(c)->get_return_value(); | |
134 | } | |
135 | ||
136 | extern "C" rados_config_t rados_cct(rados_t cluster) | |
137 | { | |
138 | librados::TestRadosClient *client = | |
139 | reinterpret_cast<librados::TestRadosClient*>(cluster); | |
140 | return reinterpret_cast<rados_config_t>(client->cct()); | |
141 | } | |
142 | ||
143 | extern "C" int rados_conf_set(rados_t cluster, const char *option, | |
144 | const char *value) { | |
145 | librados::TestRadosClient *impl = | |
146 | reinterpret_cast<librados::TestRadosClient*>(cluster); | |
147 | CephContext *cct = impl->cct(); | |
148 | return cct->_conf->set_val(option, value); | |
149 | } | |
150 | ||
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); | |
158 | if (ret == 0) { | |
159 | conf->apply_changes(NULL); | |
160 | } | |
161 | return ret; | |
162 | } | |
163 | ||
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); | |
169 | if (ret == 0) { | |
170 | conf->parse_env(); | |
171 | conf->apply_changes(NULL); | |
172 | conf->complain_about_parse_errors(client->cct()); | |
173 | } else if (ret == -ENOENT) { | |
174 | // ignore missing client config | |
175 | return 0; | |
176 | } | |
177 | return ret; | |
178 | } | |
179 | ||
180 | extern "C" int rados_connect(rados_t cluster) { | |
181 | librados::TestRadosClient *client = | |
182 | reinterpret_cast<librados::TestRadosClient*>(cluster); | |
183 | return client->connect(); | |
184 | } | |
185 | ||
186 | extern "C" int rados_create(rados_t *cluster, const char * const id) { | |
187 | *cluster = create_rados_client(); | |
188 | return 0; | |
189 | } | |
190 | ||
191 | extern "C" rados_config_t rados_ioctx_cct(rados_ioctx_t ioctx) | |
192 | { | |
193 | librados::TestIoCtxImpl *ctx = | |
194 | reinterpret_cast<librados::TestIoCtxImpl*>(ioctx); | |
195 | return reinterpret_cast<rados_config_t>(ctx->get_rados_client()->cct()); | |
196 | } | |
197 | ||
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); | |
202 | ||
203 | int64_t pool_id = client->pool_lookup(pool_name); | |
204 | if (pool_id < 0) { | |
205 | return static_cast<int>(pool_id); | |
206 | } | |
207 | ||
208 | *ioctx = reinterpret_cast<rados_ioctx_t>( | |
209 | client->create_ioctx(pool_id, pool_name)); | |
210 | return 0; | |
211 | } | |
212 | ||
213 | extern "C" int rados_ioctx_create2(rados_t cluster, int64_t pool_id, | |
214 | rados_ioctx_t *ioctx) | |
215 | { | |
216 | librados::TestRadosClient *client = | |
217 | reinterpret_cast<librados::TestRadosClient*>(cluster); | |
218 | ||
219 | std::list<std::pair<int64_t, std::string> > pools; | |
220 | int r = client->pool_list(pools); | |
221 | if (r < 0) { | |
222 | return r; | |
223 | } | |
224 | ||
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)); | |
230 | return 0; | |
231 | } | |
232 | } | |
233 | return -ENOENT; | |
234 | } | |
235 | ||
236 | extern "C" void rados_ioctx_destroy(rados_ioctx_t io) { | |
237 | librados::TestIoCtxImpl *ctx = | |
238 | reinterpret_cast<librados::TestIoCtxImpl*>(io); | |
239 | ctx->put(); | |
240 | } | |
241 | ||
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()); | |
246 | } | |
247 | ||
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, | |
252 | size_t *outslen) { | |
253 | librados::TestRadosClient *client = | |
254 | reinterpret_cast<librados::TestRadosClient*>(cluster); | |
255 | ||
256 | vector<string> cmdvec; | |
257 | for (size_t i = 0; i < cmdlen; i++) { | |
258 | cmdvec.push_back(cmd[i]); | |
259 | } | |
260 | ||
261 | bufferlist inbl; | |
262 | inbl.append(inbuf, inbuflen); | |
263 | ||
264 | bufferlist outbl; | |
265 | string outstring; | |
266 | int ret = client->mon_command(cmdvec, inbl, &outbl, &outstring); | |
267 | ||
268 | do_out_buffer(outbl, outbuf, outbuflen); | |
269 | do_out_buffer(outstring, outs, outslen); | |
270 | return ret; | |
271 | } | |
272 | ||
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(); | |
278 | ||
279 | std::list<librados::TestRadosClient::Object> *list = | |
280 | new std::list<librados::TestRadosClient::Object>(); | |
281 | ||
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); | |
285 | return 0; | |
286 | } | |
287 | ||
288 | extern "C" int rados_nobjects_list_next(rados_list_ctx_t ctx, | |
289 | const char **entry, | |
290 | const char **key, | |
291 | const char **nspace) { | |
292 | std::list<librados::TestRadosClient::Object> *list = | |
293 | reinterpret_cast<std::list<librados::TestRadosClient::Object> *>(ctx); | |
294 | if (!list->empty()) { | |
295 | list->pop_front(); | |
296 | } | |
297 | if (list->empty()) { | |
298 | return -ENOENT; | |
299 | } | |
300 | ||
301 | librados::TestRadosClient::Object &obj = list->front(); | |
302 | if (entry != NULL) { | |
303 | *entry = obj.oid.c_str(); | |
304 | } | |
305 | if (key != NULL) { | |
306 | *key = obj.locator.c_str(); | |
307 | } | |
308 | if (nspace != NULL) { | |
309 | *nspace = obj.nspace.c_str(); | |
310 | } | |
311 | return 0; | |
312 | } | |
313 | ||
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); | |
317 | delete list; | |
318 | } | |
319 | ||
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); | |
324 | } | |
325 | ||
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); | |
330 | } | |
331 | ||
332 | extern "C" void rados_shutdown(rados_t cluster) { | |
333 | librados::TestRadosClient *client = | |
334 | reinterpret_cast<librados::TestRadosClient*>(cluster); | |
335 | client->put(); | |
336 | } | |
337 | ||
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(); | |
342 | } | |
343 | ||
344 | namespace librados { | |
345 | ||
346 | void AioCompletion::release() { | |
347 | AioCompletionImpl *c = reinterpret_cast<AioCompletionImpl *>(pc); | |
348 | c->release(); | |
349 | delete this; | |
350 | } | |
351 | ||
352 | IoCtx::IoCtx() : io_ctx_impl(NULL) { | |
353 | } | |
354 | ||
355 | IoCtx::~IoCtx() { | |
356 | close(); | |
357 | } | |
358 | ||
359 | IoCtx::IoCtx(const IoCtx& rhs) { | |
360 | io_ctx_impl = rhs.io_ctx_impl; | |
361 | if (io_ctx_impl) { | |
362 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
363 | ctx->get(); | |
364 | } | |
365 | } | |
366 | ||
367 | IoCtx& IoCtx::operator=(const IoCtx& rhs) { | |
368 | if (io_ctx_impl) { | |
369 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
370 | ctx->put(); | |
371 | } | |
372 | ||
373 | io_ctx_impl = rhs.io_ctx_impl; | |
374 | if (io_ctx_impl) { | |
375 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
376 | ctx->get(); | |
377 | } | |
378 | return *this; | |
379 | } | |
380 | ||
381 | int IoCtx::aio_flush() { | |
382 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
383 | ctx->aio_flush(); | |
384 | return 0; | |
385 | } | |
386 | ||
387 | int IoCtx::aio_flush_async(AioCompletion *c) { | |
388 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
389 | ctx->aio_flush_async(c->pc); | |
390 | return 0; | |
391 | } | |
392 | ||
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); | |
397 | return 0; | |
398 | } | |
399 | ||
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); | |
403 | } | |
404 | ||
405 | int IoCtx::aio_operate(const std::string& oid, AioCompletion *c, | |
406 | ObjectReadOperation *op, int flags, | |
407 | bufferlist *pbl) { | |
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); | |
411 | } | |
412 | ||
31f18b77 FG |
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); | |
417 | } | |
418 | ||
7c673cae FG |
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); | |
424 | } | |
425 | ||
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); | |
431 | ||
432 | std::vector<snapid_t> snv; | |
433 | snv.resize(snaps.size()); | |
434 | for (size_t i = 0; i < snaps.size(); ++i) | |
435 | snv[i] = snaps[i]; | |
436 | SnapContext snapc(seq, snv); | |
437 | ||
438 | return ctx->aio_operate(oid, *ops, c->pc, &snapc, 0); | |
439 | } | |
440 | ||
31f18b77 FG |
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); | |
446 | } | |
447 | ||
7c673cae FG |
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); | |
451 | } | |
452 | ||
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); | |
457 | } | |
458 | ||
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); | |
462 | } | |
463 | ||
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()); | |
467 | } | |
468 | ||
469 | void IoCtx::close() { | |
470 | if (io_ctx_impl) { | |
471 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
472 | ctx->put(); | |
473 | } | |
474 | io_ctx_impl = NULL; | |
475 | } | |
476 | ||
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)); | |
481 | } | |
482 | ||
483 | void IoCtx::dup(const IoCtx& rhs) { | |
484 | close(); | |
485 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(rhs.io_ctx_impl); | |
486 | io_ctx_impl = reinterpret_cast<IoCtxImpl*>(ctx->clone()); | |
487 | } | |
488 | ||
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())); | |
495 | } | |
496 | ||
497 | void IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io) { | |
498 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(p); | |
499 | ctx->get(); | |
500 | ||
501 | io.close(); | |
502 | io.io_ctx_impl = reinterpret_cast<IoCtxImpl*>(ctx); | |
503 | } | |
504 | ||
505 | uint64_t IoCtx::get_instance_id() const { | |
506 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
507 | return ctx->get_instance_id(); | |
508 | } | |
509 | ||
510 | int64_t IoCtx::get_id() { | |
511 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
512 | return ctx->get_id(); | |
513 | } | |
514 | ||
515 | uint64_t IoCtx::get_last_version() { | |
516 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
517 | return ctx->get_last_version(); | |
518 | } | |
519 | ||
520 | std::string IoCtx::get_pool_name() { | |
521 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
522 | return ctx->get_pool_name(); | |
523 | } | |
524 | ||
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)); | |
529 | } | |
530 | ||
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)); | |
536 | } | |
537 | ||
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); | |
541 | } | |
542 | ||
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); | |
547 | } | |
548 | ||
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); | |
553 | } | |
554 | ||
555 | int IoCtx::omap_get_vals(const std::string& oid, | |
556 | const std::string& start_after, | |
557 | uint64_t max_return, | |
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)); | |
563 | } | |
564 | ||
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); | |
569 | } | |
570 | ||
571 | int IoCtx::operate(const std::string& oid, ObjectReadOperation *op, | |
572 | bufferlist *pbl) { | |
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); | |
576 | } | |
577 | ||
578 | int IoCtx::read(const std::string& oid, bufferlist& bl, size_t len, | |
579 | uint64_t off) { | |
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)); | |
583 | } | |
584 | ||
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())); | |
589 | } | |
590 | ||
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); | |
594 | } | |
595 | ||
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); | |
599 | } | |
600 | ||
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); | |
604 | } | |
605 | ||
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); | |
609 | } | |
610 | ||
611 | int IoCtx::selfmanaged_snap_rollback(const std::string& oid, | |
612 | uint64_t snapid) { | |
613 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
614 | return ctx->selfmanaged_snap_rollback(oid, snapid); | |
615 | } | |
616 | ||
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); | |
621 | } | |
622 | ||
623 | void IoCtx::snap_set_read(snap_t seq) { | |
624 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
625 | ctx->set_snap_read(seq); | |
626 | } | |
627 | ||
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)); | |
632 | } | |
633 | ||
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)); | |
638 | } | |
639 | ||
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())); | |
645 | } | |
646 | ||
647 | int IoCtx::unwatch2(uint64_t handle) { | |
648 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl); | |
649 | return ctx->unwatch(handle); | |
650 | } | |
651 | ||
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); | |
655 | } | |
656 | ||
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); | |
661 | } | |
662 | ||
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); | |
667 | } | |
668 | ||
669 | int IoCtx::write(const std::string& oid, bufferlist& bl, size_t len, | |
670 | uint64_t off) { | |
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())); | |
675 | } | |
676 | ||
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())); | |
682 | } | |
683 | ||
684 | int IoCtx::writesame(const std::string& oid, bufferlist& bl, size_t len, | |
685 | uint64_t off) { | |
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())); | |
690 | } | |
691 | ||
692 | static int save_operation_result(int result, int *pval) { | |
693 | if (pval != NULL) { | |
694 | *pval = result; | |
695 | } | |
696 | return result; | |
697 | } | |
698 | ||
699 | ObjectOperation::ObjectOperation() { | |
700 | TestObjectOperationImpl *o = new TestObjectOperationImpl(); | |
701 | o->get(); | |
702 | impl = reinterpret_cast<ObjectOperationImpl*>(o); | |
703 | } | |
704 | ||
705 | ObjectOperation::~ObjectOperation() { | |
706 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
707 | if (o) { | |
708 | o->put(); | |
709 | o = NULL; | |
710 | } | |
711 | } | |
712 | ||
713 | void ObjectOperation::assert_exists() { | |
714 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
715 | o->ops.push_back(boost::bind(&TestIoCtxImpl::assert_exists, _1, _2)); | |
716 | } | |
717 | ||
718 | void ObjectOperation::exec(const char *cls, const char *method, | |
719 | bufferlist& inbl) { | |
720 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
721 | o->ops.push_back(boost::bind(&TestIoCtxImpl::exec, _1, _2, | |
722 | get_class_handler(), cls, method, inbl, _3, _4)); | |
723 | } | |
724 | ||
725 | void ObjectOperation::set_op_flags2(int flags) { | |
726 | } | |
727 | ||
728 | size_t ObjectOperation::size() { | |
729 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
730 | return o->ops.size(); | |
731 | } | |
732 | ||
733 | void ObjectReadOperation::list_snaps(snap_set_t *out_snaps, int *prval) { | |
734 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
735 | ||
736 | ObjectOperationTestImpl op = boost::bind(&TestIoCtxImpl::list_snaps, _1, _2, | |
737 | out_snaps); | |
738 | if (prval != NULL) { | |
739 | op = boost::bind(save_operation_result, | |
740 | boost::bind(op, _1, _2, _3, _4), prval); | |
741 | } | |
742 | o->ops.push_back(op); | |
743 | } | |
744 | ||
745 | void ObjectReadOperation::list_watchers(std::list<obj_watch_t> *out_watchers, | |
746 | int *prval) { | |
747 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
748 | ||
749 | ObjectOperationTestImpl op = boost::bind(&TestIoCtxImpl::list_watchers, _1, | |
750 | _2, out_watchers); | |
751 | if (prval != NULL) { | |
752 | op = boost::bind(save_operation_result, | |
753 | boost::bind(op, _1, _2, _3, _4), prval); | |
754 | } | |
755 | o->ops.push_back(op); | |
756 | } | |
757 | ||
758 | void ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl, | |
759 | int *prval) { | |
760 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
761 | ||
762 | ObjectOperationTestImpl op; | |
763 | if (pbl != NULL) { | |
764 | op = boost::bind(&TestIoCtxImpl::read, _1, _2, len, off, pbl); | |
765 | } else { | |
766 | op = boost::bind(&TestIoCtxImpl::read, _1, _2, len, off, _3); | |
767 | } | |
768 | ||
769 | if (prval != NULL) { | |
770 | op = boost::bind(save_operation_result, | |
771 | boost::bind(op, _1, _2, _3, _4), prval); | |
772 | } | |
773 | o->ops.push_back(op); | |
774 | } | |
775 | ||
776 | void ObjectReadOperation::sparse_read(uint64_t off, uint64_t len, | |
777 | std::map<uint64_t,uint64_t> *m, | |
778 | bufferlist *pbl, int *prval) { | |
779 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
780 | ||
781 | ObjectOperationTestImpl op; | |
782 | if (pbl != NULL) { | |
783 | op = boost::bind(&TestIoCtxImpl::sparse_read, _1, _2, off, len, m, pbl); | |
784 | } else { | |
785 | op = boost::bind(&TestIoCtxImpl::sparse_read, _1, _2, off, len, m, _3); | |
786 | } | |
787 | ||
788 | if (prval != NULL) { | |
789 | op = boost::bind(save_operation_result, | |
790 | boost::bind(op, _1, _2, _3, _4), prval); | |
791 | } | |
792 | o->ops.push_back(op); | |
793 | } | |
794 | ||
795 | void ObjectReadOperation::stat(uint64_t *psize, time_t *pmtime, int *prval) { | |
796 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
797 | ||
798 | ObjectOperationTestImpl op = boost::bind(&TestIoCtxImpl::stat, _1, _2, | |
799 | psize, pmtime); | |
800 | ||
801 | if (prval != NULL) { | |
802 | op = boost::bind(save_operation_result, | |
803 | boost::bind(op, _1, _2, _3, _4), prval); | |
804 | } | |
805 | o->ops.push_back(op); | |
806 | } | |
807 | ||
808 | void ObjectWriteOperation::append(const bufferlist &bl) { | |
809 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
810 | o->ops.push_back(boost::bind(&TestIoCtxImpl::append, _1, _2, bl, _4)); | |
811 | } | |
812 | ||
813 | void ObjectWriteOperation::create(bool exclusive) { | |
814 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
815 | o->ops.push_back(boost::bind(&TestIoCtxImpl::create, _1, _2, exclusive)); | |
816 | } | |
817 | ||
818 | void ObjectWriteOperation::omap_set(const std::map<std::string, bufferlist> &map) { | |
819 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
820 | o->ops.push_back(boost::bind(&TestIoCtxImpl::omap_set, _1, _2, boost::ref(map))); | |
821 | } | |
822 | ||
823 | void ObjectWriteOperation::remove() { | |
824 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
825 | o->ops.push_back(boost::bind(&TestIoCtxImpl::remove, _1, _2, _4)); | |
826 | } | |
827 | ||
828 | void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid) { | |
829 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
830 | o->ops.push_back(boost::bind(&TestIoCtxImpl::selfmanaged_snap_rollback, | |
831 | _1, _2, snapid)); | |
832 | } | |
833 | ||
834 | void ObjectWriteOperation::set_alloc_hint(uint64_t expected_object_size, | |
835 | uint64_t expected_write_size) { | |
836 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
837 | o->ops.push_back(boost::bind(&TestIoCtxImpl::set_alloc_hint, _1, _2, | |
838 | expected_object_size, expected_write_size)); | |
839 | } | |
840 | ||
841 | ||
842 | void ObjectWriteOperation::tmap_update(const bufferlist& cmdbl) { | |
843 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
844 | o->ops.push_back(boost::bind(&TestIoCtxImpl::tmap_update, _1, _2, | |
845 | cmdbl)); | |
846 | } | |
847 | ||
848 | void ObjectWriteOperation::truncate(uint64_t off) { | |
849 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
850 | o->ops.push_back(boost::bind(&TestIoCtxImpl::truncate, _1, _2, off, _4)); | |
851 | } | |
852 | ||
853 | void ObjectWriteOperation::write(uint64_t off, const bufferlist& bl) { | |
854 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
855 | o->ops.push_back(boost::bind(&TestIoCtxImpl::write, _1, _2, bl, bl.length(), | |
856 | off, _4)); | |
857 | } | |
858 | ||
859 | void ObjectWriteOperation::write_full(const bufferlist& bl) { | |
860 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
861 | o->ops.push_back(boost::bind(&TestIoCtxImpl::write_full, _1, _2, bl, _4)); | |
862 | } | |
863 | ||
864 | void ObjectWriteOperation::writesame(uint64_t off, uint64_t len, const bufferlist& bl) { | |
865 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
866 | o->ops.push_back(boost::bind(&TestIoCtxImpl::writesame, _1, _2, bl, len, | |
867 | off, _4)); | |
868 | } | |
869 | ||
870 | void ObjectWriteOperation::zero(uint64_t off, uint64_t len) { | |
871 | TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl); | |
872 | o->ops.push_back(boost::bind(&TestIoCtxImpl::zero, _1, _2, off, len)); | |
873 | } | |
874 | ||
875 | Rados::Rados() : client(NULL) { | |
876 | } | |
877 | ||
878 | Rados::Rados(IoCtx& ioctx) { | |
879 | TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(ioctx.io_ctx_impl); | |
880 | TestRadosClient *impl = ctx->get_rados_client(); | |
881 | impl->get(); | |
882 | ||
883 | client = reinterpret_cast<RadosClient*>(impl); | |
884 | assert(client != NULL); | |
885 | } | |
886 | ||
887 | Rados::~Rados() { | |
888 | shutdown(); | |
889 | } | |
890 | ||
891 | AioCompletion *Rados::aio_create_completion(void *cb_arg, | |
892 | callback_t cb_complete, | |
893 | callback_t cb_safe) { | |
894 | AioCompletionImpl *c; | |
895 | int r = rados_aio_create_completion(cb_arg, cb_complete, cb_safe, | |
896 | reinterpret_cast<void**>(&c)); | |
897 | assert(r == 0); | |
898 | return new AioCompletion(c); | |
899 | } | |
900 | ||
901 | int Rados::aio_watch_flush(AioCompletion* c) { | |
902 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
903 | return impl->aio_watch_flush(c->pc); | |
904 | } | |
905 | ||
906 | int Rados::blacklist_add(const std::string& client_address, | |
907 | uint32_t expire_seconds) { | |
908 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
909 | return impl->blacklist_add(client_address, expire_seconds); | |
910 | } | |
911 | ||
912 | config_t Rados::cct() { | |
913 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
914 | return reinterpret_cast<config_t>(impl->cct()); | |
915 | } | |
916 | ||
917 | int Rados::cluster_fsid(std::string* fsid) { | |
918 | *fsid = "00000000-1111-2222-3333-444444444444"; | |
919 | return 0; | |
920 | } | |
921 | ||
922 | int Rados::conf_set(const char *option, const char *value) { | |
923 | return rados_conf_set(reinterpret_cast<rados_t>(client), option, value); | |
924 | } | |
925 | ||
926 | int Rados::conf_get(const char *option, std::string &val) { | |
927 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
928 | CephContext *cct = impl->cct(); | |
929 | ||
930 | char *str = NULL; | |
931 | int ret = cct->_conf->get_val(option, &str, -1); | |
932 | if (ret != 0) { | |
933 | free(str); | |
934 | return ret; | |
935 | } | |
936 | ||
937 | val = str; | |
938 | free(str); | |
939 | return 0; | |
940 | } | |
941 | ||
942 | int Rados::conf_parse_env(const char *env) const { | |
943 | return rados_conf_parse_env(reinterpret_cast<rados_t>(client), env); | |
944 | } | |
945 | ||
946 | int Rados::conf_read_file(const char * const path) const { | |
947 | return rados_conf_read_file(reinterpret_cast<rados_t>(client), path); | |
948 | } | |
949 | ||
950 | int Rados::connect() { | |
951 | return rados_connect(reinterpret_cast<rados_t>(client)); | |
952 | } | |
953 | ||
954 | uint64_t Rados::get_instance_id() { | |
955 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
956 | return impl->get_instance_id(); | |
957 | } | |
958 | ||
959 | int Rados::init(const char * const id) { | |
960 | return rados_create(reinterpret_cast<rados_t *>(&client), id); | |
961 | } | |
962 | ||
963 | int Rados::ioctx_create(const char *name, IoCtx &io) { | |
964 | rados_ioctx_t p; | |
965 | int ret = rados_ioctx_create(reinterpret_cast<rados_t>(client), name, &p); | |
966 | if (ret) { | |
967 | return ret; | |
968 | } | |
969 | ||
970 | io.close(); | |
971 | io.io_ctx_impl = reinterpret_cast<IoCtxImpl*>(p); | |
972 | return 0; | |
973 | } | |
974 | ||
975 | int Rados::ioctx_create2(int64_t pool_id, IoCtx &io) | |
976 | { | |
977 | rados_ioctx_t p; | |
978 | int ret = rados_ioctx_create2(reinterpret_cast<rados_t>(client), pool_id, &p); | |
979 | if (ret) { | |
980 | return ret; | |
981 | } | |
982 | ||
983 | io.close(); | |
984 | io.io_ctx_impl = reinterpret_cast<IoCtxImpl*>(p); | |
985 | return 0; | |
986 | } | |
987 | ||
988 | int Rados::mon_command(std::string cmd, const bufferlist& inbl, | |
989 | bufferlist *outbl, std::string *outs) { | |
990 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
991 | ||
992 | std::vector<std::string> cmds; | |
993 | cmds.push_back(cmd); | |
994 | return impl->mon_command(cmds, inbl, outbl, outs); | |
995 | } | |
996 | ||
997 | int Rados::pool_create(const char *name) { | |
998 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
999 | return impl->pool_create(name); | |
1000 | } | |
1001 | ||
1002 | int Rados::pool_delete(const char *name) { | |
1003 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1004 | return impl->pool_delete(name); | |
1005 | } | |
1006 | ||
1007 | int Rados::pool_get_base_tier(int64_t pool, int64_t* base_tier) { | |
1008 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1009 | return impl->pool_get_base_tier(pool, base_tier); | |
1010 | } | |
1011 | ||
1012 | int Rados::pool_list(std::list<std::string>& v) { | |
1013 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1014 | std::list<std::pair<int64_t, std::string> > pools; | |
1015 | int r = impl->pool_list(pools); | |
1016 | if (r < 0) { | |
1017 | return r; | |
1018 | } | |
1019 | ||
1020 | v.clear(); | |
1021 | for (std::list<std::pair<int64_t, std::string> >::iterator it = pools.begin(); | |
1022 | it != pools.end(); ++it) { | |
1023 | v.push_back(it->second); | |
1024 | } | |
1025 | return 0; | |
1026 | } | |
1027 | ||
1028 | int Rados::pool_list2(std::list<std::pair<int64_t, std::string> >& v) | |
1029 | { | |
1030 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1031 | return impl->pool_list(v); | |
1032 | } | |
1033 | ||
1034 | int64_t Rados::pool_lookup(const char *name) { | |
1035 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1036 | return impl->pool_lookup(name); | |
1037 | } | |
1038 | ||
1039 | int Rados::pool_reverse_lookup(int64_t id, std::string *name) { | |
1040 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1041 | return impl->pool_reverse_lookup(id, name); | |
1042 | } | |
1043 | ||
1044 | void Rados::shutdown() { | |
1045 | if (client == NULL) { | |
1046 | return; | |
1047 | } | |
1048 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1049 | impl->put(); | |
1050 | client = NULL; | |
1051 | } | |
1052 | ||
1053 | void Rados::test_blacklist_self(bool set) { | |
1054 | } | |
1055 | ||
1056 | int Rados::wait_for_latest_osdmap() { | |
1057 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1058 | return impl->wait_for_latest_osdmap(); | |
1059 | } | |
1060 | ||
1061 | int Rados::watch_flush() { | |
1062 | TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client); | |
1063 | return impl->watch_flush(); | |
1064 | } | |
1065 | ||
1066 | WatchCtx::~WatchCtx() { | |
1067 | } | |
1068 | ||
1069 | WatchCtx2::~WatchCtx2() { | |
1070 | } | |
1071 | ||
1072 | } // namespace librados | |
1073 | ||
1074 | int cls_cxx_create(cls_method_context_t hctx, bool exclusive) { | |
1075 | librados::TestClassHandler::MethodContext *ctx = | |
1076 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1077 | return ctx->io_ctx_impl->create(ctx->oid, exclusive); | |
1078 | } | |
1079 | ||
1080 | int cls_get_request_origin(cls_method_context_t hctx, entity_inst_t *origin) { | |
1081 | librados::TestClassHandler::MethodContext *ctx = | |
1082 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1083 | ||
1084 | librados::TestRadosClient *rados_client = | |
1085 | ctx->io_ctx_impl->get_rados_client(); | |
1086 | ||
1087 | struct sockaddr_in sin; | |
1088 | sin.sin_family = AF_INET; | |
1089 | sin.sin_port = 0; | |
1090 | inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr); | |
1091 | ||
1092 | entity_addr_t entity_addr(entity_addr_t::TYPE_DEFAULT, | |
1093 | rados_client->get_nonce()); | |
1094 | entity_addr.in4_addr() = sin; | |
1095 | ||
1096 | *origin = entity_inst_t( | |
1097 | entity_name_t::CLIENT(rados_client->get_instance_id()), | |
1098 | entity_addr); | |
1099 | return 0; | |
1100 | } | |
1101 | ||
1102 | int cls_cxx_getxattr(cls_method_context_t hctx, const char *name, | |
1103 | bufferlist *outbl) { | |
1104 | std::map<string, bufferlist> attrs; | |
1105 | int r = cls_cxx_getxattrs(hctx, &attrs); | |
1106 | if (r < 0) { | |
1107 | return r; | |
1108 | } | |
1109 | ||
1110 | std::map<string, bufferlist>::iterator it = attrs.find(name); | |
1111 | if (it == attrs.end()) { | |
1112 | return -ENODATA; | |
1113 | } | |
1114 | *outbl = it->second; | |
1115 | return 0; | |
1116 | } | |
1117 | ||
1118 | int cls_cxx_getxattrs(cls_method_context_t hctx, std::map<string, bufferlist> *attrset) { | |
1119 | librados::TestClassHandler::MethodContext *ctx = | |
1120 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1121 | return ctx->io_ctx_impl->xattr_get(ctx->oid, attrset); | |
1122 | } | |
1123 | ||
1124 | int cls_cxx_map_get_keys(cls_method_context_t hctx, const string &start_obj, | |
1125 | uint64_t max_to_get, std::set<string> *keys) { | |
1126 | librados::TestClassHandler::MethodContext *ctx = | |
1127 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1128 | ||
1129 | keys->clear(); | |
1130 | std::map<string, bufferlist> vals; | |
1131 | std::string last_key = start_obj; | |
1132 | do { | |
1133 | vals.clear(); | |
1134 | int r = ctx->io_ctx_impl->omap_get_vals(ctx->oid, last_key, "", 1024, | |
1135 | &vals); | |
1136 | if (r < 0) { | |
1137 | return r; | |
1138 | } | |
1139 | ||
1140 | for (std::map<string, bufferlist>::iterator it = vals.begin(); | |
1141 | it != vals.end(); ++it) { | |
1142 | last_key = it->first; | |
1143 | keys->insert(last_key); | |
1144 | } | |
1145 | } while (!vals.empty()); | |
1146 | return keys->size(); | |
1147 | } | |
1148 | ||
1149 | int cls_cxx_map_get_val(cls_method_context_t hctx, const string &key, | |
1150 | bufferlist *outbl) { | |
1151 | librados::TestClassHandler::MethodContext *ctx = | |
1152 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1153 | ||
1154 | std::map<string, bufferlist> vals; | |
1155 | int r = ctx->io_ctx_impl->omap_get_vals(ctx->oid, "", key, 1024, &vals); | |
1156 | if (r < 0) { | |
1157 | return r; | |
1158 | } | |
1159 | ||
1160 | std::map<string, bufferlist>::iterator it = vals.find(key); | |
1161 | if (it == vals.end()) { | |
1162 | return -ENOENT; | |
1163 | } | |
1164 | ||
1165 | *outbl = it->second; | |
1166 | return 0; | |
1167 | } | |
1168 | ||
1169 | int cls_cxx_map_get_vals(cls_method_context_t hctx, const string &start_obj, | |
1170 | const string &filter_prefix, uint64_t max_to_get, | |
1171 | std::map<string, bufferlist> *vals) { | |
1172 | librados::TestClassHandler::MethodContext *ctx = | |
1173 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1174 | int r = ctx->io_ctx_impl->omap_get_vals(ctx->oid, start_obj, filter_prefix, | |
1175 | max_to_get, vals); | |
1176 | if (r < 0) { | |
1177 | return r; | |
1178 | } | |
1179 | return vals->size(); | |
1180 | } | |
1181 | ||
1182 | int cls_cxx_map_remove_key(cls_method_context_t hctx, const string &key) { | |
1183 | std::set<std::string> keys; | |
1184 | keys.insert(key); | |
1185 | ||
1186 | librados::TestClassHandler::MethodContext *ctx = | |
1187 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1188 | return ctx->io_ctx_impl->omap_rm_keys(ctx->oid, keys); | |
1189 | } | |
1190 | ||
1191 | int cls_cxx_map_set_val(cls_method_context_t hctx, const string &key, | |
1192 | bufferlist *inbl) { | |
1193 | std::map<std::string, bufferlist> m; | |
1194 | m[key] = *inbl; | |
1195 | return cls_cxx_map_set_vals(hctx, &m); | |
1196 | } | |
1197 | ||
1198 | int cls_cxx_map_set_vals(cls_method_context_t hctx, | |
1199 | const std::map<string, bufferlist> *map) { | |
1200 | librados::TestClassHandler::MethodContext *ctx = | |
1201 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1202 | return ctx->io_ctx_impl->omap_set(ctx->oid, *map); | |
1203 | } | |
1204 | ||
1205 | int cls_cxx_read(cls_method_context_t hctx, int ofs, int len, | |
1206 | bufferlist *outbl) { | |
1207 | return cls_cxx_read2(hctx, ofs, len, outbl, 0); | |
1208 | } | |
1209 | ||
1210 | int cls_cxx_read2(cls_method_context_t hctx, int ofs, int len, | |
1211 | bufferlist *outbl, uint32_t op_flags) { | |
1212 | librados::TestClassHandler::MethodContext *ctx = | |
1213 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1214 | return ctx->io_ctx_impl->read(ctx->oid, len, ofs, outbl); | |
1215 | } | |
1216 | ||
1217 | int cls_cxx_setxattr(cls_method_context_t hctx, const char *name, | |
1218 | bufferlist *inbl) { | |
1219 | librados::TestClassHandler::MethodContext *ctx = | |
1220 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1221 | return ctx->io_ctx_impl->xattr_set(ctx->oid, name, *inbl); | |
1222 | } | |
1223 | ||
1224 | int cls_cxx_stat(cls_method_context_t hctx, uint64_t *size, time_t *mtime) { | |
1225 | librados::TestClassHandler::MethodContext *ctx = | |
1226 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1227 | return ctx->io_ctx_impl->stat(ctx->oid, size, mtime); | |
1228 | } | |
1229 | ||
1230 | int cls_cxx_write(cls_method_context_t hctx, int ofs, int len, | |
1231 | bufferlist *inbl) { | |
1232 | return cls_cxx_write2(hctx, ofs, len, inbl, 0); | |
1233 | } | |
1234 | ||
1235 | int cls_cxx_write2(cls_method_context_t hctx, int ofs, int len, | |
1236 | bufferlist *inbl, uint32_t op_flags) { | |
1237 | librados::TestClassHandler::MethodContext *ctx = | |
1238 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1239 | return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs, ctx->snapc); | |
1240 | } | |
1241 | ||
1242 | int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *inbl) { | |
1243 | librados::TestClassHandler::MethodContext *ctx = | |
1244 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1245 | return ctx->io_ctx_impl->write_full(ctx->oid, *inbl, ctx->snapc); | |
1246 | } | |
1247 | ||
1248 | int cls_cxx_list_watchers(cls_method_context_t hctx, | |
1249 | obj_list_watch_response_t *watchers) { | |
1250 | librados::TestClassHandler::MethodContext *ctx = | |
1251 | reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx); | |
1252 | ||
1253 | std::list<obj_watch_t> obj_watchers; | |
1254 | int r = ctx->io_ctx_impl->list_watchers(ctx->oid, &obj_watchers); | |
1255 | if (r < 0) { | |
1256 | return r; | |
1257 | } | |
1258 | ||
1259 | for (auto &w : obj_watchers) { | |
1260 | watch_item_t watcher; | |
1261 | watcher.name = entity_name_t::CLIENT(w.watcher_id); | |
1262 | watcher.cookie = w.cookie; | |
1263 | watcher.timeout_seconds = w.timeout_seconds; | |
1264 | watcher.addr.parse(w.addr, 0); | |
1265 | watchers->entries.push_back(watcher); | |
1266 | } | |
1267 | ||
1268 | return 0; | |
1269 | } | |
1270 | ||
1271 | uint64_t cls_get_features(cls_method_context_t hctx) { | |
1272 | return CEPH_FEATURES_SUPPORTED_DEFAULT; | |
1273 | } | |
1274 | ||
1275 | uint64_t cls_get_client_features(cls_method_context_t hctx) { | |
1276 | return CEPH_FEATURES_SUPPORTED_DEFAULT; | |
1277 | } | |
1278 | ||
1279 | int cls_log(int level, const char *format, ...) { | |
1280 | int size = 256; | |
1281 | va_list ap; | |
1282 | while (1) { | |
1283 | char buf[size]; | |
1284 | va_start(ap, format); | |
1285 | int n = vsnprintf(buf, size, format, ap); | |
1286 | va_end(ap); | |
1287 | if ((n > -1 && n < size) || size > 8196) { | |
1288 | dout(level) << buf << dendl; | |
1289 | return n; | |
1290 | } | |
1291 | size *= 2; | |
1292 | } | |
1293 | return 0; | |
1294 | } | |
1295 | ||
1296 | int cls_register(const char *name, cls_handle_t *handle) { | |
1297 | librados::TestClassHandler *cls = get_class_handler(); | |
1298 | return cls->create(name, handle); | |
1299 | } | |
1300 | ||
1301 | int cls_register_cxx_method(cls_handle_t hclass, const char *method, | |
1302 | int flags, | |
1303 | cls_method_cxx_call_t class_call, | |
1304 | cls_method_handle_t *handle) { | |
1305 | librados::TestClassHandler *cls = get_class_handler(); | |
1306 | return cls->create_method(hclass, method, class_call, handle); | |
1307 | } | |
1308 | ||
1309 | int cls_register_cxx_filter(cls_handle_t hclass, | |
1310 | const std::string &filter_name, | |
1311 | cls_cxx_filter_factory_t fn, | |
1312 | cls_filter_handle_t *) | |
1313 | { | |
1314 | librados::TestClassHandler *cls = get_class_handler(); | |
1315 | return cls->create_filter(hclass, filter_name, fn); | |
1316 | } |