VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp@ 43629

Last change on this file since 43629 was 43629, checked in by vboxsync, 12 years ago

Main/Metrics: Linux fs/disk metrics, VBoxManage filtering + minor fixes (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.7 KB
Line 
1/* $Id: VBoxManageMetrics.cpp 43629 2012-10-12 09:26:07Z vboxsync $ */
2/** @file
3 * VBoxManage - The 'metrics' command.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_ONLY_DOCS
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <VBox/com/com.h>
24#include <VBox/com/array.h>
25#include <VBox/com/ErrorInfo.h>
26#include <VBox/com/errorprint.h>
27#include <VBox/com/VirtualBox.h>
28
29#include <iprt/asm.h>
30#include <iprt/stream.h>
31#include <iprt/string.h>
32#include <iprt/time.h>
33#include <iprt/thread.h>
34#include <VBox/log.h>
35
36#include <set>
37#include <utility>
38
39#include "VBoxManage.h"
40using namespace com;
41
42
43// funcs
44///////////////////////////////////////////////////////////////////////////////
45
46
47static int parseFilterParameters(int argc, char *argv[],
48 ComPtr<IVirtualBox> aVirtualBox,
49 ComSafeArrayOut(BSTR, outMetrics),
50 ComSafeArrayOut(IUnknown *, outObjects))
51{
52 HRESULT rc = S_OK;
53 com::SafeArray<BSTR> retMetrics(1);
54 com::SafeIfaceArray <IUnknown> retObjects;
55
56 Bstr metricNames, baseNames;
57
58 /* Metric list */
59 if (argc > 1)
60 metricNames = argv[1];
61 else
62 {
63 metricNames = L"*";
64 baseNames = L"*";
65 }
66 metricNames.cloneTo(&retMetrics[0]);
67
68 /* Object name */
69 if (argc > 0 && strcmp(argv[0], "*"))
70 {
71 if (!strcmp(argv[0], "host"))
72 {
73 ComPtr<IHost> host;
74 CHECK_ERROR(aVirtualBox, COMGETTER(Host)(host.asOutParam()));
75 retObjects.reset(1);
76 host.queryInterfaceTo(&retObjects[0]);
77 }
78 else
79 {
80 ComPtr <IMachine> machine;
81 rc = aVirtualBox->FindMachine(Bstr(argv[0]).raw(),
82 machine.asOutParam());
83 if (SUCCEEDED (rc))
84 {
85 retObjects.reset(1);
86 machine.queryInterfaceTo(&retObjects[0]);
87 }
88 else
89 {
90 errorArgument("Invalid machine name: '%s'", argv[0]);
91 return rc;
92 }
93 }
94
95 }
96
97 retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
98 retObjects.detachTo(ComSafeArrayOutArg(outObjects));
99
100 return rc;
101}
102
103static Bstr toBaseName(Utf8Str& aFullName)
104{
105 char *pszRaw = aFullName.mutableRaw();
106 char *pszSlash = strrchr(pszRaw, '/');
107 if (pszSlash)
108 {
109 *pszSlash = 0;
110 aFullName.jolt();
111 }
112 return Bstr(aFullName);
113}
114
115static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox,
116 ComPtr<IUnknown> aObject)
117{
118 HRESULT rc;
119
120 ComPtr<IHost> host = aObject;
121 if (!host.isNull())
122 return Bstr("host");
123
124 ComPtr<IMachine> machine = aObject;
125 if (!machine.isNull())
126 {
127 Bstr name;
128 CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
129 if (SUCCEEDED(rc))
130 return name;
131 }
132 return Bstr("unknown");
133}
134
135static void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
136 ComSafeArrayIn(IPerformanceMetric*, aMetrics))
137{
138 HRESULT rc;
139 com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
140 if (metrics.size())
141 {
142 ComPtr<IUnknown> object;
143 Bstr metricName;
144 RTPrintf("The following metrics were modified:\n\n"
145 "Object Metric\n"
146 "---------- --------------------\n");
147 for (size_t i = 0; i < metrics.size(); i++)
148 {
149 CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
150 CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
151 RTPrintf("%-10ls %-20ls\n",
152 getObjectName(aVirtualBox, object).raw(), metricName.raw());
153 }
154 RTPrintf("\n");
155 }
156 else
157 {
158 RTMsgError("No metrics match the specified filter!");
159 }
160}
161
162/**
163 * list
164 */
165static int handleMetricsList(int argc, char *argv[],
166 ComPtr<IVirtualBox> aVirtualBox,
167 ComPtr<IPerformanceCollector> performanceCollector)
168{
169 HRESULT rc;
170 com::SafeArray<BSTR> metrics;
171 com::SafeIfaceArray<IUnknown> objects;
172
173 rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
174 ComSafeArrayAsOutParam(metrics),
175 ComSafeArrayAsOutParam(objects));
176 if (FAILED(rc))
177 return 1;
178
179 com::SafeIfaceArray<IPerformanceMetric> metricInfo;
180
181 CHECK_ERROR(performanceCollector,
182 GetMetrics(ComSafeArrayAsInParam(metrics),
183 ComSafeArrayAsInParam(objects),
184 ComSafeArrayAsOutParam(metricInfo)));
185
186 ComPtr<IUnknown> object;
187 Bstr metricName, unit, description;
188 ULONG period, count;
189 LONG minimum, maximum;
190 RTPrintf(
191"Object Metric Unit Minimum Maximum Period Count Description\n"
192"---------- -------------------- ---- ---------- ---------- ---------- ---------- -----------\n");
193 for (size_t i = 0; i < metricInfo.size(); i++)
194 {
195 CHECK_ERROR(metricInfo[i], COMGETTER(Object)(object.asOutParam()));
196 CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricName.asOutParam()));
197 CHECK_ERROR(metricInfo[i], COMGETTER(Period)(&period));
198 CHECK_ERROR(metricInfo[i], COMGETTER(Count)(&count));
199 CHECK_ERROR(metricInfo[i], COMGETTER(MinimumValue)(&minimum));
200 CHECK_ERROR(metricInfo[i], COMGETTER(MaximumValue)(&maximum));
201 CHECK_ERROR(metricInfo[i], COMGETTER(Unit)(unit.asOutParam()));
202 CHECK_ERROR(metricInfo[i], COMGETTER(Description)(description.asOutParam()));
203 RTPrintf("%-10ls %-20ls %-4ls %10d %10d %10u %10u %ls\n",
204 getObjectName(aVirtualBox, object).raw(), metricName.raw(), unit.raw(),
205 minimum, maximum, period, count, description.raw());
206 }
207
208 return 0;
209}
210
211/**
212 * Metrics setup
213 */
214static int handleMetricsSetup(int argc, char *argv[],
215 ComPtr<IVirtualBox> aVirtualBox,
216 ComPtr<IPerformanceCollector> performanceCollector)
217{
218 HRESULT rc;
219 com::SafeArray<BSTR> metrics;
220 com::SafeIfaceArray<IUnknown> objects;
221 uint32_t period = 1, samples = 1;
222 bool listMatches = false;
223 int i;
224
225 for (i = 1; i < argc; i++)
226 {
227 if ( !strcmp(argv[i], "--period")
228 || !strcmp(argv[i], "-period"))
229 {
230 if (argc <= i + 1)
231 return errorArgument("Missing argument to '%s'", argv[i]);
232 if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
233 || !period)
234 return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
235 }
236 else if ( !strcmp(argv[i], "--samples")
237 || !strcmp(argv[i], "-samples"))
238 {
239 if (argc <= i + 1)
240 return errorArgument("Missing argument to '%s'", argv[i]);
241 if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
242 || !samples)
243 return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
244 }
245 else if ( !strcmp(argv[i], "--list")
246 || !strcmp(argv[i], "-list"))
247 listMatches = true;
248 else
249 break; /* The rest of params should define the filter */
250 }
251
252 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
253 ComSafeArrayAsOutParam(metrics),
254 ComSafeArrayAsOutParam(objects));
255 if (FAILED(rc))
256 return 1;
257
258 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
259 CHECK_ERROR(performanceCollector,
260 SetupMetrics(ComSafeArrayAsInParam(metrics),
261 ComSafeArrayAsInParam(objects), period, samples,
262 ComSafeArrayAsOutParam(affectedMetrics)));
263 if (FAILED(rc))
264 return 2;
265
266 if (listMatches)
267 listAffectedMetrics(aVirtualBox,
268 ComSafeArrayAsInParam(affectedMetrics));
269
270 return 0;
271}
272
273/**
274 * metrics query
275 */
276static int handleMetricsQuery(int argc, char *argv[],
277 ComPtr<IVirtualBox> aVirtualBox,
278 ComPtr<IPerformanceCollector> performanceCollector)
279{
280 HRESULT rc;
281 com::SafeArray<BSTR> metrics;
282 com::SafeIfaceArray<IUnknown> objects;
283
284 rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
285 ComSafeArrayAsOutParam(metrics),
286 ComSafeArrayAsOutParam(objects));
287 if (FAILED(rc))
288 return 1;
289
290 com::SafeArray<BSTR> retNames;
291 com::SafeIfaceArray<IUnknown> retObjects;
292 com::SafeArray<BSTR> retUnits;
293 com::SafeArray<ULONG> retScales;
294 com::SafeArray<ULONG> retSequenceNumbers;
295 com::SafeArray<ULONG> retIndices;
296 com::SafeArray<ULONG> retLengths;
297 com::SafeArray<LONG> retData;
298 CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
299 ComSafeArrayAsInParam(objects),
300 ComSafeArrayAsOutParam(retNames),
301 ComSafeArrayAsOutParam(retObjects),
302 ComSafeArrayAsOutParam(retUnits),
303 ComSafeArrayAsOutParam(retScales),
304 ComSafeArrayAsOutParam(retSequenceNumbers),
305 ComSafeArrayAsOutParam(retIndices),
306 ComSafeArrayAsOutParam(retLengths),
307 ComSafeArrayAsOutParam(retData)) );
308
309 RTPrintf("Object Metric Values\n"
310 "---------- -------------------- --------------------------------------------\n");
311 for (unsigned i = 0; i < retNames.size(); i++)
312 {
313 Bstr metricUnit(retUnits[i]);
314 Bstr metricName(retNames[i]);
315 RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
316 const char *separator = "";
317 for (unsigned j = 0; j < retLengths[i]; j++)
318 {
319 if (retScales[i] == 1)
320 RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
321 else
322 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
323 (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
324 separator = ", ";
325 }
326 RTPrintf("\n");
327 }
328
329 return 0;
330}
331
332static void getTimestamp(char *pts, size_t tsSize)
333{
334 *pts = 0;
335 AssertReturnVoid(tsSize >= 13); /* 3+3+3+3+1 */
336 RTTIMESPEC TimeSpec;
337 RTTIME Time;
338 RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
339 pts += RTStrFormatNumber(pts, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
340 *pts++ = ':';
341 pts += RTStrFormatNumber(pts, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
342 *pts++ = ':';
343 pts += RTStrFormatNumber(pts, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
344 *pts++ = '.';
345 pts += RTStrFormatNumber(pts, Time.u32Nanosecond / 1000000, 10, 3, 0, RTSTR_F_ZEROPAD);
346 *pts = 0;
347}
348
349/** Used by the handleMetricsCollect loop. */
350static bool volatile g_fKeepGoing = true;
351
352#ifdef RT_OS_WINDOWS
353/**
354 * Handler routine for catching Ctrl-C, Ctrl-Break and closing of
355 * the console.
356 *
357 * @returns true if handled, false if not handled.
358 * @param dwCtrlType The type of control signal.
359 *
360 * @remarks This is called on a new thread.
361 */
362static BOOL WINAPI ctrlHandler(DWORD dwCtrlType)
363{
364 switch (dwCtrlType)
365 {
366 /* Ctrl-C or Ctrl-Break or Close */
367 case CTRL_C_EVENT:
368 case CTRL_BREAK_EVENT:
369 case CTRL_CLOSE_EVENT:
370 /* Let's shut down gracefully. */
371 ASMAtomicWriteBool(&g_fKeepGoing, false);
372 return TRUE;
373 }
374 /* Don't care about the rest -- let it die a horrible death. */
375 return FALSE;
376}
377#endif /* RT_OS_WINDOWS */
378
379/**
380 * collect
381 */
382static int handleMetricsCollect(int argc, char *argv[],
383 ComPtr<IVirtualBox> aVirtualBox,
384 ComPtr<IPerformanceCollector> performanceCollector)
385{
386 HRESULT rc;
387 com::SafeArray<BSTR> metrics;
388 com::SafeIfaceArray<IUnknown> objects;
389 uint32_t period = 1, samples = 1;
390 bool isDetached = false, listMatches = false;
391 int i;
392 for (i = 1; i < argc; i++)
393 {
394 if ( !strcmp(argv[i], "--period")
395 || !strcmp(argv[i], "-period"))
396 {
397 if (argc <= i + 1)
398 return errorArgument("Missing argument to '%s'", argv[i]);
399 if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
400 || !period)
401 return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
402 }
403 else if ( !strcmp(argv[i], "--samples")
404 || !strcmp(argv[i], "-samples"))
405 {
406 if (argc <= i + 1)
407 return errorArgument("Missing argument to '%s'", argv[i]);
408 if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
409 || !samples)
410 return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
411 }
412 else if ( !strcmp(argv[i], "--list")
413 || !strcmp(argv[i], "-list"))
414 listMatches = true;
415 else if ( !strcmp(argv[i], "--detach")
416 || !strcmp(argv[i], "-detach"))
417 isDetached = true;
418 else
419 break; /* The rest of params should define the filter */
420 }
421
422 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
423 ComSafeArrayAsOutParam(metrics),
424 ComSafeArrayAsOutParam(objects));
425 if (FAILED(rc))
426 return 1;
427
428 com::SafeIfaceArray<IPerformanceMetric> metricInfo;
429
430 CHECK_ERROR(performanceCollector,
431 GetMetrics(ComSafeArrayAsInParam(metrics),
432 ComSafeArrayAsInParam(objects),
433 ComSafeArrayAsOutParam(metricInfo)));
434
435 std::set<std::pair<ComPtr<IUnknown>,Bstr> > baseMetrics;
436 ComPtr<IUnknown> objectFiltered;
437 Bstr metricNameFiltered;
438 for (i = 0; i < (int)metricInfo.size(); i++)
439 {
440 CHECK_ERROR(metricInfo[i], COMGETTER(Object)(objectFiltered.asOutParam()));
441 CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricNameFiltered.asOutParam()));
442 Utf8Str baseMetricName(metricNameFiltered);
443 baseMetrics.insert(std::make_pair(objectFiltered, toBaseName(baseMetricName)));
444 }
445 com::SafeArray<BSTR> baseMetricsFiltered(baseMetrics.size());
446 com::SafeIfaceArray<IUnknown> objectsFiltered(baseMetrics.size());
447 std::set<std::pair<ComPtr<IUnknown>,Bstr> >::iterator it;
448 i = 0;
449 for (it = baseMetrics.begin(); it != baseMetrics.end(); ++it)
450 {
451 it->first.queryInterfaceTo(&objectsFiltered[i]);
452 Bstr(it->second).detachTo(&baseMetricsFiltered[i++]);
453 }
454 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
455 CHECK_ERROR(performanceCollector,
456 SetupMetrics(ComSafeArrayAsInParam(baseMetricsFiltered),
457 ComSafeArrayAsInParam(objectsFiltered), period, samples,
458 ComSafeArrayAsOutParam(affectedMetrics)));
459 if (FAILED(rc))
460 return 2;
461
462 if (listMatches)
463 listAffectedMetrics(aVirtualBox,
464 ComSafeArrayAsInParam(affectedMetrics));
465 if (!affectedMetrics.size())
466 return 1;
467
468 if (isDetached)
469 {
470 RTMsgWarning("The background process holding collected metrics will shutdown\n"
471 "in few seconds, discarding all collected data and parameters.");
472 return 0;
473 }
474
475#ifdef RT_OS_WINDOWS
476 SetConsoleCtrlHandler(ctrlHandler, true);
477#endif /* RT_OS_WINDOWS */
478
479 RTPrintf("Time stamp Object Metric Value\n");
480
481 while (g_fKeepGoing)
482 {
483 RTPrintf("------------ ---------- -------------------- --------------------\n");
484 RTThreadSleep(period * 1000); // Sleep for 'period' seconds
485 char ts[15];
486
487 getTimestamp(ts, sizeof(ts));
488 com::SafeArray<BSTR> retNames;
489 com::SafeIfaceArray<IUnknown> retObjects;
490 com::SafeArray<BSTR> retUnits;
491 com::SafeArray<ULONG> retScales;
492 com::SafeArray<ULONG> retSequenceNumbers;
493 com::SafeArray<ULONG> retIndices;
494 com::SafeArray<ULONG> retLengths;
495 com::SafeArray<LONG> retData;
496 CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
497 ComSafeArrayAsInParam(objects),
498 ComSafeArrayAsOutParam(retNames),
499 ComSafeArrayAsOutParam(retObjects),
500 ComSafeArrayAsOutParam(retUnits),
501 ComSafeArrayAsOutParam(retScales),
502 ComSafeArrayAsOutParam(retSequenceNumbers),
503 ComSafeArrayAsOutParam(retIndices),
504 ComSafeArrayAsOutParam(retLengths),
505 ComSafeArrayAsOutParam(retData)) );
506 for (unsigned j = 0; j < retNames.size(); j++)
507 {
508 Bstr metricUnit(retUnits[j]);
509 Bstr metricName(retNames[j]);
510 RTPrintf("%-12s %-10ls %-20ls ", ts, getObjectName(aVirtualBox, retObjects[j]).raw(), metricName.raw());
511 const char *separator = "";
512 for (unsigned k = 0; k < retLengths[j]; k++)
513 {
514 if (retScales[j] == 1)
515 RTPrintf("%s%d %ls", separator, retData[retIndices[j] + k], metricUnit.raw());
516 else
517 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[j] + k] / retScales[j],
518 (retData[retIndices[j] + k] * 100 / retScales[j]) % 100, metricUnit.raw());
519 separator = ", ";
520 }
521 RTPrintf("\n");
522 }
523 RTStrmFlush(g_pStdOut);
524 }
525
526#ifdef RT_OS_WINDOWS
527 SetConsoleCtrlHandler(ctrlHandler, false);
528#endif /* RT_OS_WINDOWS */
529
530 return 0;
531}
532
533/**
534 * Enable metrics
535 */
536static int handleMetricsEnable(int argc, char *argv[],
537 ComPtr<IVirtualBox> aVirtualBox,
538 ComPtr<IPerformanceCollector> performanceCollector)
539{
540 HRESULT rc;
541 com::SafeArray<BSTR> metrics;
542 com::SafeIfaceArray<IUnknown> objects;
543 bool listMatches = false;
544 int i;
545
546 for (i = 1; i < argc; i++)
547 {
548 if ( !strcmp(argv[i], "--list")
549 || !strcmp(argv[i], "-list"))
550 listMatches = true;
551 else
552 break; /* The rest of params should define the filter */
553 }
554
555 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
556 ComSafeArrayAsOutParam(metrics),
557 ComSafeArrayAsOutParam(objects));
558 if (FAILED(rc))
559 return 1;
560
561 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
562 CHECK_ERROR(performanceCollector,
563 EnableMetrics(ComSafeArrayAsInParam(metrics),
564 ComSafeArrayAsInParam(objects),
565 ComSafeArrayAsOutParam(affectedMetrics)));
566 if (FAILED(rc))
567 return 2;
568
569 if (listMatches)
570 listAffectedMetrics(aVirtualBox,
571 ComSafeArrayAsInParam(affectedMetrics));
572
573 return 0;
574}
575
576/**
577 * Disable metrics
578 */
579static int handleMetricsDisable(int argc, char *argv[],
580 ComPtr<IVirtualBox> aVirtualBox,
581 ComPtr<IPerformanceCollector> performanceCollector)
582{
583 HRESULT rc;
584 com::SafeArray<BSTR> metrics;
585 com::SafeIfaceArray<IUnknown> objects;
586 bool listMatches = false;
587 int i;
588
589 for (i = 1; i < argc; i++)
590 {
591 if ( !strcmp(argv[i], "--list")
592 || !strcmp(argv[i], "-list"))
593 listMatches = true;
594 else
595 break; /* The rest of params should define the filter */
596 }
597
598 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
599 ComSafeArrayAsOutParam(metrics),
600 ComSafeArrayAsOutParam(objects));
601 if (FAILED(rc))
602 return 1;
603
604 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
605 CHECK_ERROR(performanceCollector,
606 DisableMetrics(ComSafeArrayAsInParam(metrics),
607 ComSafeArrayAsInParam(objects),
608 ComSafeArrayAsOutParam(affectedMetrics)));
609 if (FAILED(rc))
610 return 2;
611
612 if (listMatches)
613 listAffectedMetrics(aVirtualBox,
614 ComSafeArrayAsInParam(affectedMetrics));
615
616 return 0;
617}
618
619
620int handleMetrics(HandlerArg *a)
621{
622 int rc;
623
624 /* at least one option: subcommand name */
625 if (a->argc < 1)
626 return errorSyntax(USAGE_METRICS, "Subcommand missing");
627
628 ComPtr<IPerformanceCollector> performanceCollector;
629 CHECK_ERROR(a->virtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam()));
630
631 if (!strcmp(a->argv[0], "list"))
632 rc = handleMetricsList(a->argc, a->argv, a->virtualBox, performanceCollector);
633 else if (!strcmp(a->argv[0], "setup"))
634 rc = handleMetricsSetup(a->argc, a->argv, a->virtualBox, performanceCollector);
635 else if (!strcmp(a->argv[0], "query"))
636 rc = handleMetricsQuery(a->argc, a->argv, a->virtualBox, performanceCollector);
637 else if (!strcmp(a->argv[0], "collect"))
638 rc = handleMetricsCollect(a->argc, a->argv, a->virtualBox, performanceCollector);
639 else if (!strcmp(a->argv[0], "enable"))
640 rc = handleMetricsEnable(a->argc, a->argv, a->virtualBox, performanceCollector);
641 else if (!strcmp(a->argv[0], "disable"))
642 rc = handleMetricsDisable(a->argc, a->argv, a->virtualBox, performanceCollector);
643 else
644 return errorSyntax(USAGE_METRICS, "Invalid subcommand '%s'", a->argv[0]);
645
646 return rc;
647}
648
649#endif /* VBOX_ONLY_DOCS */
650
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use