]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "Types.h" | |
5 | #include "include/assert.h" | |
6 | #include "include/stringify.h" | |
7 | #include "common/Formatter.h" | |
8 | ||
9 | namespace rbd { | |
10 | namespace mirror { | |
11 | namespace leader_watcher { | |
12 | ||
13 | namespace { | |
14 | ||
15 | class EncodePayloadVisitor : public boost::static_visitor<void> { | |
16 | public: | |
17 | explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) {} | |
18 | ||
19 | template <typename Payload> | |
20 | inline void operator()(const Payload &payload) const { | |
21 | ::encode(static_cast<uint32_t>(Payload::NOTIFY_OP), m_bl); | |
22 | payload.encode(m_bl); | |
23 | } | |
24 | ||
25 | private: | |
26 | bufferlist &m_bl; | |
27 | }; | |
28 | ||
29 | class DecodePayloadVisitor : public boost::static_visitor<void> { | |
30 | public: | |
31 | DecodePayloadVisitor(__u8 version, bufferlist::iterator &iter) | |
32 | : m_version(version), m_iter(iter) {} | |
33 | ||
34 | template <typename Payload> | |
35 | inline void operator()(Payload &payload) const { | |
36 | payload.decode(m_version, m_iter); | |
37 | } | |
38 | ||
39 | private: | |
40 | __u8 m_version; | |
41 | bufferlist::iterator &m_iter; | |
42 | }; | |
43 | ||
44 | class DumpPayloadVisitor : public boost::static_visitor<void> { | |
45 | public: | |
46 | explicit DumpPayloadVisitor(Formatter *formatter) : m_formatter(formatter) {} | |
47 | ||
48 | template <typename Payload> | |
49 | inline void operator()(const Payload &payload) const { | |
50 | NotifyOp notify_op = Payload::NOTIFY_OP; | |
51 | m_formatter->dump_string("notify_op", stringify(notify_op)); | |
52 | payload.dump(m_formatter); | |
53 | } | |
54 | ||
55 | private: | |
56 | ceph::Formatter *m_formatter; | |
57 | }; | |
58 | ||
59 | } // anonymous namespace | |
60 | ||
61 | void HeartbeatPayload::encode(bufferlist &bl) const { | |
62 | } | |
63 | ||
64 | void HeartbeatPayload::decode(__u8 version, bufferlist::iterator &iter) { | |
65 | } | |
66 | ||
67 | void HeartbeatPayload::dump(Formatter *f) const { | |
68 | } | |
69 | ||
70 | void LockAcquiredPayload::encode(bufferlist &bl) const { | |
71 | } | |
72 | ||
73 | void LockAcquiredPayload::decode(__u8 version, bufferlist::iterator &iter) { | |
74 | } | |
75 | ||
76 | void LockAcquiredPayload::dump(Formatter *f) const { | |
77 | } | |
78 | ||
79 | void LockReleasedPayload::encode(bufferlist &bl) const { | |
80 | } | |
81 | ||
82 | void LockReleasedPayload::decode(__u8 version, bufferlist::iterator &iter) { | |
83 | } | |
84 | ||
85 | void LockReleasedPayload::dump(Formatter *f) const { | |
86 | } | |
87 | ||
88 | void UnknownPayload::encode(bufferlist &bl) const { | |
89 | assert(false); | |
90 | } | |
91 | ||
92 | void UnknownPayload::decode(__u8 version, bufferlist::iterator &iter) { | |
93 | } | |
94 | ||
95 | void UnknownPayload::dump(Formatter *f) const { | |
96 | } | |
97 | ||
98 | void NotifyMessage::encode(bufferlist& bl) const { | |
99 | ENCODE_START(1, 1, bl); | |
100 | boost::apply_visitor(EncodePayloadVisitor(bl), payload); | |
101 | ENCODE_FINISH(bl); | |
102 | } | |
103 | ||
104 | void NotifyMessage::decode(bufferlist::iterator& iter) { | |
105 | DECODE_START(1, iter); | |
106 | ||
107 | uint32_t notify_op; | |
108 | ::decode(notify_op, iter); | |
109 | ||
110 | // select the correct payload variant based upon the encoded op | |
111 | switch (notify_op) { | |
112 | case NOTIFY_OP_HEARTBEAT: | |
113 | payload = HeartbeatPayload(); | |
114 | break; | |
115 | case NOTIFY_OP_LOCK_ACQUIRED: | |
116 | payload = LockAcquiredPayload(); | |
117 | break; | |
118 | case NOTIFY_OP_LOCK_RELEASED: | |
119 | payload = LockReleasedPayload(); | |
120 | break; | |
121 | default: | |
122 | payload = UnknownPayload(); | |
123 | break; | |
124 | } | |
125 | ||
126 | apply_visitor(DecodePayloadVisitor(struct_v, iter), payload); | |
127 | DECODE_FINISH(iter); | |
128 | } | |
129 | ||
130 | void NotifyMessage::dump(Formatter *f) const { | |
131 | apply_visitor(DumpPayloadVisitor(f), payload); | |
132 | } | |
133 | ||
134 | void NotifyMessage::generate_test_instances(std::list<NotifyMessage *> &o) { | |
135 | o.push_back(new NotifyMessage(HeartbeatPayload())); | |
136 | o.push_back(new NotifyMessage(LockAcquiredPayload())); | |
137 | o.push_back(new NotifyMessage(LockReleasedPayload())); | |
138 | } | |
139 | ||
140 | std::ostream &operator<<(std::ostream &out, const NotifyOp &op) { | |
141 | switch (op) { | |
142 | case NOTIFY_OP_HEARTBEAT: | |
143 | out << "Heartbeat"; | |
144 | break; | |
145 | case NOTIFY_OP_LOCK_ACQUIRED: | |
146 | out << "LockAcquired"; | |
147 | break; | |
148 | case NOTIFY_OP_LOCK_RELEASED: | |
149 | out << "LockReleased"; | |
150 | break; | |
151 | default: | |
152 | out << "Unknown (" << static_cast<uint32_t>(op) << ")"; | |
153 | break; | |
154 | } | |
155 | return out; | |
156 | } | |
157 | ||
158 | } // namespace leader_watcher | |
159 | } // namespace mirror | |
160 | } // namespace librbd |