]> git.proxmox.com Git - ceph.git/blame - ceph/src/osd/Watch.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / osd / Watch.h
CommitLineData
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 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14#ifndef CEPH_WATCH_H
15#define CEPH_WATCH_H
16
7c673cae 17#include <set>
11fdf7f2 18#include "msg/Connection.h"
7c673cae
FG
19#include "include/Context.h"
20
21enum WatcherState {
22 WATCHER_PENDING,
23 WATCHER_NOTIFIED,
24};
25
26class OSDService;
27class PrimaryLogPG;
28void intrusive_ptr_add_ref(PrimaryLogPG *pg);
29void intrusive_ptr_release(PrimaryLogPG *pg);
30struct ObjectContext;
31class MWatchNotify;
32
33class Watch;
11fdf7f2
TL
34typedef std::shared_ptr<Watch> WatchRef;
35typedef std::weak_ptr<Watch> WWatchRef;
7c673cae
FG
36
37class Notify;
11fdf7f2
TL
38typedef std::shared_ptr<Notify> NotifyRef;
39typedef std::weak_ptr<Notify> WNotifyRef;
7c673cae
FG
40
41struct CancelableContext;
42
43/**
44 * Notify tracks the progress of a particular notify
45 *
46 * References are held by Watch and the timeout callback.
47 */
48class Notify {
49 friend class NotifyTimeoutCB;
50 friend class Watch;
51 WNotifyRef self;
52 ConnectionRef client;
53 uint64_t client_gid;
54 bool complete;
55 bool discarded;
56 bool timed_out; ///< true if the notify timed out
57 set<WatchRef> watchers;
58
59 bufferlist payload;
60 uint32_t timeout;
61 uint64_t cookie;
62 uint64_t notify_id;
63 uint64_t version;
64
65 OSDService *osd;
66 CancelableContext *cb;
67 Mutex lock;
68
69 /// (gid,cookie) -> reply_bl for everyone who acked the notify
70 multimap<pair<uint64_t,uint64_t>,bufferlist> notify_replies;
71
72 /// true if this notify is being discarded
73 bool is_discarded() {
74 return discarded || complete;
75 }
76
77 /// Sends notify completion if watchers.empty() or timeout
78 void maybe_complete_notify();
79
80 /// Called on Notify timeout
81 void do_timeout();
82
83 Notify(
84 ConnectionRef client,
85 uint64_t client_gid,
86 bufferlist &payload,
87 uint32_t timeout,
88 uint64_t cookie,
89 uint64_t notify_id,
90 uint64_t version,
91 OSDService *osd);
92
93 /// registers a timeout callback with the watch_timer
94 void register_cb();
95
96 /// removes the timeout callback, called on completion or cancellation
97 void unregister_cb();
98public:
99
11fdf7f2
TL
100 std::ostream& gen_dbg_prefix(std::ostream& out) {
101 return out << "Notify(" << make_pair(cookie, notify_id) << " "
102 << " watchers=" << watchers.size()
103 << ") ";
7c673cae
FG
104 }
105 void set_self(NotifyRef _self) {
106 self = _self;
107 }
108 static NotifyRef makeNotifyRef(
109 ConnectionRef client,
110 uint64_t client_gid,
111 bufferlist &payload,
112 uint32_t timeout,
113 uint64_t cookie,
114 uint64_t notify_id,
115 uint64_t version,
116 OSDService *osd);
117
118 /// Call after creation to initialize
119 void init();
120
121 /// Called once per watcher prior to init()
122 void start_watcher(
123 WatchRef watcher ///< [in] watcher to complete
124 );
125
126 /// Called once per NotifyAck
127 void complete_watcher(
128 WatchRef watcher, ///< [in] watcher to complete
129 bufferlist& reply_bl ///< [in] reply buffer from the notified watcher
130 );
131 /// Called when a watcher unregisters or times out
132 void complete_watcher_remove(
133 WatchRef watcher ///< [in] watcher to complete
134 );
135
136 /// Called when the notify is canceled due to a new peering interval
137 void discard();
138};
139
140/**
141 * Watch is a mapping between a Connection and an ObjectContext
142 *
143 * References are held by ObjectContext and the timeout callback
144 */
145class HandleWatchTimeout;
146class HandleDelayedWatchTimeout;
147class Watch {
148 WWatchRef self;
149 friend class HandleWatchTimeout;
150 friend class HandleDelayedWatchTimeout;
151 ConnectionRef conn;
152 CancelableContext *cb;
153
154 OSDService *osd;
155 boost::intrusive_ptr<PrimaryLogPG> pg;
11fdf7f2 156 std::shared_ptr<ObjectContext> obc;
7c673cae
FG
157
158 std::map<uint64_t, NotifyRef> in_progress_notifies;
159
160 // Could have watch_info_t here, but this file includes osd_types.h
161 uint32_t timeout; ///< timeout in seconds
162 uint64_t cookie;
163 entity_addr_t addr;
164
165 bool will_ping; ///< is client new enough to ping the watch
11fdf7f2 166 utime_t last_ping; ///< last client ping
7c673cae
FG
167
168 entity_name_t entity;
169 bool discarded;
170
171 Watch(
172 PrimaryLogPG *pg, OSDService *osd,
11fdf7f2 173 std::shared_ptr<ObjectContext> obc, uint32_t timeout,
7c673cae
FG
174 uint64_t cookie, entity_name_t entity,
175 const entity_addr_t& addr);
176
177 /// Registers the timeout callback with watch_timer
178 void register_cb();
179
180 /// send a Notify message when connected for notif
181 void send_notify(NotifyRef notif);
182
183 /// Cleans up state on discard or remove (including Connection state, obc)
184 void discard_state();
185public:
186 /// Unregisters the timeout callback
187 void unregister_cb();
188
189 /// note receipt of a ping
190 void got_ping(utime_t t);
191 utime_t get_last_ping() const {
192 return last_ping;
193 }
194
195 bool is_connected() const {
196 return conn.get() != NULL;
197 }
198 bool is_connected(Connection *con) const {
199 return conn.get() == con;
200 }
201
202 /// NOTE: must be called with pg lock held
203 ~Watch();
204
205 uint64_t get_watcher_gid() const {
206 return entity.num();
207 }
208
11fdf7f2 209 std::ostream& gen_dbg_prefix(std::ostream& out);
7c673cae
FG
210 static WatchRef makeWatchRef(
211 PrimaryLogPG *pg, OSDService *osd,
11fdf7f2 212 std::shared_ptr<ObjectContext> obc, uint32_t timeout, uint64_t cookie, entity_name_t entity, const entity_addr_t &addr);
7c673cae
FG
213 void set_self(WatchRef _self) {
214 self = _self;
215 }
216
217 /// Does not grant a ref count!
218 boost::intrusive_ptr<PrimaryLogPG> get_pg() { return pg; }
219
11fdf7f2 220 std::shared_ptr<ObjectContext> get_obc() { return obc; }
7c673cae
FG
221
222 uint64_t get_cookie() const { return cookie; }
223 entity_name_t get_entity() const { return entity; }
224 entity_addr_t get_peer_addr() const { return addr; }
225 uint32_t get_timeout() const { return timeout; }
226
227 /// Generates context for use if watch timeout is delayed by scrub or recovery
228 Context *get_delayed_cb();
229
230 /// True if currently connected
231 bool connected();
232
233 /// Transitions Watch to connected, unregister_cb, resends pending Notifies
234 void connect(
235 ConnectionRef con, ///< [in] Reference to new connection
236 bool will_ping ///< [in] client is new and will send pings
237 );
238
239 /// Transitions watch to disconnected, register_cb
240 void disconnect();
241
242 /// Called if Watch state is discarded due to new peering interval
243 void discard();
244
245 /// True if removed or discarded
246 bool is_discarded() const;
247
248 /// Called on unwatch
249 void remove(bool send_disconnect);
250
251 /// Adds notif as in-progress notify
252 void start_notify(
253 NotifyRef notif ///< [in] Reference to new in-progress notify
254 );
255
256 /// Removes timed out notify
257 void cancel_notify(
258 NotifyRef notif ///< [in] notify which timed out
259 );
260
261 /// Call when notify_ack received on notify_id
262 void notify_ack(
263 uint64_t notify_id, ///< [in] id of acked notify
264 bufferlist& reply_bl ///< [in] notify reply buffer
265 );
266};
267
268/**
269 * Holds weak refs to Watch structures corresponding to a connection
270 * Lives in the Session object of an OSD connection
271 */
272class WatchConState {
273 Mutex lock;
274 std::set<WatchRef> watches;
275public:
276 CephContext* cct;
11fdf7f2 277 explicit WatchConState(CephContext* cct) : lock("WatchConState"), cct(cct) {}
7c673cae
FG
278
279 /// Add a watch
280 void addWatch(
281 WatchRef watch ///< [in] Ref to new watch object
282 );
283
284 /// Remove a watch
285 void removeWatch(
286 WatchRef watch ///< [in] Ref to watch object to remove
287 );
288
289 /// Called on session reset, disconnects watchers
290 void reset(Connection *con);
291};
292
293#endif