OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <tbb/atomic.h>
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 {
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
124  virtual KSyncEntry *UnresolvedReference() = 0;
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  // Returns true if the entry data is resolved
131  virtual bool IsDataResolved() {return true;}
132 
133  // User define KSync Response handler
134  virtual void Response() { };
135 
136  // Allow State Compression for delete.
137  virtual bool AllowDeleteStateComp() {return true;}
138 
139  // User defined error handler
140  virtual void ErrorHandler(int err, uint32_t seqno, KSyncEvent event) const;
141 
142  // Error message for vrouter returned errors
143  virtual std::string VrouterError(uint32_t error) const;
144  static std::string VrouterErrorToString(uint32_t error);
145 
146  // Every ksync operation needs an rx-buffer to read response. The rx buffer
147  // are pre-allocated to minimize compuation in ksync-tx-queue
148  // pre-allocation is enabled only for flows for now
149  virtual bool pre_alloc_rx_buffer() const { return false; }
150  // ksync-tx supports multiple queues for KSync events. Get index of queue
151  // to use
152  virtual uint32_t GetTableIndex() const { return 0; }
153  // On stale timer expiration, notify entry for same
154  virtual void StaleTimerExpired() { }
155 
156  size_t GetIndex() const {return index_;};
157  KSyncState GetState() const {return state_;};
158  bool del_add_pending() const {return del_add_pending_;}
159  uint32_t GetRefCount() const {return refcount_;}
160  bool Seen() const {return seen_;}
161  bool stale() const {return stale_;}
162  void SetSeen() {seen_ = true;}
163  bool IsDeleted() { return (state_ == DEL_ACK_WAIT ||
165  state_ == DEL_DEFER_SYNC ||
166  state_ == DEL_DEFER_REF); };
167 
168  // return true if an entry is actively owned some module,
169  // i.e., explicit Create was triggered for this entry and it
170  // is not deleted yet by the Creator.
171  // this entry however may still be still in unresolved state.
172  bool IsActive() { return (state_ != TEMP && !IsDeleted()); }
173 
174  void set_del_add_pending(bool pending) {del_add_pending_ = pending;}
176  t_history_.RecordTransition(from, to, event);
177  }
178 
179 protected:
180  void SetIndex(size_t index) {index_ = index;};
181  void SetState(KSyncState state) {state_ = state;};
182 private:
183  friend void intrusive_ptr_add_ref(KSyncEntry *p);
184  friend void intrusive_ptr_release(KSyncEntry *p);
185  friend class KSyncSock;
186  friend class KSyncObject;
187 
188  boost::intrusive::set_member_hook<> node_;
189 
190  size_t index_;
192  tbb::atomic<int> refcount_;
193  bool seen_;
194 
195  // Stale Entry flag indicates an entry as stale, which will be
196  // removed once stale entry timer cleanup gets triggered.
197  bool stale_;
198 
199  // flag to indicate a pending DelAdd operation on entry
200  // this is set to true when Delete Add operation cannot go
201  // through as entry is waiting of Ack for previous operation
203 
208  };
210  public:
212  idx_ = 0;
213  for (int i = 0; i < size_; i++) {
214  history_[i].event_ = INVALID;
215  }
216  }
217 
219  KSyncEvent event) {
220  history_[idx_].from_ = from;
221  history_[idx_].to_ = to;
222  history_[idx_].event_ = event;
223  idx_ = (idx_+1) % size_;
224  }
225  private:
226  static const int size_ = 5;
227  int idx_;
229  };
231 
233 };
234 
235 // Implementation of KSyncEntry with with DBTable. Must be used along
236 // with KSyncDBObject.
237 // Registers with DBTable and drives state-machine based on DBTable
238 // notifications
239 // Applications are not needed to generate any events to the state-machine
240 class KSyncDBEntry : public KSyncEntry, public DBState {
241 public:
242  typedef std::list<DBEntry *> DupEntryList;
243 
244  KSyncDBEntry() : KSyncEntry(), DBState() { db_entry_ = NULL; };
245  KSyncDBEntry(uint32_t index) : KSyncEntry(index), DBState() { db_entry_ = NULL; };
246  virtual ~KSyncDBEntry() { assert(dup_entry_list_.empty()); }
247 
248  // Check if object is in-sync with kernel.
249  // Return true if object needs sync. Else return false
250  virtual bool Sync(DBEntry *entry) = 0;
251 
252  void SetDBEntry(DBEntry *db_entry) { db_entry_ = db_entry; }
253  DBEntry * GetDBEntry() { return db_entry_; }
254 
255 private:
256  friend class KSyncDBObject;
257 
261 };
262 
263 #endif // ctrlplane_ksync_entry_h
std::string AckOperationString(KSyncEvent ack_event) const
KSyncEntry(uint32_t index)
Definition: ksync_entry.h:77
DBEntry * GetDBEntry()
Definition: ksync_entry.h:253
friend void intrusive_ptr_release(KSyncEntry *p)
virtual bool IsLess(const KSyncEntry &rhs) const =0
DupEntryList dup_entry_list_
Definition: ksync_entry.h:259
uint32_t GetRefCount() const
Definition: ksync_entry.h:159
virtual void StaleTimerExpired()
Definition: ksync_entry.h:154
virtual bool IsDataResolved()
Definition: ksync_entry.h:131
std::list< DBEntry * > DupEntryList
Definition: ksync_entry.h:242
bool IsResolved()
friend void intrusive_ptr_add_ref(KSyncEntry *p)
void SetIndex(size_t index)
Definition: ksync_entry.h:180
virtual bool pre_alloc_rx_buffer() const
Definition: ksync_entry.h:149
virtual void Response()
Definition: ksync_entry.h:134
std::string StateString() const
virtual bool Add()=0
bool operator<(const KSyncEntry &rhs) const
Definition: ksync_entry.h:96
KSyncEntryTransHistory t_history_
Definition: ksync_entry.h:230
KSyncDBEntry(uint32_t index)
Definition: ksync_entry.h:245
bool del_add_pending() const
Definition: ksync_entry.h:158
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
virtual bool Change()=0
void set_del_add_pending(bool pending)
Definition: ksync_entry.h:174
static const int kDefaultMsgSize
Definition: ksync_entry.h:70
DISALLOW_COPY_AND_ASSIGN(KSyncDBEntry)
void SetState(KSyncState state)
Definition: ksync_entry.h:181
boost::intrusive::set_member_hook node_
Definition: ksync_entry.h:188
tbb::atomic< int > refcount_
Definition: ksync_entry.h:192
boost::intrusive_ptr< KSyncEntry > KSyncEntryPtr
Definition: ksync_entry.h:68
virtual KSyncObject * GetObject() const =0
virtual bool AllowDeleteStateComp()
Definition: ksync_entry.h:137
virtual ~KSyncDBEntry()
Definition: ksync_entry.h:246
KSyncState GetState() const
Definition: ksync_entry.h:157
virtual bool ShouldReEvalBackReference() const
Definition: ksync_entry.h:125
bool del_add_pending_
Definition: ksync_entry.h:202
void SetSeen()
Definition: ksync_entry.h:162
bool stale() const
Definition: ksync_entry.h:161
static const size_t kInvalidIndex
Definition: ksync_entry.h:69
virtual std::string VrouterError(uint32_t error) const
SandeshTraceBufferPtr KSyncErrorTraceBuf
std::string EventString(KSyncEvent event) const
bool IsActive()
Definition: ksync_entry.h:172
DISALLOW_COPY_AND_ASSIGN(KSyncEntry)
static std::string VrouterErrorToString(uint32_t error)
bool IsDeleted()
Definition: ksync_entry.h:163
virtual uint32_t GetTableIndex() const
Definition: ksync_entry.h:152
virtual bool Sync(DBEntry *entry)=0
void RecordTransition(KSyncState from, KSyncState to, KSyncEvent event)
Definition: ksync_entry.h:175
size_t index_
Definition: ksync_entry.h:190
virtual void ErrorHandler(int err, uint32_t seqno, KSyncEvent event) const
virtual std::string ToString() const =0
KSyncState state_
Definition: ksync_entry.h:191
struct KSyncEntryTransition history_[size_]
Definition: ksync_entry.h:228
virtual KSyncEntry * UnresolvedReference()=0
size_t GetIndex() const
Definition: ksync_entry.h:156
bool Seen() const
Definition: ksync_entry.h:160
void RecordTransition(KSyncState from, KSyncState to, KSyncEvent event)
Definition: ksync_entry.h:218
DBEntry * db_entry_
Definition: ksync_entry.h:258
void Reset(uint32_t index)
Definition: ksync_entry.h:90
virtual ~KSyncEntry()
Definition: ksync_entry.h:80
void SetDBEntry(DBEntry *db_entry)
Definition: ksync_entry.h:252
virtual bool Delete()=0
void Reset()
Definition: ksync_entry.h:82