OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vm_stat_docker.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <sys/times.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <unistd.h>
9 #include <uve/vm_stat_docker.h>
10 #include <uve/vm_stat_data.h>
11 #include <db/db.h>
12 #include <db/db_entry.h>
13 #include <db/db_table.h>
14 #include <base/address.h>
16 #include <cmn/agent.h>
17 #include <uve/vrouter_uve_entry.h>
18 #include <sstream>
19 #include <fstream>
20 #include <uve/agent_uve.h>
21 #include <uve/vm_uve_table.h>
22 
23 using namespace boost::uuids;
24 using namespace boost::asio;
25 
26 VmStatDocker::VmStatDocker(Agent *agent, const uuid &vm_uuid)
27  : VmStat(agent, vm_uuid), container_id_() {
28 }
29 
31 }
32 
34  if (vm_uuid_ == nil_uuid()) {
35  return;
36  }
38 }
39 
41  double cpu_stat = 0;
42  std::string cpu_stat_str;
43  data_ >> cpu_stat_str;
44 
45  if (!cpu_stat_str.empty()) {
46  //Convert string to double
47  std::stringstream ss(cpu_stat_str);
48  ss >> cpu_stat;
49  //Convert from Nanoseconds to seconds
50  cpu_stat = cpu_stat / kOneSecInNanoSecs;
51  }
52 
53  time_t now;
54  time(&now);
56  cpu_usage_ = (cpu_stat - prev_cpu_stat_)/
57  difftime(now, prev_cpu_snapshot_time_);
58  cpu_usage_ *= 100;
59  }
60 
61  prev_cpu_stat_ = cpu_stat;
63 
64  //Clear buffer
65  data_.str(" ");
66  data_.clear();
67 
68  //Trigger a request to start Memory stat collection
70 }
71 
73  if (pid_) {
74  std::ostringstream proc_file;
75  proc_file << "/proc/"<<pid_<<"/status";
76  std::ifstream file(proc_file.str().c_str());
77 
78  bool vmsize = false;
79  bool rss = false;
80  bool peak = false;
81  std::string line;
82  while (std::getline(file, line)) {
83  if (line.find("VmSize") != std::string::npos) {
84  std::stringstream vm(line);
85  std::string tmp; vm >> tmp; vm >> virt_memory_;
86  vmsize = true;
87  }
88  if (line.find("VmRSS") != std::string::npos) {
89  std::stringstream vm(line);
90  std::string tmp;
91  vm >> tmp;
92  vm >> mem_usage_;
93  rss = true;
94  }
95  if (line.find("VmPeak") != std::string::npos) {
96  std::stringstream vm(line);
97  std::string tmp; vm >> tmp; vm >> virt_memory_peak_;
98  peak = true;
99  }
100  if (rss && vmsize && peak)
101  break;
102  }
103  }
104 
105  data_.str(" ");
106  data_.clear();
107 
108  SendVmCpuStats();
109  StartTimer();
110 }
111 
113  std::ostringstream cmd;
114  cmd << "cat /sys/fs/cgroup/cpuacct/docker/" << container_id_
115  << "/cpuacct.usage";
116  ExecCmd(cmd.str(), boost::bind(&VmStatDocker::ReadCpuStat, this));
117 }
118 
120  std::ostringstream cmd;
121  cmd << "cat /sys/fs/cgroup/memory/docker/" << container_id_
122  << "/memory.stat";
123  ExecCmd(cmd.str(), boost::bind(&VmStatDocker::ReadMemoryQuota, this));
124 }
125 
127  ReadMemStat();
128 }
129 
131  std::ostringstream cmd;
132  cmd << "docker inspect " << container_id_ << "| grep -A3 \\\"Paused\\\":";
133  ExecCmd(cmd.str(), boost::bind(&VmStatDocker::ReadPid, this));
134 }
135 
137  /* Expecting data_ to have the following content
138  * "Paused": false,
139  * "Pid": 24430,
140  * "Restarting": false,
141  * "Running": true,
142  */
143  string tmp, paused_str, pid_str, running_str;
144  while (data_ >> tmp) {
145  if (tmp.find("Paused") != std::string::npos) {
146  data_ >> paused_str;
147  }
148  if (tmp.find("Pid") != std::string::npos) {
149  data_ >> pid_str;
150  }
151  if (tmp.find("Running") != std::string::npos) {
152  data_ >> running_str;
153  break;
154  }
155  }
156 
157  //Remove the last character from 'pid_str'
158  if (pid_str.size() >= 2) {
159  pid_str.erase(pid_str.size() - 1);
160  //Convert string to uint32_t
161  std::stringstream ss(pid_str);
162  ss >> pid_;
163  }
164 
165  vm_state_ = VrouterAgentVmState::VROUTER_AGENT_VM_UNKNOWN;
166  if (paused_str == "true,") {
167  vm_state_ = VrouterAgentVmState::VROUTER_AGENT_VM_PAUSED;
168  } else if (running_str == "false,") {
169  vm_state_ = VrouterAgentVmState::VROUTER_AGENT_VM_SHUTDOWN;
170  } else if (running_str == "true,") {
171  vm_state_ = VrouterAgentVmState::VROUTER_AGENT_VM_ACTIVE;
172  }
173  data_.str(" ");
174  data_.clear();
175  GetMemStat();
176 }
177 
179  std::string tmp;
180  while (data_ >> tmp) {
181  if (tmp == "hierarchical_memory_limit") {
183  /* Convert the 'vm_memory_quota_' to KiB to make it consistent with
184  Kvm's 'vm_memory_quota_' */
185  vm_memory_quota_/= 1024;
186  break;
187  }
188  }
189 
190  data_.str(" ");
191  data_.clear();
192  GetPid();
193 }
194 
196  if (container_id_.empty()) {
197  GetContainerId();
198  } else {
199  //Get CPU and memory stats
200  GetCpuStat();
201  }
202  return false;
203 }
204 
206  data_ >> container_id_;
207  //Clear buffer
208  data_.str(" ");
209  data_.clear();
210 
211  if (!container_id_.empty()) {
212  //Successfully read container-id, collect other data
213  GetCpuStat();
214  } else {
215  retry_++;
216  //Retry after timeout
217  if (retry_ < kRetryCount) {
218  StartTimer();
219  }
220  }
221 }
222 
224  std::ostringstream cmd;
225  cmd << "docker ps --no-trunc | grep " << agent_->GetUuidStr(vm_uuid_)
226  << " | awk '{ print $1 }'";
227  ExecCmd(cmd.str(), boost::bind(&VmStatDocker::ReadContainerId, this));
228 }
uint32_t pid_
Definition: vm_stat.h:60
VmStatDocker(Agent *agent, const boost::uuids::uuid &vm_uuid)
double cpu_usage_
Definition: vm_stat.h:50
void ReadMemStat()
time_t prev_cpu_snapshot_time_
Definition: vm_stat.h:51
void ExecCmd(std::string cmd, DoneCb cb)
Definition: vm_stat.cc:74
void ReadContainerId()
VrouterAgentVmState::type vm_state_
Definition: vm_stat.h:66
boost::uuids::uuid uuid
static const uint32_t kRetryCount
Definition: vm_stat.h:20
Definition: vm_stat.h:17
std::stringstream data_
Definition: vm_stat.h:56
void SendVmCpuStats()
Definition: vm_stat.cc:179
void ReadCpuStat()
Definition: agent.h:358
uint32_t virt_memory_
Definition: vm_stat.h:46
void GetMemoryQuota()
uint32_t mem_usage_
Definition: vm_stat.h:45
void ReadMemoryQuota()
uint32_t virt_memory_peak_
Definition: vm_stat.h:47
uint32_t vm_memory_quota_
Definition: vm_stat.h:48
void StartTimer()
Definition: vm_stat.cc:205
double prev_cpu_stat_
Definition: vm_stat.h:49
Agent * agent_
Definition: vm_stat.h:43
static const long kOneSecInNanoSecs
std::string container_id_
std::string GetUuidStr(boost::uuids::uuid uuid_val) const
Definition: agent.cc:98
uint32_t retry_
Definition: vm_stat.h:61
void GetContainerId()
const boost::uuids::uuid vm_uuid_
Definition: vm_stat.h:44