]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/services/svc_rados.cc
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rgw / services / svc_rados.cc
CommitLineData
11fdf7f2
TL
1#include "svc_rados.h"
2
3#include "include/rados/librados.hpp"
4#include "common/errno.h"
5#include "osd/osd_types.h"
6#include "rgw/rgw_tools.h"
7
8#define dout_subsys ceph_subsys_rgw
9
11fdf7f2
TL
10int RGWSI_RADOS::do_start()
11{
494da23a
TL
12 int ret = rados.init_with_context(cct);
13 if (ret < 0) {
14 return ret;
15 }
16 ret = rados.connect();
17 if (ret < 0) {
18 return ret;
11fdf7f2 19 }
11fdf7f2
TL
20 return 0;
21}
22
494da23a 23librados::Rados* RGWSI_RADOS::get_rados_handle()
11fdf7f2 24{
494da23a 25 return &rados;
11fdf7f2
TL
26}
27
28uint64_t RGWSI_RADOS::instance_id()
29{
494da23a 30 return get_rados_handle()->get_instance_id();
11fdf7f2
TL
31}
32
494da23a 33int RGWSI_RADOS::open_pool_ctx(const rgw_pool& pool, librados::IoCtx& io_ctx)
11fdf7f2
TL
34{
35 constexpr bool create = true; // create the pool if it doesn't exist
494da23a 36 return rgw_init_ioctx(get_rados_handle(), pool, io_ctx, create);
11fdf7f2
TL
37}
38
39int RGWSI_RADOS::pool_iterate(librados::IoCtx& io_ctx,
40 librados::NObjectIterator& iter,
41 uint32_t num, vector<rgw_bucket_dir_entry>& objs,
42 RGWAccessListFilter *filter,
43 bool *is_truncated)
44{
45 if (iter == io_ctx.nobjects_end())
46 return -ENOENT;
47
48 uint32_t i;
49
50 for (i = 0; i < num && iter != io_ctx.nobjects_end(); ++i, ++iter) {
51 rgw_bucket_dir_entry e;
52
53 string oid = iter->get_oid();
54 ldout(cct, 20) << "RGWRados::pool_iterate: got " << oid << dendl;
55
56 // fill it in with initial values; we may correct later
57 if (filter && !filter->filter(oid, oid))
58 continue;
59
60 e.key = oid;
61 objs.push_back(e);
62 }
63
64 if (is_truncated)
65 *is_truncated = (iter != io_ctx.nobjects_end());
66
67 return objs.size();
68}
69
70void RGWSI_RADOS::Obj::init(const rgw_raw_obj& obj)
71{
72 ref.obj = obj;
73}
74
75int RGWSI_RADOS::Obj::open()
76{
494da23a 77 int r = rados_svc->open_pool_ctx(ref.obj.pool, ref.ioctx);
11fdf7f2
TL
78 if (r < 0) {
79 return r;
80 }
81
82 ref.ioctx.locator_set_key(ref.obj.loc);
83
84 return 0;
85}
86
87int RGWSI_RADOS::Obj::operate(librados::ObjectWriteOperation *op,
88 optional_yield y)
89{
90 return rgw_rados_operate(ref.ioctx, ref.obj.oid, op, y);
91}
92
93int RGWSI_RADOS::Obj::operate(librados::ObjectReadOperation *op, bufferlist *pbl,
94 optional_yield y)
95{
96 return rgw_rados_operate(ref.ioctx, ref.obj.oid, op, pbl, y);
97}
98
99int RGWSI_RADOS::Obj::aio_operate(librados::AioCompletion *c, librados::ObjectWriteOperation *op)
100{
101 return ref.ioctx.aio_operate(ref.obj.oid, c, op);
102}
103
104int RGWSI_RADOS::Obj::aio_operate(librados::AioCompletion *c, librados::ObjectReadOperation *op,
105 bufferlist *pbl)
106{
107 return ref.ioctx.aio_operate(ref.obj.oid, c, op, pbl);
108}
109
110int RGWSI_RADOS::Obj::watch(uint64_t *handle, librados::WatchCtx2 *ctx)
111{
112 return ref.ioctx.watch2(ref.obj.oid, handle, ctx);
113}
114
115int RGWSI_RADOS::Obj::aio_watch(librados::AioCompletion *c, uint64_t *handle, librados::WatchCtx2 *ctx)
116{
117 return ref.ioctx.aio_watch(ref.obj.oid, c, handle, ctx);
118}
119
120int RGWSI_RADOS::Obj::unwatch(uint64_t handle)
121{
122 return ref.ioctx.unwatch2(handle);
123}
124
125int RGWSI_RADOS::Obj::notify(bufferlist& bl,
126 uint64_t timeout_ms,
127 bufferlist *pbl)
128{
129 return ref.ioctx.notify2(ref.obj.oid, bl, timeout_ms, pbl);
130}
131
132void RGWSI_RADOS::Obj::notify_ack(uint64_t notify_id,
133 uint64_t cookie,
134 bufferlist& bl)
135{
136 ref.ioctx.notify_ack(ref.obj.oid, notify_id, cookie, bl);
137}
138
139uint64_t RGWSI_RADOS::Obj::get_last_version()
140{
141 return ref.ioctx.get_last_version();
142}
143
144int RGWSI_RADOS::Pool::create()
145{
494da23a 146 librados::Rados *rad = rados_svc->get_rados_handle();
11fdf7f2
TL
147 int r = rad->pool_create(pool.name.c_str());
148 if (r < 0) {
149 ldout(rados_svc->cct, 0) << "WARNING: pool_create returned " << r << dendl;
150 return r;
151 }
152 librados::IoCtx io_ctx;
153 r = rad->ioctx_create(pool.name.c_str(), io_ctx);
154 if (r < 0) {
155 ldout(rados_svc->cct, 0) << "WARNING: ioctx_create returned " << r << dendl;
156 return r;
157 }
158 r = io_ctx.application_enable(pg_pool_t::APPLICATION_NAME_RGW, false);
159 if (r < 0) {
160 ldout(rados_svc->cct, 0) << "WARNING: application_enable returned " << r << dendl;
161 return r;
162 }
163 return 0;
164}
165
166int RGWSI_RADOS::Pool::create(const vector<rgw_pool>& pools, vector<int> *retcodes)
167{
168 vector<librados::PoolAsyncCompletion *> completions;
169 vector<int> rets;
170
494da23a 171 librados::Rados *rad = rados_svc->get_rados_handle();
11fdf7f2
TL
172 for (auto iter = pools.begin(); iter != pools.end(); ++iter) {
173 librados::PoolAsyncCompletion *c = librados::Rados::pool_async_create_completion();
174 completions.push_back(c);
175 auto& pool = *iter;
176 int ret = rad->pool_create_async(pool.name.c_str(), c);
177 rets.push_back(ret);
178 }
179
180 vector<int>::iterator riter;
181 vector<librados::PoolAsyncCompletion *>::iterator citer;
182
183 bool error = false;
184 ceph_assert(rets.size() == completions.size());
185 for (riter = rets.begin(), citer = completions.begin(); riter != rets.end(); ++riter, ++citer) {
186 int r = *riter;
187 librados::PoolAsyncCompletion *c = *citer;
188 if (r == 0) {
189 c->wait();
190 r = c->get_return_value();
191 if (r < 0) {
192 ldout(rados_svc->cct, 0) << "WARNING: async pool_create returned " << r << dendl;
193 error = true;
194 }
195 }
196 c->release();
197 retcodes->push_back(r);
198 }
199 if (error) {
200 return 0;
201 }
202
203 std::vector<librados::IoCtx> io_ctxs;
204 retcodes->clear();
205 for (auto pool : pools) {
206 io_ctxs.emplace_back();
207 int ret = rad->ioctx_create(pool.name.c_str(), io_ctxs.back());
208 if (ret < 0) {
209 ldout(rados_svc->cct, 0) << "WARNING: ioctx_create returned " << ret << dendl;
210 error = true;
211 }
212 retcodes->push_back(ret);
213 }
214 if (error) {
215 return 0;
216 }
217
218 completions.clear();
219 for (auto &io_ctx : io_ctxs) {
220 librados::PoolAsyncCompletion *c =
221 librados::Rados::pool_async_create_completion();
222 completions.push_back(c);
223 int ret = io_ctx.application_enable_async(pg_pool_t::APPLICATION_NAME_RGW,
224 false, c);
225 ceph_assert(ret == 0);
226 }
227
228 retcodes->clear();
229 for (auto c : completions) {
230 c->wait();
231 int ret = c->get_return_value();
232 if (ret == -EOPNOTSUPP) {
233 ret = 0;
234 } else if (ret < 0) {
235 ldout(rados_svc->cct, 0) << "WARNING: async application_enable returned " << ret
236 << dendl;
237 error = true;
238 }
239 c->release();
240 retcodes->push_back(ret);
241 }
242 return 0;
243}
244
245int RGWSI_RADOS::Pool::lookup()
246{
494da23a 247 librados::Rados *rad = rados_svc->get_rados_handle();
11fdf7f2
TL
248 int ret = rad->pool_lookup(pool.name.c_str());
249 if (ret < 0) {
250 return ret;
251 }
252
253 return 0;
254}
255
256int RGWSI_RADOS::Pool::List::init(const string& marker, RGWAccessListFilter *filter)
257{
258 if (ctx.initialized) {
259 return -EINVAL;
260 }
261
494da23a 262 int r = pool.rados_svc->open_pool_ctx(pool.pool, ctx.ioctx);
11fdf7f2
TL
263 if (r < 0) {
264 return r;
265 }
266
267 librados::ObjectCursor oc;
268 if (!oc.from_str(marker)) {
269 ldout(pool.rados_svc->cct, 10) << "failed to parse cursor: " << marker << dendl;
270 return -EINVAL;
271 }
272
273 ctx.iter = ctx.ioctx.nobjects_begin(oc);
274 ctx.filter = filter;
275 ctx.initialized = true;
276
277 return 0;
278}
279
280int RGWSI_RADOS::Pool::List::get_next(int max,
281 std::list<string> *oids,
282 bool *is_truncated)
283{
284 if (!ctx.initialized) {
285 return -EINVAL;
286 }
287 vector<rgw_bucket_dir_entry> objs;
288 int r = pool.rados_svc->pool_iterate(ctx.ioctx, ctx.iter, max, objs, ctx.filter, is_truncated);
289 if (r < 0) {
290 if(r != -ENOENT) {
291 ldout(pool.rados_svc->cct, 10) << "failed to list objects pool_iterate returned r=" << r << dendl;
292 }
293 return r;
294 }
295
296 vector<rgw_bucket_dir_entry>::iterator iter;
297 for (auto& o : objs) {
298 oids->push_back(o.key.name);
299 }
300
301 return oids->size();
302}
303
304int RGWSI_RADOS::Handle::watch_flush()
305{
494da23a 306 librados::Rados *rad = rados_svc->get_rados_handle();
11fdf7f2
TL
307 return rad->watch_flush();
308}