]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/TrashWatcher.cc
Import ceph 15.2.8
[ceph.git] / ceph / src / librbd / TrashWatcher.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "librbd/TrashWatcher.h"
5 #include "include/rbd_types.h"
6 #include "include/rados/librados.hpp"
7 #include "common/errno.h"
8 #include "librbd/Utils.h"
9 #include "librbd/watcher/Utils.h"
10
11 #define dout_subsys ceph_subsys_rbd
12 #undef dout_prefix
13 #define dout_prefix *_dout << "librbd::TrashWatcher: " << __func__ << ": "
14
15 namespace librbd {
16
17 using namespace trash_watcher;
18 using namespace watcher;
19
20 using librbd::util::create_rados_callback;
21
22 namespace {
23
24 static const uint64_t NOTIFY_TIMEOUT_MS = 5000;
25
26 } // anonymous namespace
27
28 template <typename I>
29 TrashWatcher<I>::TrashWatcher(librados::IoCtx &io_ctx, ContextWQ *work_queue)
30 : Watcher(io_ctx, work_queue, RBD_TRASH) {
31 }
32
33 template <typename I>
34 void TrashWatcher<I>::notify_image_added(
35 librados::IoCtx &io_ctx, const std::string& image_id,
36 const cls::rbd::TrashImageSpec& trash_image_spec, Context *on_finish) {
37 CephContext *cct = reinterpret_cast<CephContext*>(io_ctx.cct());
38 ldout(cct, 20) << dendl;
39
40 bufferlist bl;
41 encode(NotifyMessage{ImageAddedPayload{image_id, trash_image_spec}}, bl);
42
43 librados::AioCompletion *comp = create_rados_callback(on_finish);
44 int r = io_ctx.aio_notify(RBD_TRASH, comp, bl, NOTIFY_TIMEOUT_MS, nullptr);
45 ceph_assert(r == 0);
46 comp->release();
47 }
48
49 template <typename I>
50 void TrashWatcher<I>::notify_image_removed(librados::IoCtx &io_ctx,
51 const std::string& image_id,
52 Context *on_finish) {
53 CephContext *cct = reinterpret_cast<CephContext*>(io_ctx.cct());
54 ldout(cct, 20) << dendl;
55
56 bufferlist bl;
57 encode(NotifyMessage{ImageRemovedPayload{image_id}}, bl);
58
59 librados::AioCompletion *comp = create_rados_callback(on_finish);
60 int r = io_ctx.aio_notify(RBD_TRASH, comp, bl, NOTIFY_TIMEOUT_MS, nullptr);
61 ceph_assert(r == 0);
62 comp->release();
63 }
64
65 template <typename I>
66 void TrashWatcher<I>::handle_notify(uint64_t notify_id, uint64_t handle,
67 uint64_t notifier_id, bufferlist &bl) {
68 CephContext *cct = this->m_cct;
69 ldout(cct, 15) << "notify_id=" << notify_id << ", "
70 << "handle=" << handle << dendl;
71
72
73 NotifyMessage notify_message;
74 try {
75 auto iter = bl.cbegin();
76 decode(notify_message, iter);
77 } catch (const buffer::error &err) {
78 lderr(cct) << "error decoding image notification: " << err.what()
79 << dendl;
80 Context *ctx = new C_NotifyAck(this, notify_id, handle);
81 ctx->complete(0);
82 return;
83 }
84
85 apply_visitor(watcher::util::HandlePayloadVisitor<TrashWatcher<I>>(
86 this, notify_id, handle), notify_message.payload);
87 }
88
89 template <typename I>
90 bool TrashWatcher<I>::handle_payload(const ImageAddedPayload &payload,
91 Context *on_notify_ack) {
92 CephContext *cct = this->m_cct;
93 ldout(cct, 20) << dendl;
94 handle_image_added(payload.image_id, payload.trash_image_spec);
95 return true;
96 }
97
98 template <typename I>
99 bool TrashWatcher<I>::handle_payload(const ImageRemovedPayload &payload,
100 Context *on_notify_ack) {
101 CephContext *cct = this->m_cct;
102 ldout(cct, 20) << dendl;
103 handle_image_removed(payload.image_id);
104 return true;
105 }
106
107 template <typename I>
108 bool TrashWatcher<I>::handle_payload(const UnknownPayload &payload,
109 Context *on_notify_ack) {
110 return true;
111 }
112
113 } // namespace librbd
114
115 template class librbd::TrashWatcher<librbd::ImageCtx>;