OpenSDN source code
ovsdb_entry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  * Copyright Contributors to the OpenSDN project
4  */
5 extern "C" {
6 #include <ovsdb_wrapper.h>
7 }
8 #include <ovsdb_object.h>
9 #include <ovsdb_entry.h>
10 #include <ovsdb_types.h>
11 
12 using OVSDB::OvsdbEntry;
14 using OVSDB::OvsdbObject;
16 
17 OvsdbEntry::OvsdbEntry(OvsdbObject *table) : KSyncEntry(), table_(table),
18  ovs_entry_(NULL) {
19 }
20 
21 OvsdbEntry::OvsdbEntry(OvsdbObject *table, uint32_t index) : KSyncEntry(index),
22  table_(table), ovs_entry_(NULL) {
23 }
24 
26 }
27 
29  return true;
30 }
31 
33  return true;
34 }
35 
37  return true;
38 }
39 
41  return table_;
42 }
43 
44 void OvsdbEntry::Ack(bool success) {
45  // TODO we don't handle failures for these entries
46  if (!success) {
47  OVSDB_TRACE(Error, "Transaction failed for " + ToString());
48  }
49 
50  OvsdbObject *object = static_cast<OvsdbObject*>(GetObject());
51  object->SafeNotifyEvent(this, ack_event_);
52 }
53 
55  ovs_entry_(NULL) {
56 }
57 
58 OvsdbDBEntry::OvsdbDBEntry(OvsdbDBObject *table, struct ovsdb_idl_row *ovs_entry) : KSyncDBEntry(),
59  table_(table), ovs_entry_(ovs_entry) {
60 }
61 
63 }
64 
66  OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
67  // trigger pre add/change only if idl is not marked deleted.
68  // we should not update KSync references as, these references eventually
69  // need to be released as part of delete trigger due to cleanup.
70  if (object->client_idl_ != NULL && !object->client_idl_->deleted()) {
71  PreAddChange();
72  }
73 
74  if (IsNoTxnEntry()) {
75  // trigger AddMsg with NULL pointer and return true to complete
76  // KSync state
77  AddMsg(NULL);
78  return true;
79  }
80 
81  struct ovsdb_idl_txn *txn;
82  if (UseBulkTxn()) {
83  txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::ADD_ACK);
84  } else {
85  txn = object->client_idl_->CreateTxn(this, KSyncEntry::ADD_ACK);
86  }
87 
88  if (txn == NULL) {
89  // failed to create transaction because of idl marked for
90  // deletion return from here.
92  return true;
93  }
94  AddMsg(txn);
95  return object->client_idl_->EncodeSendTxn(txn, this);
96 }
97 
99  OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
100  // trigger pre add/change only if idl is not marked deleted.
101  // we should not update KSync references as, these references eventually
102  // need to be released as part of delete trigger due to cleanup.
103  if (object->client_idl_ != NULL && !object->client_idl_->deleted()) {
104  PreAddChange();
105  }
106 
107  if (IsNoTxnEntry()) {
108  // trigger ChangeMsg with NULL pointer and return true to complete
109  // KSync state
110  ChangeMsg(NULL);
111  return true;
112  }
113 
114  struct ovsdb_idl_txn *txn;
115  if (UseBulkTxn()) {
116  txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::CHANGE_ACK);
117  } else {
118  txn = object->client_idl_->CreateTxn(this, KSyncEntry::CHANGE_ACK);
119  }
120 
121  if (txn == NULL) {
122  // failed to create transaction because of idl marked for
123  // deletion return from here.
125  return true;
126  }
127  ChangeMsg(txn);
128  return object->client_idl_->EncodeSendTxn(txn, this);
129 }
130 
132  if (IsNoTxnEntry()) {
133  // trigger DeleteMsg with NULL pointer
134  DeleteMsg(NULL);
135  // trigger Post Delete, to allow post delete processing
136  PostDelete();
137  // return true to complete KSync State
138  return true;
139  }
140 
141  OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
142  struct ovsdb_idl_txn *txn;
143  if (UseBulkTxn()) {
144  txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::DEL_ACK);
145  } else {
146  txn = object->client_idl_->CreateTxn(this, KSyncEntry::DEL_ACK);
147  }
148  if (txn == NULL) {
149  // failed to create transaction because of idl marked for
150  // deletion return from here.
152  return true;
153  }
154  DeleteMsg(txn);
155  bool ret = object->client_idl_->EncodeSendTxn(txn, this);
156  // trigger post delete if we are not waiting for Ack
157  // otherwise trigger post delete on Ack
158  if (ret) {
159  // current transaction send completed trigger post delete
160  PostDelete();
161  }
162  return ret;
163 }
164 
166  return (ovs_entry_ == NULL) ? false : true;
167 }
168 
170  KSyncState state = GetState();
171  return (state >= DEL_DEFER_DEL_ACK && state <= RENEW_WAIT);
172 }
173 
175  KSyncState state = GetState();
176  return (state == SYNC_WAIT || state == NEED_SYNC ||
177  state == DEL_DEFER_SYNC);
178 }
179 
180 void OvsdbDBEntry::NotifyAdd(struct ovsdb_idl_row *row) {
181  if (ovs_entry_ == NULL) {
182  ovs_entry_ = row;
183  } else {
184  // ovs_entry should never change from Non-NULL value to
185  // another Non-NULL value.
186  assert(ovs_entry_ == row);
187  }
188  OvsdbChange();
189 }
190 
191 void OvsdbDBEntry::NotifyDelete(struct ovsdb_idl_row *row) {
192  ovs_entry_ = NULL;
193 }
194 
196  return table_;
197 }
198 
199 void OvsdbDBEntry::Ack(bool success) {
200  OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
201 
202  // trigger post delete for Del Ack
204  // current transaction send completed trigger post delete
205  PostDelete();
206  }
207 
208  if (success) {
209  if (IsDelAckWaiting())
210  object->SafeNotifyEvent(this, KSyncEntry::DEL_ACK);
211  else if (IsAddChangeAckWaiting())
212  object->SafeNotifyEvent(this, KSyncEntry::ADD_ACK);
213  else
214  delete this;
215  } else {
216  bool trigger_ack = false;
217  // On Failure try again
218  if (IsDelAckWaiting()) {
219  OVSDB_TRACE(Error, "Delete Transaction failed for " + ToString());
220  // if we are waiting to renew, dont retry delete.
221  if (GetState() != RENEW_WAIT) {
222  // trigger ack when if no message to send, on calling delete
223  trigger_ack = Delete();
224  } else {
225  trigger_ack = true;
226  }
227 
228  if (trigger_ack) {
229  object->SafeNotifyEvent(this, KSyncEntry::DEL_ACK);
230  }
231  } else if (IsAddChangeAckWaiting()) {
232  OVSDB_TRACE(Error, "Add Transaction failed for " + ToString());
233  // if we are waiting to delete, dont retry add.
234  if (GetState() != DEL_DEFER_SYNC) {
235  // Enqueue a change before generating an ADD_ACK to keep
236  // the entry in a not sync'd state.
237  object->Change(this);
238  }
239 
240  object->SafeNotifyEvent(this, KSyncEntry::ADD_ACK);
241  } else {
242  // should never happen
243  assert(0);
244  }
245  }
246 }
247 
249  if (IsDeleted() || stale()) {
250  // skip this operation for Deleted/stale Entry, After this operation
251  // Deleted/Stale entry would become active/non-stale which is not
252  // intended use of this API, caller must ensure the entry to be Active
253  // if this operation is required
254  return;
255  }
257 }
virtual std::string ToString() const =0
@ DEL_DEFER_DEL_ACK
Definition: ksync_entry.h:46
@ DEL_DEFER_SYNC
Definition: ksync_entry.h:44
bool stale() const
Definition: ksync_entry.h:180
KSyncState GetState() const
Definition: ksync_entry.h:176
bool IsDeleted()
Definition: ksync_entry.h:182
void SafeNotifyEvent(KSyncEntry *entry, KSyncEntry::KSyncEvent event)
virtual bool Add()
Definition: ovsdb_entry.cc:65
bool IsAddChangeAckWaiting()
Definition: ovsdb_entry.cc:174
virtual bool Change()
Definition: ovsdb_entry.cc:98
virtual bool IsNoTxnEntry()
Definition: ovsdb_entry.h:106
struct ovsdb_idl_row * ovs_entry_
Definition: ovsdb_entry.h:112
virtual void Ack(bool success)
Definition: ovsdb_entry.cc:199
virtual void PostDelete()
Definition: ovsdb_entry.h:71
KSyncObject * GetObject() const
Definition: ovsdb_entry.cc:195
virtual void OvsdbChange()
Definition: ovsdb_entry.h:79
virtual void PreAddChange()
Definition: ovsdb_entry.h:67
virtual void AddMsg(struct ovsdb_idl_txn *)
Definition: ovsdb_entry.h:73
virtual bool UseBulkTxn()
Definition: ovsdb_entry.h:109
virtual bool Delete()
Definition: ovsdb_entry.cc:131
virtual void NotifyAdd(struct ovsdb_idl_row *)
Definition: ovsdb_entry.cc:180
OvsdbDBObject * table_
Definition: ovsdb_entry.h:111
virtual ~OvsdbDBEntry()
Definition: ovsdb_entry.cc:62
virtual bool IsDataResolved()
Definition: ovsdb_entry.cc:165
virtual void ChangeMsg(struct ovsdb_idl_txn *)
Definition: ovsdb_entry.h:75
OvsdbDBEntry(OvsdbDBObject *table)
Definition: ovsdb_entry.cc:54
virtual void NotifyDelete(struct ovsdb_idl_row *)
Definition: ovsdb_entry.cc:191
virtual void DeleteMsg(struct ovsdb_idl_txn *)
Definition: ovsdb_entry.h:77
OvsdbClientIdlPtr client_idl_
Definition: ovsdb_object.h:84
KSyncEntry::KSyncEvent ack_event_
Definition: ovsdb_entry.h:35
virtual void TxnDoneNoMessage()
Definition: ovsdb_entry.h:28
virtual bool Add()
Definition: ovsdb_entry.cc:28
virtual bool Delete()
Definition: ovsdb_entry.cc:36
OvsdbObject * table_
Definition: ovsdb_entry.h:53
virtual bool Change()
Definition: ovsdb_entry.cc:32
virtual ~OvsdbEntry()
Definition: ovsdb_entry.cc:25
OvsdbEntry(OvsdbObject *table)
Definition: ovsdb_entry.cc:17
KSyncObject * GetObject() const
Definition: ovsdb_entry.cc:40
void Ack(bool success)
Definition: ovsdb_entry.cc:44
#define OVSDB_TRACE(obj,...)