/
vm_uve_table.cc
133 lines (114 loc) · 3.82 KB
/
vm_uve_table.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#include <oper/interface_common.h>
#include <uve/vm_uve_table.h>
#include <uve/vm_uve_entry.h>
#include <uve/agent_uve.h>
#include <uve/vm_stat_kvm.h>
#include <uve/vm_stat_docker.h>
VmUveTable::VmUveTable(Agent *agent, uint32_t default_intvl)
: VmUveTableBase(agent, default_intvl) {
event_queue_.reset(new WorkQueue<VmStatData *>
(TaskScheduler::GetInstance()->GetTaskId("Agent::Uve"), 0,
boost::bind(&VmUveTable::Process, this, _1)));
event_queue_->set_name("Virtual-Machine UVE");
}
VmUveTable::~VmUveTable() {
}
void VmUveTable::UpdateBitmap(const VmEntry* vm, uint8_t proto,
uint16_t sport, uint16_t dport) {
tbb::mutex::scoped_lock lock(uve_vm_map_mutex_);
UveVmMap::iterator it = uve_vm_map_.find(vm->GetUuid());
if (it != uve_vm_map_.end()) {
VmUveEntry *entry = static_cast<VmUveEntry *>(it->second.get());
entry->UpdatePortBitmap(proto, sport, dport);
}
}
VmUveEntry *VmUveTable::InterfaceIdToVmUveEntry(uint32_t id) {
Interface *intf = InterfaceTable::GetInstance()->FindInterface(id);
if (!intf || intf->type() != Interface::VM_INTERFACE) {
return NULL;
}
VmInterface *vm_intf = static_cast<VmInterface *>(intf);
/* Ignore if Vm interface does not have a VM */
if (vm_intf->vm() == NULL) {
return NULL;
}
UveVmMap::iterator it = uve_vm_map_.find(vm_intf->vm()->GetUuid());
if (it == uve_vm_map_.end()) {
return NULL;
}
return static_cast<VmUveEntry *>(it->second.get());
}
VmUveTableBase::VmUveEntryPtr VmUveTable::Allocate(const VmEntry *vm) {
VmUveEntryPtr uve(new VmUveEntry(agent_, vm->GetCfgName()));
return uve;
}
void VmUveTable::SendVmStatsMsg(const boost::uuids::uuid &u) {
VmUveEntry* entry = static_cast<VmUveEntry*>(UveEntryFromVm(u));
if (entry == NULL) {
return;
}
if (entry->deleted()) {
/* Skip entry marked for delete because the 'vm' pointer could be
* invalid */
return;
}
UveVirtualMachineAgent uve;
/* Two VM UVEs will be sent for all VM stats. VirtualMachineStats will
* have VM stats and UveVirtualMachineAgent will have port bitmap for VM
* and all its containing interfaces */
bool send = entry->FrameVmStatsMsg(&uve);
if (send) {
DispatchVmMsg(uve);
}
}
void VmUveTable::VmStatCollectionStart(VmUveVmState *state, const VmEntry *vm) {
//Create object to poll for VM stats
VmStat *stat = NULL;
if (agent_->isKvmMode()) {
stat = new VmStatKvm(agent_, vm->GetUuid());
} else if (agent_->isDockerMode()) {
stat = new VmStatDocker(agent_, vm->GetUuid());
}
if (stat) {
stat->Start();
state->stat_ = stat;
}
}
void VmUveTable::VmStatCollectionStop(VmUveVmState *state) {
if (state->stat_) {
state->stat_->Stop();
state->stat_ = NULL;
}
}
void VmUveTable::EnqueueVmStatData(VmStatData *data) {
event_queue_->Enqueue(data);
}
bool VmUveTable::Process(VmStatData* vm_stat_data) {
if (vm_stat_data->vm_stat()->marked_delete()) {
delete vm_stat_data->vm_stat();
} else {
vm_stat_data->vm_stat()->ProcessData();
}
delete vm_stat_data;
return true;
}
void VmUveTable::DispatchVmStatsMsg(const VirtualMachineStats &uve) {
VirtualMachineStatsTrace::Send(uve);
}
void VmUveTable::SendVmStats(void) {
UveVmMap::iterator it = uve_vm_map_.begin();
while (it != uve_vm_map_.end()) {
SendVmStatsMsg(it->first);
it++;
}
}
void VmUveTable::SendVmDeleteMsg(const string &vm_config_name) {
VmUveTableBase::SendVmDeleteMsg(vm_config_name);
VirtualMachineStats stats_uve;
stats_uve.set_name(vm_config_name);
stats_uve.set_deleted(true);
DispatchVmStatsMsg(stats_uve);
}