VirtualBox

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

Last change on this file since 40081 was 40081, checked in by vboxsync, 13 years ago

VBoxManage: metrics collect fix for guest metrics

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette