OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vm_uve_table_base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
7 #include <uve/agent_uve_base.h>
8 
9 using boost::uuids::nil_uuid;
10 
11 VmUveTableBase::VmUveTableBase(Agent *agent, uint32_t default_intvl)
12  : uve_vm_map_(), agent_(agent), uve_vm_map_mutex_(),
13  intf_listener_id_(DBTableBase::kInvalidId),
14  vm_listener_id_(DBTableBase::kInvalidId), timer_last_visited_(nil_uuid()),
15  timer_(TimerManager::CreateTimer
16  (*(agent->event_manager())->io_service(),
17  "VmUveTimer",
18  TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
19  expiry_time_ = default_intvl;
21  boost::bind(&VmUveTableBase::TimerExpiry, this));
22 }
23 
25 }
26 
28  UveVmMap::iterator it = uve_vm_map_.lower_bound(timer_last_visited_);
29  if (it == uve_vm_map_.end()) {
30  timer_last_visited_ = nil_uuid();
31  return true;
32  }
33 
34  uint32_t count = 0;
35  while (it != uve_vm_map_.end() && count < AgentUveBase::kUveCountPerTimer) {
36  VmUveEntryBase* entry = it->second.get();
37  const boost::uuids::uuid u= it->first;
38  UveVmMap::iterator prev = it;
39  it++;
40  count++;
41 
42  if (entry->deleted()) {
44  if (!entry->renewed()) {
45  tbb::mutex::scoped_lock lock(uve_vm_map_mutex_);
46  uve_vm_map_.erase(prev);
47  } else {
48  entry->set_deleted(false);
49  entry->set_renewed(false);
50  entry->set_changed(false);
51  SendVmMsg(entry, u);
52  }
53  } else if (entry->changed()) {
54  SendVmMsg(entry, u);
55  entry->set_changed(false);
56  /* Clear renew flag to be on safer side. Not really required */
57  entry->set_renewed(false);
58  }
59  }
60 
61  if (it == uve_vm_map_.end()) {
62  timer_last_visited_ = nil_uuid();
64  } else {
65  timer_last_visited_ = it->first;
67  }
68  /* Return true to trigger auto-restart of timer */
69  return true;
70 }
71 
73  if (time != expiry_time_) {
74  expiry_time_ = time;
76  }
77 }
78 
79 void VmUveTableBase::SendVmDeleteMsg(const string &vm_config_name) {
80  UveVirtualMachineAgent uve;
81  uve.set_name(vm_config_name);
82  uve.set_deleted(true);
83  DispatchVmMsg(uve);
84 }
85 
86 VmUveEntryBase* VmUveTableBase::Add(const VmEntry *vm, bool vm_notify) {
87  VmUveEntryPtr uve = Allocate(vm);
88  pair<UveVmMap::iterator, bool> ret;
89  ret = uve_vm_map_.insert(UveVmPair(vm->GetUuid(), uve));
90  UveVmMap::iterator it = ret.first;
91  VmUveEntryBase* entry = it->second.get();
92  if (!entry->add_by_vm_notify()) {
93  entry->set_add_by_vm_notify(vm_notify);
94  }
95  if (entry->deleted()) {
96  entry->set_renewed(true);
97  }
98  return entry;
99 }
100 
102  UveVmMap::iterator it = uve_vm_map_.find(u);
103  if (it == uve_vm_map_.end()) {
104  return;
105  }
106  VmUveEntryBase* entry = it->second.get();
107  /* We need to reset all non-key fields to ensure that they have right
108  * values since the entry is getting re-used. Also update the 'deleted_'
109  * and 'renewed_' flags */
110  entry->Reset();
111  return;
112 }
113 
115  VmUveEntryBase* entry = UveEntryFromVm(vm->GetUuid());
116  if (entry == NULL) {
117  return;
118  }
119 
120  bool send = entry->Update(vm);
121  if (send) {
122  entry->set_changed(true);
123  }
124 }
125 
128  return uve;
129 }
130 
132  UveVmMap::iterator it = uve_vm_map_.find(u);
133  if (it == uve_vm_map_.end()) {
134  return NULL;
135  }
136  return it->second.get();
137 }
138 
139 void VmUveTableBase::DispatchVmMsg(const UveVirtualMachineAgent &uve) {
140  UveVirtualMachineAgentTrace::Send(uve);
141 }
142 
144  const boost::uuids::uuid &u) {
145  UveVirtualMachineAgent uve;
146  if (entry->FrameVmMsg(u, &uve)) {
147  DispatchVmMsg(uve);
148  }
149 }
150 
152  VmUveEntryBase* entry = UveEntryFromVm(u);
153  if (entry == NULL) {
154  return;
155  }
156  entry->set_changed(true);
157  return;
158 }
159 
161  const VmInterface *vmi) {
162  VmUveEntryBase *vm_uve_entry = Add(vm, false);
163 
164  vm_uve_entry->InterfaceAdd(vmi->cfg_name());
165  vm_uve_entry->set_vm_name(vmi->vm_name());
166  vm_uve_entry->set_changed(true);
167 }
168 
170  const string &intf_cfg_name) {
171  VmUveEntryBase* entry = UveEntryFromVm(u);
172  if (entry == NULL) {
173  return;
174  }
175 
176  entry->InterfaceDelete(intf_cfg_name);
177  entry->set_changed(true);
178 }
179 
181  const string &vm_name) {
182  VmUveEntryBase* entry = UveEntryFromVm(u);
183  if (entry == NULL) {
184  return;
185  }
186 
187  entry->set_vm_name(vm_name);
188  entry->set_changed(true);
189 }
190 
192  DBEntryBase *e) {
193  const VmInterface *vm_port = dynamic_cast<const VmInterface*>(e);
194  if (vm_port == NULL) {
195  return;
196  }
197 
198  VmUveInterfaceState *state = static_cast<VmUveInterfaceState *>
199  (e->GetState(partition->parent(), intf_listener_id_));
200  if (e->IsDeleted() || ((vm_port->vm() == NULL))) {
201  if (state) {
203  e->ClearState(partition->parent(), intf_listener_id_);
204  delete state;
205  }
206  } else {
207  const VmEntry *vm = vm_port->vm();
209 
210  if (!state) {
211  /* Skip Add notification if it does not have config name */
212  if (vm_port->cfg_name().empty()) {
213  return;
214  }
215  state = new VmUveInterfaceState(nil_uuid(), "");
216  e->SetState(partition->parent(), intf_listener_id_, state);
217  }
218  /* Handle Change of VM in a given VM interface */
219  if ((vm->GetUuid() != state->vm_uuid_) ||
220  (vm_port->cfg_name() != state->interface_cfg_name_)) {
221  //Handle disassociation of old VM from the VMI
222  if (state->vm_uuid_ != nil_uuid() &&
223  !state->interface_cfg_name_.empty()) {
225  state->interface_cfg_name_);
226  }
227  if (vm->GetUuid() != nil_uuid() &&
228  !vm_port->cfg_name().empty()) {
229  InterfaceAddHandler(vm, vm_port);
230  }
231  state->vm_uuid_ = vm->GetUuid();
232  state->interface_cfg_name_ = vm_port->cfg_name();
233  state->vm_name_ = vm_port->vm_name();
234  } else if (vm_port->vm_name() != state->vm_name_) {
235  UpdateVmName(state->vm_uuid_, vm_port->vm_name());
236  state->vm_name_ = vm_port->vm_name();
237  }
238  }
239 }
240 
242  const VmEntry *vm = static_cast<const VmEntry *>(e);
243 
244  VmUveVmState *state = static_cast<VmUveVmState *>
245  (e->GetState(partition->parent(), vm_listener_id_));
246 
247  if (e->IsDeleted()) {
248  if (state) {
249  Delete(vm->GetUuid());
250 
251  VmStatCollectionStop(state);
252 
253  e->ClearState(partition->parent(), vm_listener_id_);
254  delete state;
255  }
256  return;
257  }
258 
259  if (!state) {
260  state = new VmUveVmState();
261  e->SetState(partition->parent(), vm_listener_id_, state);
262 
263  Add(vm, true);
264 
265  VmStatCollectionStart(state, vm);
266  MarkChanged(vm->GetUuid());
267  } else {
268  Change(vm);
269  }
270 }
271 
273  const VmEntry *vm) {
274 }
275 
277 }
278 
280  InterfaceTable *intf_table = agent_->interface_table();
281  intf_listener_id_ = intf_table->Register
282  (boost::bind(&VmUveTableBase::InterfaceNotify, this, _1, _2));
283 
284  VmTable *vm_table = agent_->vm_table();
285  vm_listener_id_ = vm_table->Register
286  (boost::bind(&VmUveTableBase::VmNotify, this, _1, _2));
287 }
288 
294 
295  if (timer_) {
296  timer_->Cancel();
298  timer_ = NULL;
299  }
300 }
tbb::mutex uve_vm_map_mutex_
VmUveEntryBase * UveEntryFromVm(const boost::uuids::uuid &u)
void set_vm_name(const std::string name)
uint32_t incremental_interval() const
const string & GetCfgName() const
Definition: vm.h:43
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
#define kTaskDBExclude
Definition: agent.h:336
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
uint32_t default_interval() const
boost::uuids::uuid timer_last_visited_
AgentUveBase * uve() const
Definition: agent.cc:909
virtual VmUveEntryPtr Allocate(const VmEntry *vm)
bool IsDeleted() const
Definition: db_entry.h:49
virtual void VmStatCollectionStop(VmUveVmState *state)
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
Definition: vm.h:32
Definition: vm.h:78
const std::string & vm_config_name() const
DBTableBase * parent()
static const uint32_t kUveCountPerTimer
InterfaceTable * interface_table() const
Definition: agent.h:465
boost::uuids::uuid uuid
void SendVmMsg(VmUveEntryBase *entry, const boost::uuids::uuid &u)
const boost::uuids::uuid & GetUuid() const
Definition: vm.h:46
boost::shared_ptr< VmUveEntryBase > VmUveEntryPtr
bool Update(const VmEntry *vm)
bool changed() const
void Unregister(ListenerId listener)
Definition: db_table.cc:186
void InterfaceDelete(const std::string &intf_cfg_name)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
void VmNotify(DBTablePartBase *partition, DBEntryBase *e)
void Delete(const boost::uuids::uuid &u)
void set_changed(bool val)
virtual ~VmUveTableBase()
void set_expiry_time(int time)
Definition: agent.h:358
DBTableBase::ListenerId vm_listener_id_
void InterfaceAddHandler(const VmEntry *vm, const VmInterface *vmi)
void set_deleted(bool value)
virtual void VmStatCollectionStart(VmUveVmState *state, const VmEntry *vm)
void InterfaceDeleteHandler(const boost::uuids::uuid &u, const std::string &intf_cfg_name)
VmUveTableBase(Agent *agent, uint32_t default_intvl)
virtual void Reset()
bool renewed() const
bool add_by_vm_notify() const
virtual void DispatchVmMsg(const UveVirtualMachineAgent &uve)
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
bool Cancel()
Definition: timer.cc:150
void UpdateVmName(const boost::uuids::uuid &u, const std::string &vm_name)
std::pair< const boost::uuids::uuid, VmUveEntryPtr > UveVmPair
const std::string & vm_name() const
virtual void SendVmDeleteMsg(const std::string &vm_config_name)
bool deleted() const
bool FrameVmMsg(const boost::uuids::uuid &u, UveVirtualMachineAgent *uve)
void set_add_by_vm_notify(bool value)
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
void Change(const VmEntry *vm)
const std::string & cfg_name() const
static const int kInvalidId
Definition: db_table.h:64
VmUveEntryBase * Add(const VmEntry *vm, bool vm_notify)
std::set< FloatingIp, FloatingIp > FloatingIpSet
Definition: vm_interface.h:567
void InterfaceAdd(const std::string &intf_cfg_name)
void InterfaceNotify(DBTablePartBase *partition, DBEntryBase *e)
void MarkChanged(const boost::uuids::uuid &u)
bool Reschedule(int time)
Definition: timer.cc:137
VmTable * vm_table() const
Definition: agent.h:490
const VmEntry * vm() const
DBTableBase::ListenerId intf_listener_id_
void set_renewed(bool value)
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222