]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | |
2 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | |
3 | // vim: ts=8 sw=2 smarttab ft=cpp | |
4 | ||
5 | #include "common/admin_socket.h" | |
6 | ||
11fdf7f2 TL |
7 | #include "svc_sys_obj_cache.h" |
8 | #include "svc_zone.h" | |
9 | #include "svc_notify.h" | |
10 | ||
11 | #include "rgw/rgw_zone.h" | |
12 | #include "rgw/rgw_tools.h" | |
13 | ||
14 | #define dout_subsys ceph_subsys_rgw | |
15 | ||
16 | class RGWSI_SysObj_Cache_CB : public RGWSI_Notify::CB | |
17 | { | |
18 | RGWSI_SysObj_Cache *svc; | |
19 | public: | |
20 | RGWSI_SysObj_Cache_CB(RGWSI_SysObj_Cache *_svc) : svc(_svc) {} | |
21 | int watch_cb(uint64_t notify_id, | |
22 | uint64_t cookie, | |
23 | uint64_t notifier_id, | |
24 | bufferlist& bl) { | |
25 | return svc->watch_cb(notify_id, cookie, notifier_id, bl); | |
26 | } | |
27 | ||
28 | void set_enabled(bool status) { | |
29 | svc->set_enabled(status); | |
30 | } | |
31 | }; | |
32 | ||
33 | int RGWSI_SysObj_Cache::do_start() | |
34 | { | |
9f95a23c TL |
35 | int r = asocket.start(); |
36 | if (r < 0) { | |
37 | return r; | |
38 | } | |
39 | ||
40 | r = RGWSI_SysObj_Core::do_start(); | |
11fdf7f2 TL |
41 | if (r < 0) { |
42 | return r; | |
43 | } | |
44 | ||
45 | r = notify_svc->start(); | |
46 | if (r < 0) { | |
47 | return r; | |
48 | } | |
49 | ||
50 | assert(notify_svc->is_started()); | |
51 | ||
52 | cb.reset(new RGWSI_SysObj_Cache_CB(this)); | |
53 | ||
54 | notify_svc->register_watch_cb(cb.get()); | |
55 | ||
56 | return 0; | |
57 | } | |
58 | ||
9f95a23c TL |
59 | void RGWSI_SysObj_Cache::shutdown() |
60 | { | |
61 | asocket.shutdown(); | |
62 | RGWSI_SysObj_Core::shutdown(); | |
63 | } | |
64 | ||
11fdf7f2 TL |
65 | static string normal_name(rgw_pool& pool, const std::string& oid) { |
66 | std::string buf; | |
67 | buf.reserve(pool.name.size() + pool.ns.size() + oid.size() + 2); | |
68 | buf.append(pool.name).append("+").append(pool.ns).append("+").append(oid); | |
69 | return buf; | |
70 | } | |
71 | ||
72 | void RGWSI_SysObj_Cache::normalize_pool_and_obj(const rgw_pool& src_pool, const string& src_obj, rgw_pool& dst_pool, string& dst_obj) | |
73 | { | |
74 | if (src_obj.size()) { | |
75 | dst_pool = src_pool; | |
76 | dst_obj = src_obj; | |
77 | } else { | |
78 | dst_pool = zone_svc->get_zone_params().domain_root; | |
79 | dst_obj = src_pool.name; | |
80 | } | |
81 | } | |
82 | ||
83 | ||
84 | int RGWSI_SysObj_Cache::remove(RGWSysObjectCtxBase& obj_ctx, | |
85 | RGWObjVersionTracker *objv_tracker, | |
9f95a23c TL |
86 | const rgw_raw_obj& obj, |
87 | optional_yield y) | |
11fdf7f2 TL |
88 | |
89 | { | |
90 | rgw_pool pool; | |
91 | string oid; | |
92 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
93 | ||
94 | string name = normal_name(pool, oid); | |
95 | cache.remove(name); | |
96 | ||
97 | ObjectCacheInfo info; | |
9f95a23c | 98 | int r = distribute_cache(name, obj, info, REMOVE_OBJ, y); |
11fdf7f2 TL |
99 | if (r < 0) { |
100 | ldout(cct, 0) << "ERROR: " << __func__ << "(): failed to distribute cache: r=" << r << dendl; | |
101 | } | |
102 | ||
9f95a23c | 103 | return RGWSI_SysObj_Core::remove(obj_ctx, objv_tracker, obj, y); |
11fdf7f2 TL |
104 | } |
105 | ||
106 | int RGWSI_SysObj_Cache::read(RGWSysObjectCtxBase& obj_ctx, | |
9f95a23c | 107 | RGWSI_SysObj_Obj_GetObjState& read_state, |
11fdf7f2 TL |
108 | RGWObjVersionTracker *objv_tracker, |
109 | const rgw_raw_obj& obj, | |
110 | bufferlist *obl, off_t ofs, off_t end, | |
111 | map<string, bufferlist> *attrs, | |
112 | bool raw_attrs, | |
113 | rgw_cache_entry_info *cache_info, | |
9f95a23c TL |
114 | boost::optional<obj_version> refresh_version, |
115 | optional_yield y) | |
11fdf7f2 TL |
116 | { |
117 | rgw_pool pool; | |
118 | string oid; | |
119 | if (ofs != 0) { | |
120 | return RGWSI_SysObj_Core::read(obj_ctx, read_state, objv_tracker, | |
9f95a23c TL |
121 | obj, obl, ofs, end, attrs, raw_attrs, |
122 | cache_info, refresh_version, y); | |
11fdf7f2 TL |
123 | } |
124 | ||
125 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
126 | string name = normal_name(pool, oid); | |
127 | ||
128 | ObjectCacheInfo info; | |
129 | ||
130 | uint32_t flags = (end != 0 ? CACHE_FLAG_DATA : 0); | |
131 | if (objv_tracker) | |
132 | flags |= CACHE_FLAG_OBJV; | |
133 | if (attrs) | |
134 | flags |= CACHE_FLAG_XATTRS; | |
f6b5b4d7 TL |
135 | |
136 | int r = cache.get(name, info, flags, cache_info); | |
137 | if (r == 0 && | |
11fdf7f2 TL |
138 | (!refresh_version || !info.version.compare(&(*refresh_version)))) { |
139 | if (info.status < 0) | |
140 | return info.status; | |
141 | ||
142 | bufferlist& bl = info.data; | |
143 | ||
144 | bufferlist::iterator i = bl.begin(); | |
145 | ||
146 | obl->clear(); | |
147 | ||
148 | i.copy_all(*obl); | |
149 | if (objv_tracker) | |
150 | objv_tracker->read_version = info.version; | |
151 | if (attrs) { | |
152 | if (raw_attrs) { | |
153 | *attrs = info.xattrs; | |
154 | } else { | |
155 | rgw_filter_attrset(info.xattrs, RGW_ATTR_PREFIX, attrs); | |
156 | } | |
157 | } | |
158 | return obl->length(); | |
159 | } | |
f6b5b4d7 TL |
160 | if(r == -ENODATA) |
161 | return -ENOENT; | |
11fdf7f2 TL |
162 | |
163 | map<string, bufferlist> unfiltered_attrset; | |
f6b5b4d7 | 164 | r = RGWSI_SysObj_Core::read(obj_ctx, read_state, objv_tracker, |
11fdf7f2 TL |
165 | obj, obl, ofs, end, |
166 | (attrs ? &unfiltered_attrset : nullptr), | |
167 | true, /* cache unfiltered attrs */ | |
168 | cache_info, | |
9f95a23c | 169 | refresh_version, y); |
11fdf7f2 TL |
170 | if (r < 0) { |
171 | if (r == -ENOENT) { // only update ENOENT, we'd rather retry other errors | |
172 | info.status = r; | |
173 | cache.put(name, info, cache_info); | |
174 | } | |
175 | return r; | |
176 | } | |
177 | ||
178 | if (obl->length() == end + 1) { | |
179 | /* in this case, most likely object contains more data, we can't cache it */ | |
180 | flags &= ~CACHE_FLAG_DATA; | |
181 | } else { | |
182 | bufferptr p(r); | |
183 | bufferlist& bl = info.data; | |
184 | bl.clear(); | |
185 | bufferlist::iterator o = obl->begin(); | |
186 | o.copy_all(bl); | |
187 | } | |
188 | ||
189 | info.status = 0; | |
190 | info.flags = flags; | |
191 | if (objv_tracker) { | |
192 | info.version = objv_tracker->read_version; | |
193 | } | |
194 | if (attrs) { | |
195 | info.xattrs = std::move(unfiltered_attrset); | |
196 | if (raw_attrs) { | |
197 | *attrs = info.xattrs; | |
198 | } else { | |
199 | rgw_filter_attrset(info.xattrs, RGW_ATTR_PREFIX, attrs); | |
200 | } | |
201 | } | |
202 | cache.put(name, info, cache_info); | |
203 | return r; | |
204 | } | |
205 | ||
206 | int RGWSI_SysObj_Cache::get_attr(const rgw_raw_obj& obj, | |
9f95a23c TL |
207 | const char *attr_name, |
208 | bufferlist *dest, | |
209 | optional_yield y) | |
11fdf7f2 TL |
210 | { |
211 | rgw_pool pool; | |
212 | string oid; | |
213 | ||
214 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
215 | string name = normal_name(pool, oid); | |
216 | ||
217 | ObjectCacheInfo info; | |
218 | ||
219 | uint32_t flags = CACHE_FLAG_XATTRS; | |
220 | ||
f6b5b4d7 TL |
221 | int r = cache.get(name, info, flags, nullptr); |
222 | if (r == 0) { | |
11fdf7f2 TL |
223 | if (info.status < 0) |
224 | return info.status; | |
225 | ||
226 | auto iter = info.xattrs.find(attr_name); | |
227 | if (iter == info.xattrs.end()) { | |
228 | return -ENODATA; | |
229 | } | |
230 | ||
231 | *dest = iter->second; | |
232 | return dest->length(); | |
f6b5b4d7 TL |
233 | } else if (r == -ENODATA) { |
234 | return -ENOENT; | |
11fdf7f2 TL |
235 | } |
236 | /* don't try to cache this one */ | |
9f95a23c | 237 | return RGWSI_SysObj_Core::get_attr(obj, attr_name, dest, y); |
11fdf7f2 TL |
238 | } |
239 | ||
240 | int RGWSI_SysObj_Cache::set_attrs(const rgw_raw_obj& obj, | |
241 | map<string, bufferlist>& attrs, | |
242 | map<string, bufferlist> *rmattrs, | |
9f95a23c TL |
243 | RGWObjVersionTracker *objv_tracker, |
244 | optional_yield y) | |
11fdf7f2 TL |
245 | { |
246 | rgw_pool pool; | |
247 | string oid; | |
248 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
249 | ObjectCacheInfo info; | |
250 | info.xattrs = attrs; | |
251 | if (rmattrs) { | |
252 | info.rm_xattrs = *rmattrs; | |
253 | } | |
254 | info.status = 0; | |
255 | info.flags = CACHE_FLAG_MODIFY_XATTRS; | |
256 | if (objv_tracker) { | |
257 | info.version = objv_tracker->write_version; | |
258 | info.flags |= CACHE_FLAG_OBJV; | |
259 | } | |
9f95a23c | 260 | int ret = RGWSI_SysObj_Core::set_attrs(obj, attrs, rmattrs, objv_tracker, y); |
11fdf7f2 TL |
261 | string name = normal_name(pool, oid); |
262 | if (ret >= 0) { | |
263 | cache.put(name, info, NULL); | |
9f95a23c | 264 | int r = distribute_cache(name, obj, info, UPDATE_OBJ, y); |
11fdf7f2 TL |
265 | if (r < 0) |
266 | ldout(cct, 0) << "ERROR: failed to distribute cache for " << obj << dendl; | |
267 | } else { | |
268 | cache.remove(name); | |
269 | } | |
270 | ||
271 | return ret; | |
272 | } | |
273 | ||
274 | int RGWSI_SysObj_Cache::write(const rgw_raw_obj& obj, | |
275 | real_time *pmtime, | |
276 | map<std::string, bufferlist>& attrs, | |
277 | bool exclusive, | |
278 | const bufferlist& data, | |
279 | RGWObjVersionTracker *objv_tracker, | |
9f95a23c TL |
280 | real_time set_mtime, |
281 | optional_yield y) | |
11fdf7f2 TL |
282 | { |
283 | rgw_pool pool; | |
284 | string oid; | |
285 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
286 | ObjectCacheInfo info; | |
287 | info.xattrs = attrs; | |
288 | info.status = 0; | |
289 | info.data = data; | |
290 | info.flags = CACHE_FLAG_XATTRS | CACHE_FLAG_DATA | CACHE_FLAG_META; | |
291 | if (objv_tracker) { | |
292 | info.version = objv_tracker->write_version; | |
293 | info.flags |= CACHE_FLAG_OBJV; | |
294 | } | |
295 | ceph::real_time result_mtime; | |
296 | int ret = RGWSI_SysObj_Core::write(obj, &result_mtime, attrs, | |
9f95a23c TL |
297 | exclusive, data, |
298 | objv_tracker, set_mtime, y); | |
11fdf7f2 TL |
299 | if (pmtime) { |
300 | *pmtime = result_mtime; | |
301 | } | |
302 | info.meta.mtime = result_mtime; | |
303 | info.meta.size = data.length(); | |
304 | string name = normal_name(pool, oid); | |
305 | if (ret >= 0) { | |
306 | cache.put(name, info, NULL); | |
307 | // Only distribute the cache information if we did not just create | |
308 | // the object with the exclusive flag. Note: PUT_OBJ_EXCL implies | |
309 | // PUT_OBJ_CREATE. Generally speaking, when successfully creating | |
310 | // a system object with the exclusive flag it is not necessary to | |
311 | // call distribute_cache, as a) it's unclear whether other RGWs | |
312 | // will need that system object in the near-term and b) it | |
313 | // generates additional network traffic. | |
314 | if (!exclusive) { | |
9f95a23c | 315 | int r = distribute_cache(name, obj, info, UPDATE_OBJ, y); |
11fdf7f2 TL |
316 | if (r < 0) |
317 | ldout(cct, 0) << "ERROR: failed to distribute cache for " << obj << dendl; | |
318 | } | |
319 | } else { | |
320 | cache.remove(name); | |
321 | } | |
322 | ||
323 | return ret; | |
324 | } | |
325 | ||
326 | int RGWSI_SysObj_Cache::write_data(const rgw_raw_obj& obj, | |
327 | const bufferlist& data, | |
328 | bool exclusive, | |
9f95a23c TL |
329 | RGWObjVersionTracker *objv_tracker, |
330 | optional_yield y) | |
11fdf7f2 TL |
331 | { |
332 | rgw_pool pool; | |
333 | string oid; | |
334 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
335 | ||
336 | ObjectCacheInfo info; | |
337 | info.data = data; | |
338 | info.meta.size = data.length(); | |
339 | info.status = 0; | |
340 | info.flags = CACHE_FLAG_DATA; | |
341 | ||
342 | if (objv_tracker) { | |
343 | info.version = objv_tracker->write_version; | |
344 | info.flags |= CACHE_FLAG_OBJV; | |
345 | } | |
9f95a23c | 346 | int ret = RGWSI_SysObj_Core::write_data(obj, data, exclusive, objv_tracker, y); |
11fdf7f2 TL |
347 | string name = normal_name(pool, oid); |
348 | if (ret >= 0) { | |
349 | cache.put(name, info, NULL); | |
9f95a23c | 350 | int r = distribute_cache(name, obj, info, UPDATE_OBJ, y); |
11fdf7f2 TL |
351 | if (r < 0) |
352 | ldout(cct, 0) << "ERROR: failed to distribute cache for " << obj << dendl; | |
353 | } else { | |
354 | cache.remove(name); | |
355 | } | |
356 | ||
357 | return ret; | |
358 | } | |
359 | ||
360 | int RGWSI_SysObj_Cache::raw_stat(const rgw_raw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *pepoch, | |
361 | map<string, bufferlist> *attrs, bufferlist *first_chunk, | |
9f95a23c TL |
362 | RGWObjVersionTracker *objv_tracker, |
363 | optional_yield y) | |
11fdf7f2 TL |
364 | { |
365 | rgw_pool pool; | |
366 | string oid; | |
367 | normalize_pool_and_obj(obj.pool, obj.oid, pool, oid); | |
368 | ||
369 | string name = normal_name(pool, oid); | |
370 | ||
371 | uint64_t size; | |
372 | real_time mtime; | |
373 | uint64_t epoch; | |
374 | ||
375 | ObjectCacheInfo info; | |
376 | uint32_t flags = CACHE_FLAG_META | CACHE_FLAG_XATTRS; | |
377 | if (objv_tracker) | |
378 | flags |= CACHE_FLAG_OBJV; | |
379 | int r = cache.get(name, info, flags, NULL); | |
380 | if (r == 0) { | |
381 | if (info.status < 0) | |
382 | return info.status; | |
383 | ||
384 | size = info.meta.size; | |
385 | mtime = info.meta.mtime; | |
386 | epoch = info.epoch; | |
387 | if (objv_tracker) | |
388 | objv_tracker->read_version = info.version; | |
389 | goto done; | |
390 | } | |
f6b5b4d7 TL |
391 | if (r == -ENODATA) { |
392 | return -ENOENT; | |
393 | } | |
9f95a23c TL |
394 | r = RGWSI_SysObj_Core::raw_stat(obj, &size, &mtime, &epoch, &info.xattrs, |
395 | first_chunk, objv_tracker, y); | |
11fdf7f2 TL |
396 | if (r < 0) { |
397 | if (r == -ENOENT) { | |
398 | info.status = r; | |
399 | cache.put(name, info, NULL); | |
400 | } | |
401 | return r; | |
402 | } | |
403 | info.status = 0; | |
404 | info.epoch = epoch; | |
405 | info.meta.mtime = mtime; | |
406 | info.meta.size = size; | |
407 | info.flags = CACHE_FLAG_META | CACHE_FLAG_XATTRS; | |
408 | if (objv_tracker) { | |
409 | info.flags |= CACHE_FLAG_OBJV; | |
410 | info.version = objv_tracker->read_version; | |
411 | } | |
412 | cache.put(name, info, NULL); | |
413 | done: | |
414 | if (psize) | |
415 | *psize = size; | |
416 | if (pmtime) | |
417 | *pmtime = mtime; | |
418 | if (pepoch) | |
419 | *pepoch = epoch; | |
420 | if (attrs) | |
421 | *attrs = info.xattrs; | |
422 | return 0; | |
423 | } | |
424 | ||
9f95a23c TL |
425 | int RGWSI_SysObj_Cache::distribute_cache(const string& normal_name, |
426 | const rgw_raw_obj& obj, | |
427 | ObjectCacheInfo& obj_info, int op, | |
428 | optional_yield y) | |
11fdf7f2 TL |
429 | { |
430 | RGWCacheNotifyInfo info; | |
11fdf7f2 | 431 | info.op = op; |
11fdf7f2 TL |
432 | info.obj_info = obj_info; |
433 | info.obj = obj; | |
434 | bufferlist bl; | |
435 | encode(info, bl); | |
9f95a23c | 436 | return notify_svc->distribute(normal_name, bl, y); |
11fdf7f2 TL |
437 | } |
438 | ||
439 | int RGWSI_SysObj_Cache::watch_cb(uint64_t notify_id, | |
440 | uint64_t cookie, | |
441 | uint64_t notifier_id, | |
442 | bufferlist& bl) | |
443 | { | |
444 | RGWCacheNotifyInfo info; | |
445 | ||
446 | try { | |
447 | auto iter = bl.cbegin(); | |
448 | decode(info, iter); | |
449 | } catch (buffer::end_of_buffer& err) { | |
450 | ldout(cct, 0) << "ERROR: got bad notification" << dendl; | |
451 | return -EIO; | |
452 | } catch (buffer::error& err) { | |
453 | ldout(cct, 0) << "ERROR: buffer::error" << dendl; | |
454 | return -EIO; | |
455 | } | |
456 | ||
457 | rgw_pool pool; | |
458 | string oid; | |
459 | normalize_pool_and_obj(info.obj.pool, info.obj.oid, pool, oid); | |
460 | string name = normal_name(pool, oid); | |
461 | ||
462 | switch (info.op) { | |
463 | case UPDATE_OBJ: | |
464 | cache.put(name, info.obj_info, NULL); | |
465 | break; | |
466 | case REMOVE_OBJ: | |
467 | cache.remove(name); | |
468 | break; | |
469 | default: | |
470 | ldout(cct, 0) << "WARNING: got unknown notification op: " << info.op << dendl; | |
471 | return -EINVAL; | |
472 | } | |
473 | ||
474 | return 0; | |
475 | } | |
476 | ||
477 | void RGWSI_SysObj_Cache::set_enabled(bool status) | |
478 | { | |
479 | cache.set_enabled(status); | |
480 | } | |
481 | ||
482 | bool RGWSI_SysObj_Cache::chain_cache_entry(std::initializer_list<rgw_cache_entry_info *> cache_info_entries, | |
483 | RGWChainedCache::Entry *chained_entry) | |
484 | { | |
485 | return cache.chain_cache_entry(cache_info_entries, chained_entry); | |
486 | } | |
487 | ||
488 | void RGWSI_SysObj_Cache::register_chained_cache(RGWChainedCache *cc) | |
489 | { | |
490 | cache.chain_cache(cc); | |
491 | } | |
492 | ||
493 | void RGWSI_SysObj_Cache::unregister_chained_cache(RGWChainedCache *cc) | |
494 | { | |
495 | cache.unchain_cache(cc); | |
496 | } | |
497 | ||
498 | static void cache_list_dump_helper(Formatter* f, | |
499 | const std::string& name, | |
500 | const ceph::real_time mtime, | |
501 | const std::uint64_t size) | |
502 | { | |
503 | f->dump_string("name", name); | |
504 | f->dump_string("mtime", ceph::to_iso_8601(mtime)); | |
505 | f->dump_unsigned("size", size); | |
506 | } | |
507 | ||
9f95a23c TL |
508 | class RGWSI_SysObj_Cache_ASocketHook : public AdminSocketHook { |
509 | RGWSI_SysObj_Cache *svc; | |
510 | ||
511 | static constexpr const char* admin_commands[4][3] = { | |
512 | { "cache list", | |
513 | "cache list name=filter,type=CephString,req=false", | |
514 | "cache list [filter_str]: list object cache, possibly matching substrings" }, | |
515 | { "cache inspect name=target,type=CephString,req=true", | |
516 | "cache inspect target: print cache element" }, | |
517 | { "cache erase name=target,type=CephString,req=true", | |
518 | "cache erase target: erase element from cache" }, | |
519 | { "cache zap", | |
520 | "cache zap: erase all elements from cache" } | |
521 | }; | |
522 | ||
523 | public: | |
524 | RGWSI_SysObj_Cache_ASocketHook(RGWSI_SysObj_Cache *_svc) : svc(_svc) {} | |
525 | ||
526 | int start(); | |
527 | void shutdown(); | |
528 | ||
529 | int call(std::string_view command, const cmdmap_t& cmdmap, | |
530 | Formatter *f, | |
531 | std::ostream& ss, | |
532 | bufferlist& out) override; | |
533 | }; | |
534 | ||
535 | int RGWSI_SysObj_Cache_ASocketHook::start() | |
536 | { | |
537 | auto admin_socket = svc->ctx()->get_admin_socket(); | |
538 | for (auto cmd : admin_commands) { | |
539 | int r = admin_socket->register_command(cmd[0], this, cmd[1]); | |
540 | if (r < 0) { | |
541 | ldout(svc->ctx(), 0) << "ERROR: fail to register admin socket command (r=" << r | |
542 | << ")" << dendl; | |
543 | return r; | |
544 | } | |
545 | } | |
546 | return 0; | |
547 | } | |
548 | ||
549 | void RGWSI_SysObj_Cache_ASocketHook::shutdown() | |
550 | { | |
551 | auto admin_socket = svc->ctx()->get_admin_socket(); | |
552 | admin_socket->unregister_commands(this); | |
553 | } | |
554 | ||
555 | int RGWSI_SysObj_Cache_ASocketHook::call( | |
556 | std::string_view command, const cmdmap_t& cmdmap, | |
557 | Formatter *f, | |
558 | std::ostream& ss, | |
559 | bufferlist& out) | |
560 | { | |
561 | if (command == "cache list"sv) { | |
562 | std::optional<std::string> filter; | |
563 | if (auto i = cmdmap.find("filter"); i != cmdmap.cend()) { | |
564 | filter = boost::get<std::string>(i->second); | |
565 | } | |
566 | f->open_array_section("cache_entries"); | |
567 | svc->asocket.call_list(filter, f); | |
568 | f->close_section(); | |
569 | return 0; | |
570 | } else if (command == "cache inspect"sv) { | |
571 | const auto& target = boost::get<std::string>(cmdmap.at("target")); | |
572 | if (svc->asocket.call_inspect(target, f)) { | |
573 | return 0; | |
574 | } else { | |
575 | ss << "Unable to find entry "s + target + ".\n"; | |
576 | return -ENOENT; | |
577 | } | |
578 | } else if (command == "cache erase"sv) { | |
579 | const auto& target = boost::get<std::string>(cmdmap.at("target")); | |
580 | if (svc->asocket.call_erase(target)) { | |
581 | return 0; | |
582 | } else { | |
583 | ss << "Unable to find entry "s + target + ".\n"; | |
584 | return -ENOENT; | |
585 | } | |
586 | } else if (command == "cache zap"sv) { | |
587 | svc->asocket.call_zap(); | |
588 | return 0; | |
589 | } | |
590 | return -ENOSYS; | |
591 | } | |
592 | ||
593 | RGWSI_SysObj_Cache::ASocketHandler::ASocketHandler(RGWSI_SysObj_Cache *_svc) : svc(_svc) | |
594 | { | |
595 | hook.reset(new RGWSI_SysObj_Cache_ASocketHook(_svc)); | |
596 | } | |
597 | ||
598 | RGWSI_SysObj_Cache::ASocketHandler::~ASocketHandler() | |
599 | { | |
600 | } | |
601 | ||
602 | int RGWSI_SysObj_Cache::ASocketHandler::start() | |
603 | { | |
604 | return hook->start(); | |
605 | } | |
606 | ||
607 | void RGWSI_SysObj_Cache::ASocketHandler::shutdown() | |
608 | { | |
609 | return hook->shutdown(); | |
610 | } | |
611 | ||
612 | void RGWSI_SysObj_Cache::ASocketHandler::call_list(const std::optional<std::string>& filter, Formatter* f) | |
11fdf7f2 | 613 | { |
9f95a23c TL |
614 | svc->cache.for_each( |
615 | [&filter, f] (const string& name, const ObjectCacheEntry& entry) { | |
11fdf7f2 TL |
616 | if (!filter || name.find(*filter) != name.npos) { |
617 | cache_list_dump_helper(f, name, entry.info.meta.mtime, | |
618 | entry.info.meta.size); | |
619 | } | |
620 | }); | |
621 | } | |
622 | ||
9f95a23c | 623 | int RGWSI_SysObj_Cache::ASocketHandler::call_inspect(const std::string& target, Formatter* f) |
11fdf7f2 | 624 | { |
9f95a23c | 625 | if (const auto entry = svc->cache.get(target)) { |
11fdf7f2 TL |
626 | f->open_object_section("cache_entry"); |
627 | f->dump_string("name", target.c_str()); | |
628 | entry->dump(f); | |
629 | f->close_section(); | |
630 | return true; | |
631 | } else { | |
632 | return false; | |
633 | } | |
634 | } | |
635 | ||
9f95a23c | 636 | int RGWSI_SysObj_Cache::ASocketHandler::call_erase(const std::string& target) |
11fdf7f2 | 637 | { |
9f95a23c | 638 | return svc->cache.remove(target); |
11fdf7f2 TL |
639 | } |
640 | ||
9f95a23c | 641 | int RGWSI_SysObj_Cache::ASocketHandler::call_zap() |
11fdf7f2 | 642 | { |
9f95a23c | 643 | svc->cache.invalidate_all(); |
11fdf7f2 TL |
644 | return 0; |
645 | } |