XEN subagent: added domain state parameters
[public/netxms.git] / src / agent / subagents / xen / domain.cpp
CommitLineData
1647762a
VK
1/*
2** NetXMS XEN hypervisor subagent
3** Copyright (C) 2017 Raden Solutions
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
41668ccd 19** File: domain.cpp
1647762a
VK
20**
21**/
22
23#include "xen.h"
24
38270c40
VK
25/**
26 * Resolve domain name to ID
27 */
28LONG XenResolveDomainName(const char *name, uint32_t *domId)
29{
30 libxl_ctx *ctx;
31 XEN_CONNECT(ctx);
32 int rc = (libxl_name_to_domid(ctx, name, domId) == 0) ? SYSINFO_RC_SUCCESS : SYSINFO_RC_NO_SUCH_INSTANCE;
33 libxl_ctx_free(ctx);
34 return rc;
35}
36
1647762a
VK
37/**
38 * Handler for XEN.VirtualMachines list
39 */
40LONG H_XenDomainList(const TCHAR *param, const TCHAR *arg, StringList *value, AbstractCommSession *session)
41{
42 libxl_ctx *ctx;
43 XEN_CONNECT(ctx);
44
45 LONG rc = SYSINFO_RC_ERROR;
46
47 int count = 0;
48 libxl_dominfo *domains = libxl_list_domain(ctx, &count);
49 if (domains != NULL)
50 {
51 for(int i = 0; i < count; i++)
52 {
53 value->addMBString(libxl_domid_to_name(ctx, domains[i].domid));
54 }
55 libxl_dominfo_list_free(domains, count);
56 rc = SYSINFO_RC_SUCCESS;
57 }
58 else
59 {
60 nxlog_debug(4, _T("XEN: call to libxl_list_domain failed"));
61 }
62
63 libxl_ctx_free(ctx);
64 return rc;
65}
66
67/**
68 * Handler for XEN.VirtualMachines table
69 */
70LONG H_XenDomainTable(const TCHAR *param, const TCHAR *arg, Table *value, AbstractCommSession *session)
71{
72 libxl_ctx *ctx;
73 XEN_CONNECT(ctx);
74
75 LONG rc = SYSINFO_RC_ERROR;
76
77 int count = 0;
78 libxl_dominfo *domains = libxl_list_domain(ctx, &count);
79 if (domains != NULL)
80 {
81 value->addColumn(_T("ID"), DCI_DT_INT, _T("ID"), true);
82 value->addColumn(_T("NAME"), DCI_DT_STRING, _T("Name"));
83 value->addColumn(_T("STATE"), DCI_DT_STRING, _T("State"));
84 value->addColumn(_T("MEM_CURRENT"), DCI_DT_UINT64, _T("Current memory"));
85 value->addColumn(_T("MEM_SHARED"), DCI_DT_UINT64, _T("Shared memory"));
86 value->addColumn(_T("MEM_PAGED"), DCI_DT_UINT64, _T("Paged memory"));
87 value->addColumn(_T("MEM_OUTSTANDING"), DCI_DT_UINT64, _T("Outstanding memory"));
88 value->addColumn(_T("MEM_MAX"), DCI_DT_UINT64, _T("Max memory"));
89 value->addColumn(_T("CPU_COUNT"), DCI_DT_INT, _T("CPU count"));
90 value->addColumn(_T("CPU_TIME"), DCI_DT_UINT64, _T("CPU time"));
41668ccd
VK
91 value->addColumn(_T("CPU_USAGE_CURR"), DCI_DT_FLOAT, _T("CPU usage (current)"));
92 value->addColumn(_T("CPU_USAGE_1MIN"), DCI_DT_FLOAT, _T("CPU usage (1 minute average)"));
93 value->addColumn(_T("NET_RX_BYTES"), DCI_DT_UINT64, _T("Net Rx Bytes"));
94 value->addColumn(_T("NET_TX_BYTES"), DCI_DT_UINT64, _T("Net Tx Bytes"));
95 value->addColumn(_T("NET_RX_PACKETS"), DCI_DT_UINT64, _T("Net Rx Packets"));
96 value->addColumn(_T("NET_TX_PACKETS"), DCI_DT_UINT64, _T("Net Tx Packets"));
1647762a
VK
97
98 for(int i = 0; i < count; i++)
99 {
100 value->addRow();
101
102 libxl_dominfo *d = &domains[i];
103 value->set(0, d->domid);
104 value->set(1, libxl_domid_to_name(ctx, d->domid));
105
106 TCHAR state[6] = _T("-----");
107 if (d->running)
108 state[0] = _T('R');
109 if (d->blocked)
110 state[1] = _T('B');
111 if (d->paused)
112 state[2] = _T('P');
113 if (d->shutdown)
114 state[3] = _T('S');
115 if (d->dying)
116 state[4] = _T('D');
117 value->set(2, state);
118
119 value->set(3, d->current_memkb * _LL(1024));
120 value->set(4, d->shared_memkb * _LL(1024));
121 value->set(5, d->paged_memkb * _LL(1024));
122 value->set(6, d->outstanding_memkb * _LL(1024));
123 value->set(7, d->max_memkb * _LL(1024));
124
125 value->set(8, d->vcpu_online);
126 value->set(9, (UINT64)d->cpu_time);
41668ccd
VK
127
128 INT32 curr, avg;
129 if (XenQueryDomainCpuUsage(d->domid, &curr, &avg))
130 {
131 TCHAR buffer[32];
132 _sntprintf(buffer, 32, _T("%d.%d"), curr / 10, curr % 10);
133 value->set(10, buffer);
134 _sntprintf(buffer, 32, _T("%d.%d"), avg / 10, avg % 10);
135 value->set(11, buffer);
136 }
137
138 UINT64 rxBytes, txBytes, rxPackets, txPackets;
139 if (XenQueryDomainNetworkTraffic(d->domid, &rxBytes, &txBytes, &rxPackets, &txPackets))
140 {
141 value->set(12, rxBytes);
142 value->set(13, txBytes);
143 value->set(14, rxPackets);
144 value->set(15, txPackets);
145 }
1647762a
VK
146 }
147 libxl_dominfo_list_free(domains, count);
148 rc = SYSINFO_RC_SUCCESS;
149 }
150 else
151 {
152 nxlog_debug(4, _T("XEN: call to libxl_list_domain failed"));
153 }
154
155 libxl_ctx_free(ctx);
156 return rc;
157}
9d249009
VK
158
159/**
160 * Handler for domain state parameters
161 */
162LONG H_XenDomainState(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
163{
164 char domName[256];
165 if (!AgentGetParameterArgA(param, 1, domName, 256))
166 return SYSINFO_RC_UNSUPPORTED;
167
168 libxl_ctx *ctx;
169 XEN_CONNECT(ctx);
170
171 char *eptr;
172 uint32_t domId = strtoul(domName, &eptr, 0);
173 if (*eptr != 0)
174 {
175 if (libxl_name_to_domid(ctx, domName, &domId) != 0)
176 {
177 if (*arg == '?')
178 {
179 ret_string(value, _T("MISSING"));
180 }
181 else
182 {
183 ret_int(value, 0);
184 }
185 return SYSINFO_RC_SUCCESS;
186 }
187 }
188
189 LONG ret = SYSINFO_RC_SUCCESS;
190
191 libxl_dominfo dom;
192 libxl_dominfo_init(&dom);
193 int rc = libxl_domain_info(ctx, &dom, domId);
194 if (rc == 0)
195 {
196 switch(*arg)
197 {
198 case 'E':
199 ret_int(value, 1);
200 break;
201 case 'O':
202 ret_int(value, dom.running || dom.blocked ? 1 : 0);
203 break;
204 case 'P':
205 ret_int(value, dom.paused ? 1 : 0);
206 break;
207 case '?':
208 if (dom.running)
209 ret_string(value, _T("RUNNING"));
210 else if (dom.blocked)
211 ret_string(value, _T("BLOCKED"));
212 else if (dom.paused)
213 ret_string(value, _T("PAUSED"));
214 else if (dom.shutdown)
215 ret_string(value, _T("SHUTDOWN"));
216 else if (dom.dying)
217 ret_string(value, _T("DYING"));
218 else
219 ret_string(value, _T("UNKNOWN"));
220 break;
221 default:
222 ret = SYSINFO_RC_UNSUPPORTED;
223 break;
224 }
225 }
226 else if (rc == ERROR_DOMAIN_NOTFOUND)
227 {
228 if (*arg == '?')
229 {
230 ret_string(value, _T("MISSING"));
231 }
232 else
233 {
234 ret_int(value, 0);
235 }
236 }
237 else
238 {
239 ret = SYSINFO_RC_ERROR;
240 }
241
242 libxl_ctx_free(ctx);
243 return ret;
244}