1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #include "include/rados/librados.hpp"
7 #include "common/errno.h"
8 #include "osd/osd_types.h"
9 #include "rgw/rgw_tools.h"
10 #include "rgw/rgw_cr_rados.h"
12 #include "auth/AuthRegistry.h"
14 #define dout_subsys ceph_subsys_rgw
16 RGWSI_RADOS::RGWSI_RADOS(CephContext
*cct
) : RGWServiceInstance(cct
)
20 RGWSI_RADOS::~RGWSI_RADOS()
24 int RGWSI_RADOS::do_start(optional_yield
)
26 int ret
= rados
.init_with_context(cct
);
30 ret
= rados
.connect();
35 async_processor
.reset(new RGWAsyncRadosProcessor(cct
, cct
->_conf
->rgw_num_async_rados_threads
));
36 async_processor
->start();
41 void RGWSI_RADOS::shutdown()
43 if (async_processor
) {
44 async_processor
->stop();
48 librados::Rados
* RGWSI_RADOS::get_rados_handle()
53 uint64_t RGWSI_RADOS::instance_id()
55 return get_rados_handle()->get_instance_id();
58 int RGWSI_RADOS::open_pool_ctx(const rgw_pool
& pool
, librados::IoCtx
& io_ctx
,
59 const OpenParams
& params
)
61 return rgw_init_ioctx(get_rados_handle(), pool
, io_ctx
,
66 int RGWSI_RADOS::pool_iterate(librados::IoCtx
& io_ctx
,
67 librados::NObjectIterator
& iter
,
68 uint32_t num
, vector
<rgw_bucket_dir_entry
>& objs
,
69 RGWAccessListFilter
*filter
,
72 if (iter
== io_ctx
.nobjects_end())
77 for (i
= 0; i
< num
&& iter
!= io_ctx
.nobjects_end(); ++i
, ++iter
) {
78 rgw_bucket_dir_entry e
;
80 string oid
= iter
->get_oid();
81 ldout(cct
, 20) << "RGWRados::pool_iterate: got " << oid
<< dendl
;
83 // fill it in with initial values; we may correct later
84 if (filter
&& !filter
->filter(oid
, oid
))
92 *is_truncated
= (iter
!= io_ctx
.nobjects_end());
97 RGWSI_RADOS::Obj::Obj(Pool
& pool
, const string
& oid
) : rados_svc(pool
.rados_svc
)
100 ref
.obj
= rgw_raw_obj(pool
.get_pool(), oid
);
103 void RGWSI_RADOS::Obj::init(const rgw_raw_obj
& obj
)
105 ref
.pool
= RGWSI_RADOS::Pool(rados_svc
, obj
.pool
);
109 int RGWSI_RADOS::Obj::open()
111 int r
= ref
.pool
.open();
116 ref
.pool
.ioctx().locator_set_key(ref
.obj
.loc
);
121 int RGWSI_RADOS::Obj::operate(librados::ObjectWriteOperation
*op
,
122 optional_yield y
, int flags
)
124 return rgw_rados_operate(ref
.pool
.ioctx(), ref
.obj
.oid
, op
, y
, flags
);
127 int RGWSI_RADOS::Obj::operate(librados::ObjectReadOperation
*op
,
128 bufferlist
*pbl
, optional_yield y
, int flags
)
130 return rgw_rados_operate(ref
.pool
.ioctx(), ref
.obj
.oid
, op
, pbl
, y
, flags
);
133 int RGWSI_RADOS::Obj::aio_operate(librados::AioCompletion
*c
, librados::ObjectWriteOperation
*op
)
135 return ref
.pool
.ioctx().aio_operate(ref
.obj
.oid
, c
, op
);
138 int RGWSI_RADOS::Obj::aio_operate(librados::AioCompletion
*c
, librados::ObjectReadOperation
*op
,
141 return ref
.pool
.ioctx().aio_operate(ref
.obj
.oid
, c
, op
, pbl
);
144 int RGWSI_RADOS::Obj::watch(uint64_t *handle
, librados::WatchCtx2
*ctx
)
146 return ref
.pool
.ioctx().watch2(ref
.obj
.oid
, handle
, ctx
);
149 int RGWSI_RADOS::Obj::aio_watch(librados::AioCompletion
*c
, uint64_t *handle
, librados::WatchCtx2
*ctx
)
151 return ref
.pool
.ioctx().aio_watch(ref
.obj
.oid
, c
, handle
, ctx
);
154 int RGWSI_RADOS::Obj::unwatch(uint64_t handle
)
156 return ref
.pool
.ioctx().unwatch2(handle
);
159 int RGWSI_RADOS::Obj::notify(bufferlist
& bl
, uint64_t timeout_ms
,
160 bufferlist
*pbl
, optional_yield y
)
162 return rgw_rados_notify(ref
.pool
.ioctx(), ref
.obj
.oid
, bl
, timeout_ms
, pbl
, y
);
165 void RGWSI_RADOS::Obj::notify_ack(uint64_t notify_id
,
169 ref
.pool
.ioctx().notify_ack(ref
.obj
.oid
, notify_id
, cookie
, bl
);
172 uint64_t RGWSI_RADOS::Obj::get_last_version()
174 return ref
.pool
.ioctx().get_last_version();
177 int RGWSI_RADOS::Pool::create()
179 librados::Rados
*rad
= rados_svc
->get_rados_handle();
180 int r
= rad
->pool_create(pool
.name
.c_str());
182 ldout(rados_svc
->cct
, 0) << "WARNING: pool_create returned " << r
<< dendl
;
185 librados::IoCtx io_ctx
;
186 r
= rad
->ioctx_create(pool
.name
.c_str(), io_ctx
);
188 ldout(rados_svc
->cct
, 0) << "WARNING: ioctx_create returned " << r
<< dendl
;
191 r
= io_ctx
.application_enable(pg_pool_t::APPLICATION_NAME_RGW
, false);
193 ldout(rados_svc
->cct
, 0) << "WARNING: application_enable returned " << r
<< dendl
;
199 int RGWSI_RADOS::Pool::create(const vector
<rgw_pool
>& pools
, vector
<int> *retcodes
)
201 vector
<librados::PoolAsyncCompletion
*> completions
;
204 librados::Rados
*rad
= rados_svc
->get_rados_handle();
205 for (auto iter
= pools
.begin(); iter
!= pools
.end(); ++iter
) {
206 librados::PoolAsyncCompletion
*c
= librados::Rados::pool_async_create_completion();
207 completions
.push_back(c
);
209 int ret
= rad
->pool_create_async(pool
.name
.c_str(), c
);
213 vector
<int>::iterator riter
;
214 vector
<librados::PoolAsyncCompletion
*>::iterator citer
;
217 ceph_assert(rets
.size() == completions
.size());
218 for (riter
= rets
.begin(), citer
= completions
.begin(); riter
!= rets
.end(); ++riter
, ++citer
) {
220 librados::PoolAsyncCompletion
*c
= *citer
;
223 r
= c
->get_return_value();
225 ldout(rados_svc
->cct
, 0) << "WARNING: async pool_create returned " << r
<< dendl
;
230 retcodes
->push_back(r
);
236 std::vector
<librados::IoCtx
> io_ctxs
;
238 for (auto pool
: pools
) {
239 io_ctxs
.emplace_back();
240 int ret
= rad
->ioctx_create(pool
.name
.c_str(), io_ctxs
.back());
242 ldout(rados_svc
->cct
, 0) << "WARNING: ioctx_create returned " << ret
<< dendl
;
245 retcodes
->push_back(ret
);
252 for (auto &io_ctx
: io_ctxs
) {
253 librados::PoolAsyncCompletion
*c
=
254 librados::Rados::pool_async_create_completion();
255 completions
.push_back(c
);
256 int ret
= io_ctx
.application_enable_async(pg_pool_t::APPLICATION_NAME_RGW
,
258 ceph_assert(ret
== 0);
262 for (auto c
: completions
) {
264 int ret
= c
->get_return_value();
265 if (ret
== -EOPNOTSUPP
) {
267 } else if (ret
< 0) {
268 ldout(rados_svc
->cct
, 0) << "WARNING: async application_enable returned " << ret
273 retcodes
->push_back(ret
);
278 int RGWSI_RADOS::Pool::lookup()
280 librados::Rados
*rad
= rados_svc
->get_rados_handle();
281 int ret
= rad
->pool_lookup(pool
.name
.c_str());
289 int RGWSI_RADOS::Pool::open(const OpenParams
& params
)
291 return rados_svc
->open_pool_ctx(pool
, state
.ioctx
, params
);
294 int RGWSI_RADOS::Pool::List::init(const string
& marker
, RGWAccessListFilter
*filter
)
296 if (ctx
.initialized
) {
304 int r
= pool
->rados_svc
->open_pool_ctx(pool
->pool
, ctx
.ioctx
);
309 librados::ObjectCursor oc
;
310 if (!oc
.from_str(marker
)) {
311 ldout(pool
->rados_svc
->cct
, 10) << "failed to parse cursor: " << marker
<< dendl
;
315 ctx
.iter
= ctx
.ioctx
.nobjects_begin(oc
);
317 ctx
.initialized
= true;
322 int RGWSI_RADOS::Pool::List::get_next(int max
,
323 std::vector
<string
> *oids
,
326 if (!ctx
.initialized
) {
329 vector
<rgw_bucket_dir_entry
> objs
;
330 int r
= pool
->rados_svc
->pool_iterate(ctx
.ioctx
, ctx
.iter
, max
, objs
, ctx
.filter
, is_truncated
);
333 ldout(pool
->rados_svc
->cct
, 10) << "failed to list objects pool_iterate returned r=" << r
<< dendl
;
338 for (auto& o
: objs
) {
339 oids
->push_back(o
.key
.name
);
345 RGWSI_RADOS::Obj
RGWSI_RADOS::Handle::obj(const rgw_raw_obj
& o
)
347 return RGWSI_RADOS::Obj(rados_svc
, o
);
349 int RGWSI_RADOS::Handle::watch_flush()
351 librados::Rados
*rad
= rados_svc
->get_rados_handle();
352 return rad
->watch_flush();
355 int RGWSI_RADOS::Handle::mon_command(std::string cmd
,
356 const bufferlist
& inbl
,
360 librados::Rados
*rad
= rados_svc
->get_rados_handle();
361 return rad
->mon_command(cmd
, inbl
, outbl
, outs
);
364 int RGWSI_RADOS::Pool::List::get_marker(string
*marker
)
366 if (!ctx
.initialized
) {
370 *marker
= ctx
.iter
.get_cursor().to_str();
374 int RGWSI_RADOS::clog_warn(const string
& msg
)
378 "\"prefix\": \"log\", "
379 "\"level\": \"warn\", "
380 "\"logtext\": [\"" + msg
+ "\"]"
385 return h
.mon_command(cmd
, inbl
, nullptr, nullptr);
388 bool RGWSI_RADOS::check_secure_mon_conn() const
390 AuthRegistry
reg(cct
);
392 reg
.refresh_config();
394 std::vector
<uint32_t> methods
;
395 std::vector
<uint32_t> modes
;
397 reg
.get_supported_methods(CEPH_ENTITY_TYPE_MON
, &methods
, &modes
);
398 ldout(cct
, 20) << __func__
<< "(): auth registy supported: methods=" << methods
<< " modes=" << modes
<< dendl
;
400 for (auto method
: methods
) {
401 if (!reg
.is_secure_method(method
)) {
402 ldout(cct
, 20) << __func__
<< "(): method " << method
<< " is insecure" << dendl
;
407 for (auto mode
: modes
) {
408 if (!reg
.is_secure_mode(mode
)) {
409 ldout(cct
, 20) << __func__
<< "(): mode " << mode
<< " is insecure" << dendl
;