]>
Commit | Line | Data |
---|---|---|
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 |
10 | int 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 | 23 | librados::Rados* RGWSI_RADOS::get_rados_handle() |
11fdf7f2 | 24 | { |
494da23a | 25 | return &rados; |
11fdf7f2 TL |
26 | } |
27 | ||
28 | uint64_t RGWSI_RADOS::instance_id() | |
29 | { | |
494da23a | 30 | return get_rados_handle()->get_instance_id(); |
11fdf7f2 TL |
31 | } |
32 | ||
494da23a | 33 | int 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 | ||
39 | int 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 | ||
70 | void RGWSI_RADOS::Obj::init(const rgw_raw_obj& obj) | |
71 | { | |
72 | ref.obj = obj; | |
73 | } | |
74 | ||
75 | int 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 | ||
87 | int 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 | ||
93 | int 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 | ||
99 | int 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 | ||
104 | int 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 | ||
110 | int RGWSI_RADOS::Obj::watch(uint64_t *handle, librados::WatchCtx2 *ctx) | |
111 | { | |
112 | return ref.ioctx.watch2(ref.obj.oid, handle, ctx); | |
113 | } | |
114 | ||
115 | int 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 | ||
120 | int RGWSI_RADOS::Obj::unwatch(uint64_t handle) | |
121 | { | |
122 | return ref.ioctx.unwatch2(handle); | |
123 | } | |
124 | ||
125 | int 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 | ||
132 | void 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 | ||
139 | uint64_t RGWSI_RADOS::Obj::get_last_version() | |
140 | { | |
141 | return ref.ioctx.get_last_version(); | |
142 | } | |
143 | ||
144 | int 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 | ||
166 | int 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 | ||
245 | int 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 | ||
256 | int 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 | ||
280 | int 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 | ||
304 | int RGWSI_RADOS::Handle::watch_flush() | |
305 | { | |
494da23a | 306 | librados::Rados *rad = rados_svc->get_rados_handle(); |
11fdf7f2 TL |
307 | return rad->watch_flush(); |
308 | } |