OpenSDN source code
ksync_entry.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef ctrlplane_ksync_entry_h
6 #define ctrlplane_ksync_entry_h
7 
8 #include <boost/intrusive_ptr.hpp>
9 #include <boost/intrusive/set.hpp>
10 #include <atomic>
11 #include <sandesh/common/vns_constants.h>
12 #include <sandesh/common/vns_types.h>
13 #include <sandesh/sandesh_trace.h>
14 #include <db/db_entry.h>
15 
16 #define KSYNC_ERROR(obj, ...)\
17 do {\
18  if (LoggingDisabled()) break;\
19  obj::Send(g_vns_constants.CategoryNames.find(Category::VROUTER)->second,\
20  SandeshLevel::SYS_DEBUG, __FILE__, __LINE__, ##__VA_ARGS__);\
21 } while (false)
22 
24 #define KSYNC_ERROR_TRACE(obj, ...) \
25 do { \
26  KSyncError##obj::TraceMsg(KSyncErrorTraceBuf, \
27  __FILE__, __LINE__, __VA_ARGS__); \
28 } while (false)
29 
30 class KSyncObject;
31 class KSyncDBObject;
32 
33 class KSyncEntry {
34 public:
35  enum KSyncState {
36  INIT, // Init state. Not notified
37  TEMP, // Temporary entry created on reference
38  ADD_DEFER, // Add of entry deferred due to unmet dependencies
39  CHANGE_DEFER, // Change of entry deferred due to unmet dependencies
40  IN_SYNC, // Object in sync
41  SYNC_WAIT, // Waiting on ACK for add/change
42  NEED_SYNC, // Object changed. Needs Sync
43  DEL_DEFER_SYNC, // Del pending to be sent due to sync_wait
44  DEL_DEFER_REF, // Del pending to be sent due to ref-count
45  DEL_DEFER_DEL_ACK, // Del pending to be sent due to Del Ack wait
46  DEL_ACK_WAIT, // Del request sent waiting for ack
47  RENEW_WAIT, // Object renewal waiting for delete-ack
48  FREE_WAIT // Entry to be freed
49  };
50 
51  enum KSyncEvent {
60  INVALID
61  };
62 
63  std::string StateString() const;
64  std::string AckOperationString(KSyncEvent ack_event) const;
65  std::string EventString(KSyncEvent event) const;
66  // All referring KSyncEntries must use KSyncEntryPtr. The ref-count
67  // maintained is optionally used to defer DELETE till refcount is 0
68  typedef boost::intrusive_ptr<KSyncEntry> KSyncEntryPtr;
69  static const size_t kInvalidIndex = 0xFFFFFFFF;
70  static const int kDefaultMsgSize = 512;
71 
72  // Use this constructor if automatic index allocation is *not* needed
74  Reset();
75  };
76  // Use this constructor if automatic index allocation is needed
77  KSyncEntry(uint32_t index) {
78  Reset(index);
79  };
80  virtual ~KSyncEntry() { assert(refcount_ == 0);};
81 
82  void Reset() {
84  state_ = INIT;
85  seen_ = false;
86  stale_ = false;
87  del_add_pending_ = false;
88  refcount_ = 0;
89  }
90  void Reset(uint32_t index) {
91  Reset();
92  index_ = index;
93  }
94 
95  // Comparator for boost::set containing all KSyncEntries in an KSyncObject
96  bool operator<(const KSyncEntry &rhs) const {
97  return IsLess(rhs);
98  };
99  // Comparator to manage the tree
100  virtual bool IsLess(const KSyncEntry &rhs) const = 0;
101 
102  // Convert KSync to String
103  virtual std::string ToString() const = 0;
104 
105  // Create handler.
106  // Return true if operation is complete
107  // Return false if operation asynchronously
108  virtual bool Add() = 0;
109 
110  // Change handler.
111  // Return true if operation is complete
112  // Return false if operation asynchronously
113  virtual bool Change() = 0;
114 
115  // Delete handler.
116  // Return true if operation is complete
117  // Return false if operation asynchronously
118  virtual bool Delete() = 0;
119 
120  // KSyncObject for this entry. Used to release the index
121  virtual KSyncObject *GetObject() const = 0;
122  // Get an unresolved reference.
123  // This entry will be added into resolveq_ of unresolved-entry
125  virtual bool ShouldReEvalBackReference() const { return true; }
126 
127  // Returns true if entry is resolved and referring entry can be written
128  bool IsResolved();
129 
130  bool IsInSync() const { return (state_ == IN_SYNC); }
131 
132  // Returns true if the entry data is resolved
133  virtual bool IsDataResolved() {return true;}
134 
135  // User define KSync Response handler
136  virtual void Response() { };
137 
138  // Allow State Compression for delete.
139  virtual bool AllowDeleteStateComp() {return true;}
140 
141  // User defined error handler
142  virtual void ErrorHandler(int err, uint32_t seqno, KSyncEvent event) const;
143 
144  // Error message for vrouter returned errors
145  virtual std::string VrouterError(uint32_t error) const;
146  static std::string VrouterErrorToString(uint32_t error);
147 
148  // Every ksync operation needs an rx-buffer to read response. The rx buffer
149  // are pre-allocated to minimize compuation in ksync-tx-queue
150  // pre-allocation is enabled only for flows for now
151  virtual bool pre_alloc_rx_buffer() const { return false; }
152  // ksync-tx supports multiple queues for KSync events. Get index of queue
153  // to use
154  virtual uint32_t GetTableIndex() const { return 0; }
155  // On stale timer expiration, notify entry for same
156  virtual void StaleTimerExpired() { }
157 
158  size_t GetIndex() const {return index_;};
159  KSyncState GetState() const {return state_;};
160  bool del_add_pending() const {return del_add_pending_;}
161  uint32_t GetRefCount() const {return refcount_;}
162  bool Seen() const {return seen_;}
163  bool stale() const {return stale_;}
164  void SetSeen() {seen_ = true;}
165  bool IsDeleted() { return (state_ == DEL_ACK_WAIT ||
167  state_ == DEL_DEFER_SYNC ||
168  state_ == DEL_DEFER_REF); };
169 
170  // return true if an entry is actively owned some module,
171  // i.e., explicit Create was triggered for this entry and it
172  // is not deleted yet by the Creator.
173  // this entry however may still be still in unresolved state.
174  bool IsActive() { return (state_ != TEMP && !IsDeleted()); }
175 
176  void set_del_add_pending(bool pending) {del_add_pending_ = pending;}
178  t_history_.RecordTransition(from, to, event);
179  }
180 
181 protected:
182  void SetIndex(size_t index) {index_ = index;};
183  void SetState(KSyncState state) {state_ = state;};
184 private:
185  friend void intrusive_ptr_add_ref(KSyncEntry *p);
186  friend void intrusive_ptr_release(KSyncEntry *p);
187  friend class KSyncSock;
188  friend class KSyncObject;
189 
190  boost::intrusive::set_member_hook<> node_;
191 
192  size_t index_;
194  std::atomic<int> refcount_;
195  bool seen_;
196 
197  // Stale Entry flag indicates an entry as stale, which will be
198  // removed once stale entry timer cleanup gets triggered.
199  bool stale_;
200 
201  // flag to indicate a pending DelAdd operation on entry
202  // this is set to true when Delete Add operation cannot go
203  // through as entry is waiting of Ack for previous operation
205 
210  };
212  public:
214  idx_ = 0;
215  for (int i = 0; i < size_; i++) {
216  history_[i].event_ = INVALID;
217  }
218  }
219 
221  KSyncEvent event) {
222  history_[idx_].from_ = from;
223  history_[idx_].to_ = to;
224  history_[idx_].event_ = event;
225  idx_ = (idx_+1) % size_;
226  }
227  private:
228  static const int size_ = 5;
229  int idx_;
231  };
233 
235 };
236 
237 // Implementation of KSyncEntry with with DBTable. Must be used along
238 // with KSyncDBObject.
239 // Registers with DBTable and drives state-machine based on DBTable
240 // notifications
241 // Applications are not needed to generate any events to the state-machine
242 class KSyncDBEntry : public KSyncEntry, public DBState {
243 public:
244  typedef std::list<DBEntry *> DupEntryList;
245 
246  KSyncDBEntry() : KSyncEntry(), DBState() { db_entry_ = NULL; };
247  KSyncDBEntry(uint32_t index) : KSyncEntry(index), DBState() { db_entry_ = NULL; };
248  virtual ~KSyncDBEntry() { assert(dup_entry_list_.empty()); }
249 
250  // Check if object is in-sync with kernel.
251  // Return true if object needs sync. Else return false
252  virtual bool Sync(DBEntry *entry) = 0;
253 
254  void SetDBEntry(DBEntry *db_entry) { db_entry_ = db_entry; }
255  DBEntry * GetDBEntry() { return db_entry_; }
256 
257 private:
258  friend class KSyncDBObject;
259 
263 };
264 
265 #endif // ctrlplane_ksync_entry_h
DupEntryList dup_entry_list_
Definition: ksync_entry.h:261
DBEntry * db_entry_
Definition: ksync_entry.h:260
DBEntry * GetDBEntry()
Definition: ksync_entry.h:255
KSyncDBEntry(uint32_t index)
Definition: ksync_entry.h:247
DISALLOW_COPY_AND_ASSIGN(KSyncDBEntry)
std::list< DBEntry * > DupEntryList
Definition: ksync_entry.h:244
void SetDBEntry(DBEntry *db_entry)
Definition: ksync_entry.h:254
virtual bool Sync(DBEntry *entry)=0
virtual ~KSyncDBEntry()
Definition: ksync_entry.h:248
void RecordTransition(KSyncState from, KSyncState to, KSyncEvent event)
Definition: ksync_entry.h:220
struct KSyncEntryTransition history_[size_]
Definition: ksync_entry.h:230
virtual bool AllowDeleteStateComp()
Definition: ksync_entry.h:139
virtual bool Add()=0
boost::intrusive::set_member_hook node_
Definition: ksync_entry.h:190
virtual std::string VrouterError(uint32_t error) const
virtual bool IsDataResolved()
Definition: ksync_entry.h:133
std::string AckOperationString(KSyncEvent ack_event) const
bool IsActive()
Definition: ksync_entry.h:174
bool IsInSync() const
Definition: ksync_entry.h:130
virtual KSyncObject * GetObject() const =0
void SetState(KSyncState state)
Definition: ksync_entry.h:183
void set_del_add_pending(bool pending)
Definition: ksync_entry.h:176
KSyncEntry(uint32_t index)
Definition: ksync_entry.h:77
virtual std::string ToString() const =0
bool del_add_pending() const
Definition: ksync_entry.h:160
std::string EventString(KSyncEvent event) const
friend void intrusive_ptr_add_ref(KSyncEntry *p)
@ DEL_DEFER_DEL_ACK
Definition: ksync_entry.h:45
@ DEL_DEFER_SYNC
Definition: ksync_entry.h:43
virtual uint32_t GetTableIndex() const
Definition: ksync_entry.h:154
void SetSeen()
Definition: ksync_entry.h:164
std::string StateString() const
virtual bool Delete()=0
virtual bool ShouldReEvalBackReference() const
Definition: ksync_entry.h:125
virtual void StaleTimerExpired()
Definition: ksync_entry.h:156
DISALLOW_COPY_AND_ASSIGN(KSyncEntry)
virtual void Response()
Definition: ksync_entry.h:136
size_t GetIndex() const
Definition: ksync_entry.h:158
@ ADD_CHANGE_REQ
Definition: ksync_entry.h:52
void Reset()
Definition: ksync_entry.h:82
void Reset(uint32_t index)
Definition: ksync_entry.h:90
static const int kDefaultMsgSize
Definition: ksync_entry.h:70
size_t index_
Definition: ksync_entry.h:192
bool del_add_pending_
Definition: ksync_entry.h:204
bool IsResolved()
KSyncEntryTransHistory t_history_
Definition: ksync_entry.h:232
boost::intrusive_ptr< KSyncEntry > KSyncEntryPtr
Definition: ksync_entry.h:68
virtual bool pre_alloc_rx_buffer() const
Definition: ksync_entry.h:151
bool Seen() const
Definition: ksync_entry.h:162
bool operator<(const KSyncEntry &rhs) const
Definition: ksync_entry.h:96
virtual ~KSyncEntry()
Definition: ksync_entry.h:80
bool stale() const
Definition: ksync_entry.h:163
KSyncState state_
Definition: ksync_entry.h:193
void RecordTransition(KSyncState from, KSyncState to, KSyncEvent event)
Definition: ksync_entry.h:177
virtual void ErrorHandler(int err, uint32_t seqno, KSyncEvent event) const
static std::string VrouterErrorToString(uint32_t error)
std::atomic< int > refcount_
Definition: ksync_entry.h:194
uint32_t GetRefCount() const
Definition: ksync_entry.h:161
static const size_t kInvalidIndex
Definition: ksync_entry.h:69
virtual bool IsLess(const KSyncEntry &rhs) const =0
void SetIndex(size_t index)
Definition: ksync_entry.h:182
KSyncState GetState() const
Definition: ksync_entry.h:159
friend void intrusive_ptr_release(KSyncEntry *p)
virtual KSyncEntry * UnresolvedReference()=0
bool IsDeleted()
Definition: ksync_entry.h:165
virtual bool Change()=0
SandeshTraceBufferPtr KSyncErrorTraceBuf
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18