]> git.proxmox.com Git - ceph.git/blame - ceph/src/osd/Watch.h
import ceph quincy 17.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
9f95a23c 57 std::set<WatchRef> watchers;
7c673cae 58
9f95a23c 59 ceph::buffer::list payload;
7c673cae
FG
60 uint32_t timeout;
61 uint64_t cookie;
62 uint64_t notify_id;
63 uint64_t version;
64
65 OSDService *osd;
66 CancelableContext *cb;
9f95a23c 67 ceph::mutex lock = ceph::make_mutex("Notify::lock");
7c673cae
FG
68
69 /// (gid,cookie) -> reply_bl for everyone who acked the notify
9f95a23c 70 std::multimap<std::pair<uint64_t,uint64_t>, ceph::buffer::list> notify_replies;
7c673cae
FG
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,
9f95a23c 86 ceph::buffer::list& payload,
7c673cae
FG
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 100 std::ostream& gen_dbg_prefix(std::ostream& out) {
9f95a23c 101 return out << "Notify(" << std::make_pair(cookie, notify_id) << " "
11fdf7f2
TL
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,
9f95a23c 111 ceph::buffer::list &payload,
7c673cae
FG
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
9f95a23c 129 ceph::buffer::list& reply_bl ///< [in] reply buffer from the notified watcher
7c673cae
FG
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);
7c673cae 191
9f95a23c 192 /// True if currently connected
7c673cae
FG
193 bool is_connected() const {
194 return conn.get() != NULL;
195 }
196 bool is_connected(Connection *con) const {
197 return conn.get() == con;
198 }
199
200 /// NOTE: must be called with pg lock held
201 ~Watch();
202
203 uint64_t get_watcher_gid() const {
204 return entity.num();
205 }
206
11fdf7f2 207 std::ostream& gen_dbg_prefix(std::ostream& out);
7c673cae
FG
208 static WatchRef makeWatchRef(
209 PrimaryLogPG *pg, OSDService *osd,
11fdf7f2 210 std::shared_ptr<ObjectContext> obc, uint32_t timeout, uint64_t cookie, entity_name_t entity, const entity_addr_t &addr);
7c673cae
FG
211 void set_self(WatchRef _self) {
212 self = _self;
213 }
214
215 /// Does not grant a ref count!
216 boost::intrusive_ptr<PrimaryLogPG> get_pg() { return pg; }
217
11fdf7f2 218 std::shared_ptr<ObjectContext> get_obc() { return obc; }
7c673cae
FG
219
220 uint64_t get_cookie() const { return cookie; }
221 entity_name_t get_entity() const { return entity; }
222 entity_addr_t get_peer_addr() const { return addr; }
223 uint32_t get_timeout() const { return timeout; }
224
225 /// Generates context for use if watch timeout is delayed by scrub or recovery
226 Context *get_delayed_cb();
227
7c673cae
FG
228 /// Transitions Watch to connected, unregister_cb, resends pending Notifies
229 void connect(
230 ConnectionRef con, ///< [in] Reference to new connection
231 bool will_ping ///< [in] client is new and will send pings
232 );
233
234 /// Transitions watch to disconnected, register_cb
235 void disconnect();
236
237 /// Called if Watch state is discarded due to new peering interval
238 void discard();
239
240 /// True if removed or discarded
241 bool is_discarded() const;
242
243 /// Called on unwatch
244 void remove(bool send_disconnect);
245
246 /// Adds notif as in-progress notify
247 void start_notify(
248 NotifyRef notif ///< [in] Reference to new in-progress notify
249 );
250
251 /// Removes timed out notify
252 void cancel_notify(
253 NotifyRef notif ///< [in] notify which timed out
254 );
255
256 /// Call when notify_ack received on notify_id
257 void notify_ack(
258 uint64_t notify_id, ///< [in] id of acked notify
9f95a23c 259 ceph::buffer::list& reply_bl ///< [in] notify reply buffer
7c673cae
FG
260 );
261};
262
263/**
264 * Holds weak refs to Watch structures corresponding to a connection
265 * Lives in the Session object of an OSD connection
266 */
267class WatchConState {
9f95a23c 268 ceph::mutex lock = ceph::make_mutex("WatchConState");
7c673cae
FG
269 std::set<WatchRef> watches;
270public:
271 CephContext* cct;
9f95a23c 272 explicit WatchConState(CephContext* cct) : cct(cct) {}
7c673cae
FG
273
274 /// Add a watch
275 void addWatch(
276 WatchRef watch ///< [in] Ref to new watch object
277 );
278
279 /// Remove a watch
280 void removeWatch(
281 WatchRef watch ///< [in] Ref to watch object to remove
282 );
283
284 /// Called on session reset, disconnects watchers
285 void reset(Connection *con);
286};
287
288#endif