Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include "agent_cmn.h"
6 : #include "agent_db.h"
7 : #include <cfg/cfg_init.h>
8 :
9 574 : void AgentDBEntry::SetRefState() const {
10 574 : AgentDBTable *table = static_cast<AgentDBTable *>(get_table());
11 : // Force calling SetState on a const object.
12 : // Ideally, SetState should be 'const method' and StateMap mutable
13 574 : AgentDBEntry *entry = (AgentDBEntry *)this;
14 574 : entry->SetState(table, table->GetRefListenerId(), new AgentDBState(this));
15 574 : }
16 :
17 574 : void AgentDBEntry::ClearRefState() const {
18 574 : AgentDBTable *table = static_cast<AgentDBTable *>(get_table());
19 : // Force calling SetState on a const object.
20 : // Ideally, ClearState should be 'const method' and StateMap mutable
21 574 : AgentDBEntry *entry = (AgentDBEntry *)this;
22 574 : table->OnZeroRefcount(entry);
23 574 : delete(entry->GetState(table, table->GetRefListenerId()));
24 574 : entry->ClearState(table, table->GetRefListenerId());
25 574 : }
26 :
27 3254 : bool AgentDBEntry::IsActive() const {
28 3254 : return !IsDeleted();
29 : }
30 :
31 186 : DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) {
32 : DBState *state = dynamic_cast<DBState *>
33 186 : (GetState(get_table(), listener_id));
34 186 : return state;
35 : }
36 :
37 263 : const DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) const {
38 : const DBState *state = dynamic_cast<const DBState *>
39 263 : (GetState(get_table(), listener_id));
40 263 : return state;
41 : }
42 :
43 567 : void AgentDBEntry::AllocateResources(ResourceManager *resource_manager) {
44 567 : }
45 :
46 567 : void AgentDBEntry::FreeResources(ResourceManager *resource_manager) {
47 567 : }
48 :
49 245 : void AgentDBEntry::PostAdd() {
50 245 : }
51 :
52 20 : static bool FlushNotify(DBTablePartBase *partition, DBEntryBase *e) {
53 20 : if (e->IsDeleted()) {
54 4 : return true;
55 : }
56 :
57 16 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
58 16 : req.key = e->GetDBRequestKey();
59 16 : (static_cast<AgentDBTable *>(e->get_table()))->Process(req);
60 16 : return true;
61 16 : }
62 :
63 16 : static void FlushWalkDone(DBTable::DBTableWalkRef walk_ref,
64 : DBTableBase *partition) {
65 16 : AgentDBTable *table = static_cast<AgentDBTable *>(partition);
66 16 : table->ReleaseWalker(walk_ref);
67 16 : table->reset_flush_walk_ref();
68 16 : }
69 :
70 48 : AgentDBTable::AgentDBTable(DB *db, const std::string &name) :
71 48 : DBTable(db, name), ref_listener_id_(-1), agent_(NULL),
72 48 : OperDBTraceBuf(SandeshTraceBufferCreate(("Oper " + name), 5000)),
73 96 : flush_walk_ref_() {
74 48 : ref_listener_id_ = Register(boost::bind(&AgentDBTable::Notify,
75 : this, _1, _2));
76 48 : };
77 :
78 0 : AgentDBTable::AgentDBTable(DB *db, const std::string &name,
79 0 : bool del_on_zero_refcount) :
80 0 : DBTable(db, name), ref_listener_id_(-1) , agent_(NULL),
81 0 : OperDBTraceBuf(SandeshTraceBufferCreate(("Oper " + name), 5000)),
82 0 : flush_walk_ref_() {
83 0 : ref_listener_id_ = Register(boost::bind(&AgentDBTable::Notify,
84 : this, _1, _2));
85 0 : };
86 :
87 48 : AgentDBTable::~AgentDBTable() {
88 48 : assert(HasWalkers() == false);
89 48 : }
90 :
91 0 : void AgentDBTable::NotifyEntry(DBEntryBase *e) {
92 0 : agent_->ConcurrencyCheck();
93 : DBTablePartBase *tpart =
94 0 : static_cast<DBTablePartition *>(GetTablePartition(e));
95 0 : tpart->Notify(e);
96 0 : }
97 :
98 16 : void AgentDBTable::reset_flush_walk_ref() {
99 16 : flush_walk_ref_ = NULL;
100 16 : }
101 :
102 0 : AgentDBEntry *AgentDBTable::FindActiveEntryNoLock(const DBEntry *key) {
103 0 : AgentDBEntry *entry = static_cast<AgentDBEntry *> (FindNoLock(key));
104 0 : if (entry && (entry->IsActive() == false)) {
105 0 : return NULL;
106 : }
107 0 : return entry;
108 : }
109 :
110 572 : AgentDBEntry *AgentDBTable::FindActiveEntry(const DBEntry *key) {
111 572 : AgentDBEntry *entry = static_cast<AgentDBEntry *> (Find(key));
112 572 : if (entry && (entry->IsActive() == false)) {
113 0 : return NULL;
114 : }
115 572 : return entry;
116 : }
117 :
118 8 : AgentDBEntry *AgentDBTable::FindActiveEntryNoLock(const DBRequestKey *key) {
119 8 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(FindNoLock(key));
120 8 : if (entry && (entry->IsActive() == false)) {
121 0 : return NULL;
122 : }
123 8 : return entry;
124 : }
125 :
126 3537 : AgentDBEntry *AgentDBTable::FindActiveEntry(const DBRequestKey *key) {
127 3537 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(Find(key));
128 3537 : if (entry && (entry->IsActive() == false)) {
129 3 : return NULL;
130 : }
131 3534 : return entry;
132 : }
133 :
134 0 : AgentDBEntry *AgentDBTable::Find(const DBEntry *key, bool ret_del) {
135 0 : if (ret_del) {
136 0 : return Find(key);
137 : } else {
138 0 : return FindActiveEntry(key);
139 : }
140 : }
141 :
142 2276 : AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key, bool ret_del) {
143 2276 : if (ret_del) {
144 2204 : return Find(key);
145 : } else {
146 72 : return FindActiveEntry(key);
147 : }
148 : }
149 :
150 572 : AgentDBEntry *AgentDBTable::Find(const DBEntry *key) {
151 572 : return static_cast<AgentDBEntry *> (DBTable::Find(key));
152 : }
153 :
154 5741 : AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key) {
155 5741 : return static_cast<AgentDBEntry *>(DBTable::Find(key));
156 : }
157 :
158 567 : void AgentDBTablePartition::Add(DBEntry *entry) {
159 567 : entry->set_table_partition(static_cast<DBTablePartBase *>(this));
160 567 : Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
161 567 : if (agent) {
162 : (static_cast<AgentDBEntry *>(entry))->AllocateResources
163 567 : (agent->resource_manager());
164 : }
165 567 : DBTablePartition::Add(entry);
166 567 : static_cast<AgentDBEntry *>(entry)->PostAdd();
167 567 : }
168 :
169 567 : void AgentDBTablePartition::Remove(DBEntryBase *entry) {
170 567 : AgentDBEntry *agent_dbentry = static_cast<AgentDBEntry *>(entry);
171 567 : if (agent_dbentry->GetRefCount() != 0) {
172 0 : agent_dbentry->ClearOnRemoveQ();
173 0 : return;
174 : }
175 567 : Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
176 567 : if (agent) {
177 : (static_cast<AgentDBEntry *>(entry))->FreeResources
178 567 : (agent->resource_manager());
179 : }
180 567 : DBTablePartition::Remove(entry);
181 : }
182 :
183 191 : bool AgentDBTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id) {
184 191 : id = boost::uuids::nil_uuid();
185 191 : return false;
186 : }
187 :
188 2426 : void AgentDBTable::Input(DBTablePartition *partition, DBClient *client,
189 : DBRequest *req) {
190 2426 : AgentKey *key = static_cast<AgentKey *>(req->key.get());
191 :
192 2426 : if (key->sub_op_ == AgentKey::ADD_DEL_CHANGE) {
193 2315 : DBTable::Input(partition, client, req);
194 2315 : return;
195 : }
196 :
197 111 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(partition->Find(key));
198 111 : if (entry && (entry->IsActive() == false)) {
199 5 : return;
200 : }
201 :
202 : // Dont create an entry on RESYNC sub_op
203 106 : if (key->sub_op_ == AgentKey::RESYNC) {
204 106 : if (entry == NULL) {
205 24 : return;
206 : }
207 82 : if (Resync(entry, req)) {
208 65 : partition->Change(entry);
209 : }
210 82 : return;
211 : }
212 0 : return;
213 : }
214 :
215 2 : void AgentDBTable::Clear() {
216 2 : Unregister(ref_listener_id_);
217 2 : assert(!HasListeners());
218 : DBTablePartition *partition = static_cast<DBTablePartition *>(
219 2 : GetTablePartition(0));
220 :
221 2 : DBEntryBase *next = NULL;
222 2 : for (DBEntryBase *entry = partition->GetFirst(); entry; entry = next) {
223 0 : next = partition->GetNext(entry);
224 0 : if (entry->IsDeleted()) {
225 0 : continue;
226 : }
227 0 : partition->Delete(entry);
228 : }
229 2 : }
230 :
231 16 : void AgentDBTable::Process(DBRequest &req) {
232 16 : agent_->ConcurrencyCheck();
233 : DBTablePartition *tpart =
234 16 : static_cast<DBTablePartition *>(GetTablePartition(req.key.get()));
235 16 : tpart->Process(NULL, &req);
236 16 : }
237 :
238 16 : void AgentDBTable::Flush() {
239 32 : flush_walk_ref_ = AllocWalker(boost::bind(FlushNotify, _1, _2),
240 16 : boost::bind(FlushWalkDone, _1, _2));
241 16 : WalkAgain(flush_walk_ref_);
242 16 : }
|