OpenSDN source code
agent_db.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef vnsw_agent_db_hpp
6 #define vnsw_agent_db_hpp
7 
8 #include <atomic>
9 #include <mutex>
10 #include <cmn/agent_cmn.h>
11 
12 class Agent;
13 class AgentDBEntry;
14 class AgentDBTable;
15 struct AgentDBState;
16 class AgentSandesh;
18 class AgentSandesh;
19 class ResourceManager;
20 typedef class boost::shared_ptr<AgentSandesh> AgentSandeshPtr;
21 
23 // Refcount class for AgentDBEntry
25 template <class Derived>
27 public:
28  friend void intrusive_ptr_add_ref(const Derived* p) {
29  const AgentRefCount *entry = (const AgentRefCount *) (p);
30  if (entry->refcount_.fetch_add(1) == 0) {
31  p->SetRefState();
32  }
33  }
34 
35  friend void intrusive_ptr_release(const Derived* p) {
36  const AgentRefCount *entry = (const AgentRefCount *) (p);
37  if (entry->refcount_.fetch_sub(1) == 1) {
38  p->ClearRefState();
39  }
40  }
41 
43  const Derived* p) {
44  const AgentRefCount *entry = (const AgentRefCount *) (p);
45  std::scoped_lock lock(entry->back_ref_mutex_);
46  entry->back_ref_set_.insert(ref);
47  }
48 
50  const Derived* p) {
51  const AgentRefCount *entry = (const AgentRefCount *) (p);
52  std::scoped_lock lock(entry->back_ref_mutex_);
53  entry->back_ref_set_.erase(ref);
54  }
55 
56  uint32_t GetRefCount() const {return refcount_;};
57 protected:
60  AgentRefCount& operator=(const AgentRefCount&) { return *this; }
61  virtual ~AgentRefCount() {assert(refcount_ == 0);};
62  void swap(AgentRefCount&) {};
63 
64  mutable std::mutex back_ref_mutex_;
65  mutable std::set<IntrusiveReferrer> back_ref_set_;
66 
67 private:
68  mutable std::atomic<uint32_t> refcount_;
69 };
70 
72 // DBState for AgentDBEntry
75  AgentDBState(const AgentDBEntry *entry) : DBState(), entry_(entry) { };
77 };
78 
80 // VNSwitch DB Table Partition class
83 public:
86  virtual ~AgentDBTablePartition() {};
87  virtual void Add(DBEntry *entry);
88  virtual void Remove(DBEntryBase *entry);
89 
90 private:
92 };
93 
95 // VNSwitch DB Entry Key base class. Defines additional operations on DBEntry
97 struct AgentKey : public DBRequestKey {
98  typedef enum {
99  // Add/Delete/Change a entry
101  // Change an entry if its already present and not in deleted state
102  // Its a no-op if entry is not present or is in deleted state
104  } DBSubOperation;
105 
107  AgentKey(DBSubOperation sub_op) : DBRequestKey(), sub_op_(sub_op) { };
108  virtual ~AgentKey() { };
109 
110  uint8_t sub_op_;
111 };
112 
114 // VNSwitch DB Entry Data base class
116 struct AgentData : public DBRequestData {
118  virtual ~AgentData() { };
119 };
120 
122 // VNSwitch DB Entry base class. Supports
123 // 1. Reference counting with boost Intrusive pointer
125 class AgentDBEntry : public DBEntry {
126 public:
128  virtual ~AgentDBEntry() {};
129  virtual uint32_t GetRefCount() const = 0;
130 
131  typedef boost::intrusive_ptr<AgentDBEntry> AgentDBEntyRef;
132  void SetRefState() const;
133  void ClearRefState() const;
134  bool IsActive() const;
135  DBState *GetAgentDBEntryState(int listener_id);
136  const DBState *GetAgentDBEntryState(int listener_id) const;
137 
138  virtual void AllocateResources(ResourceManager *resource_manager);
139  virtual void FreeResources(ResourceManager *resource_manager);
140  virtual void PostAdd();
141  virtual bool DBEntrySandesh(Sandesh *resp, std::string &name) const = 0;
142 private:
143  friend class AgentDBTable;
145 };
146 
148 // VNSwitch DB Table base class
150 class AgentDBTable : public DBTable {
151 public:
152  static const int kPartitionCount = 1;
153  AgentDBTable(DB *db, const std::string &name);
154  AgentDBTable(DB *db, const std::string &name, bool del_on_zero_refcount);
155  virtual ~AgentDBTable();
156 
157  virtual int PartitionCount() const { return kPartitionCount; }
158  virtual void Input(DBTablePartition *root, DBClient *client,
159  DBRequest *req);
160  virtual DBEntry *CfgAdd(DBRequest *req) {return NULL;};
161  virtual bool Resync(DBEntry *entry, const DBRequest *req) {return false;};
162 
163  /*
164  * Clear all entries on a table. Requires the table to have no listeners.
165  * Used in process shutdown.
166  */
167  virtual void Clear();
168 
169  virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req,
170  const boost::uuids::uuid &uuid) {
171  assert(0);
172  return false;
173  }
174  virtual bool IFLinkToReq(IFMapLink *link, IFMapNode *node,
175  const std::string &peer_name, IFMapNode *peer,
176  DBRequest &req) {
177  assert(0);
178  return false;
179  }
180  virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id);
181 
182  virtual DBTablePartition *AllocPartition(int index) {
183  return new AgentDBTablePartition(this, index);
184  };
185  virtual void OnZeroRefcount(AgentDBEntry *e) {};
186  virtual void NotifyEntry(DBEntryBase *entry);
187 
189  const std::string &context) {
190  return AgentSandeshPtr();
191  }
192 
193  // Dummy notification
194  void Notify(DBTablePartBase *partition, DBEntryBase *entry) {
195  };
196 
198  AgentDBEntry *FindActiveEntry(const DBEntry *key);
202  AgentDBEntry *Find(const DBEntry *key, bool ret_del);
203  AgentDBEntry *Find(const DBRequestKey *key, bool ret_del);
204  virtual bool CanNotify(IFMapNode *dbe) {
205  return true;
206  }
207  virtual void Process(DBRequest &req);
208  virtual bool ProcessConfig(IFMapNode *node, DBRequest &req,
209  const boost::uuids::uuid &u) {
210  assert(0);
211  return false;
212  }
213 
215  Agent *agent() const { return agent_; }
216 
217  void Flush();
218  void reset_flush_walk_ref();
220 private:
221  AgentDBEntry *Find(const DBEntry *key);
222  AgentDBEntry *Find(const DBRequestKey *key);
223 
229 };
230 
231 #define OPER_TRACE(obj, ...)\
232 do {\
233  Oper##obj::TraceMsg(GetOperDBTraceBuf(), __FILE__, __LINE__, __VA_ARGS__);\
234 } while (false)
235 
236 #define OPER_TRACE_ENTRY(obj, table, ...)\
237 do {\
238  Oper##obj::TraceMsg(table->GetOperDBTraceBuf(),\
239  __FILE__, __LINE__, __VA_ARGS__);\
240 } while (false)
241 
242 #endif // vnsw_agent_db_hpp
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
Definition: agent_db.h:20
virtual bool DBEntrySandesh(Sandesh *resp, std::string &name) const =0
bool IsActive() const
Definition: agent_db.cc:27
virtual void FreeResources(ResourceManager *resource_manager)
Definition: agent_db.cc:46
void SetRefState() const
Definition: agent_db.cc:9
void ClearRefState() const
Definition: agent_db.cc:17
virtual void PostAdd()
Definition: agent_db.cc:49
virtual ~AgentDBEntry()
Definition: agent_db.h:128
virtual void AllocateResources(ResourceManager *resource_manager)
Definition: agent_db.cc:43
DBState * GetAgentDBEntryState(int listener_id)
Definition: agent_db.cc:31
DISALLOW_COPY_AND_ASSIGN(AgentDBEntry)
boost::intrusive_ptr< AgentDBEntry > AgentDBEntyRef
Definition: agent_db.h:131
virtual uint32_t GetRefCount() const =0
DISALLOW_COPY_AND_ASSIGN(AgentDBTablePartition)
AgentDBTablePartition(DBTable *parent, int index)
Definition: agent_db.h:84
virtual void Add(DBEntry *entry)
Definition: agent_db.cc:158
virtual ~AgentDBTablePartition()
Definition: agent_db.h:86
virtual void Remove(DBEntryBase *entry)
Definition: agent_db.cc:169
virtual void Input(DBTablePartition *root, DBClient *client, DBRequest *req)
Definition: agent_db.cc:188
DISALLOW_COPY_AND_ASSIGN(AgentDBTable)
SandeshTraceBufferPtr OperDBTraceBuf
Definition: agent_db.h:226
SandeshTraceBufferPtr GetOperDBTraceBuf() const
Definition: agent_db.h:219
virtual ~AgentDBTable()
Definition: agent_db.cc:87
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
virtual DBEntry * CfgAdd(DBRequest *req)
Definition: agent_db.h:160
AgentDBEntry * FindActiveEntryNoLock(const DBEntry *key)
Definition: agent_db.cc:102
virtual bool ProcessConfig(IFMapNode *node, DBRequest &req, const boost::uuids::uuid &u)
Definition: agent_db.h:208
virtual bool IFLinkToReq(IFMapLink *link, IFMapNode *node, const std::string &peer_name, IFMapNode *peer, DBRequest &req)
Definition: agent_db.h:174
virtual int PartitionCount() const
Definition: agent_db.h:157
virtual bool CanNotify(IFMapNode *dbe)
Definition: agent_db.h:204
virtual bool Resync(DBEntry *entry, const DBRequest *req)
Definition: agent_db.h:161
void Notify(DBTablePartBase *partition, DBEntryBase *entry)
Definition: agent_db.h:194
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
Definition: agent_db.h:188
DBTable::DBTableWalkRef flush_walk_ref_
Definition: agent_db.h:227
static const int kPartitionCount
Definition: agent_db.h:152
Agent * agent_
Definition: agent_db.h:225
AgentDBTable(DB *db, const std::string &name)
Definition: agent_db.cc:70
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
virtual void Clear()
Definition: agent_db.cc:215
DBTableBase::ListenerId GetRefListenerId() const
Definition: agent_db.h:197
virtual void Process(DBRequest &req)
Definition: agent_db.cc:231
virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req, const boost::uuids::uuid &uuid)
Definition: agent_db.h:169
void Flush()
Definition: agent_db.cc:238
Agent * agent() const
Definition: agent_db.h:215
DBTableBase::ListenerId ref_listener_id_
Definition: agent_db.h:224
virtual void OnZeroRefcount(AgentDBEntry *e)
Definition: agent_db.h:185
virtual DBTablePartition * AllocPartition(int index)
Definition: agent_db.h:182
virtual void NotifyEntry(DBEntryBase *entry)
Definition: agent_db.cc:91
void reset_flush_walk_ref()
Definition: agent_db.cc:98
void set_agent(Agent *agent)
Definition: agent_db.h:214
virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id)
Definition: agent_db.cc:183
virtual ~AgentRefCount()
Definition: agent_db.h:61
AgentRefCount & operator=(const AgentRefCount &)
Definition: agent_db.h:60
uint32_t GetRefCount() const
Definition: agent_db.h:56
friend void intrusive_ptr_release(const Derived *p)
Definition: agent_db.h:35
std::atomic< uint32_t > refcount_
Definition: agent_db.h:68
void swap(AgentRefCount &)
Definition: agent_db.h:62
friend void intrusive_ptr_del_back_ref(const IntrusiveReferrer ref, const Derived *p)
Definition: agent_db.h:49
std::set< IntrusiveReferrer > back_ref_set_
Definition: agent_db.h:65
friend void intrusive_ptr_add_ref(const Derived *p)
Definition: agent_db.h:28
AgentRefCount(const AgentRefCount &)
Definition: agent_db.h:59
std::mutex back_ref_mutex_
Definition: agent_db.h:62
friend void intrusive_ptr_add_back_ref(const IntrusiveReferrer ref, const Derived *p)
Definition: agent_db.h:42
Definition: agent.h:360
int ListenerId
Definition: db_table.h:62
const std::string & name() const
Definition: db_table.h:110
DBTableBase * parent()
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:169
Definition: db.h:24
std::pair< void *, void * > IntrusiveReferrer
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
const AgentDBEntry * entry_
Definition: agent_db.h:75
AgentDBState(const AgentDBEntry *entry)
Definition: agent_db.h:75
virtual ~AgentData()
Definition: agent_db.h:118
AgentData()
Definition: agent_db.h:117
virtual ~AgentKey()
Definition: agent_db.h:108
DBSubOperation
Definition: agent_db.h:98
@ ADD_DEL_CHANGE
Definition: agent_db.h:100
@ RESYNC
Definition: agent_db.h:103
AgentKey(DBSubOperation sub_op)
Definition: agent_db.h:107
uint8_t sub_op_
Definition: agent_db.h:108
AgentKey()
Definition: agent_db.h:106
boost::uuids::uuid uuid