VirtualBox

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

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

Main/Metrics: All calls to VM processes are done in separate thread (#6029)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.2 KB
Line 
1/* $Id: VBoxManageMetrics.cpp 40358 2012-03-05 14:40:52Z 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 (FAILED(rc))
306 return 2;
307
308 if (listMatches)
309 listAffectedMetrics(aVirtualBox,
310 ComSafeArrayAsInParam(affectedMetrics));
311
312 return 0;
313}
314
315/**
316 * metrics query
317 */
318static int handleMetricsQuery(int argc, char *argv[],
319 ComPtr<IVirtualBox> aVirtualBox,
320 ComPtr<IPerformanceCollector> performanceCollector)
321{
322 HRESULT rc;
323 com::SafeArray<BSTR> metrics;
324 com::SafeArray<BSTR> baseMetrics;
325 com::SafeIfaceArray<IUnknown> objects;
326
327 rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
328 ComSafeArrayAsOutParam(metrics),
329 ComSafeArrayAsOutParam(baseMetrics),
330 ComSafeArrayAsOutParam(objects));
331 if (FAILED(rc))
332 return 1;
333
334 com::SafeArray<BSTR> retNames;
335 com::SafeIfaceArray<IUnknown> retObjects;
336 com::SafeArray<BSTR> retUnits;
337 com::SafeArray<ULONG> retScales;
338 com::SafeArray<ULONG> retSequenceNumbers;
339 com::SafeArray<ULONG> retIndices;
340 com::SafeArray<ULONG> retLengths;
341 com::SafeArray<LONG> retData;
342 CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
343 ComSafeArrayAsInParam(objects),
344 ComSafeArrayAsOutParam(retNames),
345 ComSafeArrayAsOutParam(retObjects),
346 ComSafeArrayAsOutParam(retUnits),
347 ComSafeArrayAsOutParam(retScales),
348 ComSafeArrayAsOutParam(retSequenceNumbers),
349 ComSafeArrayAsOutParam(retIndices),
350 ComSafeArrayAsOutParam(retLengths),
351 ComSafeArrayAsOutParam(retData)) );
352
353 RTPrintf("Object Metric Values\n"
354 "---------- -------------------- --------------------------------------------\n");
355 for (unsigned i = 0; i < retNames.size(); i++)
356 {
357 Bstr metricUnit(retUnits[i]);
358 Bstr metricName(retNames[i]);
359 RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
360 const char *separator = "";
361 for (unsigned j = 0; j < retLengths[i]; j++)
362 {
363 if (retScales[i] == 1)
364 RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
365 else
366 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
367 (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
368 separator = ", ";
369 }
370 RTPrintf("\n");
371 }
372
373 return 0;
374}
375
376static void getTimestamp(char *pts, size_t tsSize)
377{
378 *pts = 0;
379 AssertReturnVoid(tsSize >= 13); /* 3+3+3+3+1 */
380 RTTIMESPEC TimeSpec;
381 RTTIME Time;
382 RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
383 pts += RTStrFormatNumber(pts, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
384 *pts++ = ':';
385 pts += RTStrFormatNumber(pts, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
386 *pts++ = ':';
387 pts += RTStrFormatNumber(pts, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
388 *pts++ = '.';
389 pts += RTStrFormatNumber(pts, Time.u32Nanosecond / 1000000, 10, 3, 0, RTSTR_F_ZEROPAD);
390 *pts = 0;
391}
392
393/** Used by the handleMetricsCollect loop. */
394static bool volatile g_fKeepGoing = true;
395
396#ifdef RT_OS_WINDOWS
397/**
398 * Handler routine for catching Ctrl-C, Ctrl-Break and closing of
399 * the console.
400 *
401 * @returns true if handled, false if not handled.
402 * @param dwCtrlType The type of control signal.
403 *
404 * @remarks This is called on a new thread.
405 */
406static BOOL WINAPI ctrlHandler(DWORD dwCtrlType)
407{
408 switch (dwCtrlType)
409 {
410 /* Ctrl-C or Ctrl-Break or Close */
411 case CTRL_C_EVENT:
412 case CTRL_BREAK_EVENT:
413 case CTRL_CLOSE_EVENT:
414 /* Let's shut down gracefully. */
415 ASMAtomicWriteBool(&g_fKeepGoing, false);
416 return TRUE;
417 }
418 /* Don't care about the rest -- let it die a horrible death. */
419 return FALSE;
420}
421#endif /* RT_OS_WINDOWS */
422
423/**
424 * collect
425 */
426static int handleMetricsCollect(int argc, char *argv[],
427 ComPtr<IVirtualBox> aVirtualBox,
428 ComPtr<IPerformanceCollector> performanceCollector)
429{
430 HRESULT rc;
431 com::SafeArray<BSTR> metrics;
432 com::SafeArray<BSTR> baseMetrics;
433 com::SafeIfaceArray<IUnknown> objects;
434 uint32_t period = 1, samples = 1;
435 bool isDetached = false, listMatches = false;
436 int i;
437 for (i = 1; i < argc; i++)
438 {
439 if ( !strcmp(argv[i], "--period")
440 || !strcmp(argv[i], "-period"))
441 {
442 if (argc <= i + 1)
443 return errorArgument("Missing argument to '%s'", argv[i]);
444 if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
445 || !period)
446 return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
447 }
448 else if ( !strcmp(argv[i], "--samples")
449 || !strcmp(argv[i], "-samples"))
450 {
451 if (argc <= i + 1)
452 return errorArgument("Missing argument to '%s'", argv[i]);
453 if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
454 || !samples)
455 return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
456 }
457 else if ( !strcmp(argv[i], "--list")
458 || !strcmp(argv[i], "-list"))
459 listMatches = true;
460 else if ( !strcmp(argv[i], "--detach")
461 || !strcmp(argv[i], "-detach"))
462 isDetached = true;
463 else
464 break; /* The rest of params should define the filter */
465 }
466
467 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
468 ComSafeArrayAsOutParam(metrics),
469 ComSafeArrayAsOutParam(baseMetrics),
470 ComSafeArrayAsOutParam(objects));
471 if (FAILED(rc))
472 return 1;
473
474
475 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
476 CHECK_ERROR(performanceCollector,
477 SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
478 ComSafeArrayAsInParam(objects), period, samples,
479 ComSafeArrayAsOutParam(affectedMetrics)));
480 if (FAILED(rc))
481 return 2;
482
483 if (listMatches)
484 listAffectedMetrics(aVirtualBox,
485 ComSafeArrayAsInParam(affectedMetrics));
486 if (!affectedMetrics.size())
487 return 1;
488
489 if (isDetached)
490 {
491 RTMsgWarning("The background process holding collected metrics will shutdown\n"
492 "in few seconds, discarding all collected data and parameters.");
493 return 0;
494 }
495
496#ifdef RT_OS_WINDOWS
497 SetConsoleCtrlHandler(ctrlHandler, true);
498#endif /* RT_OS_WINDOWS */
499
500 RTPrintf("Time stamp Object Metric Value\n");
501
502 while (g_fKeepGoing)
503 {
504 RTPrintf("------------ ---------- -------------------- --------------------\n");
505 RTThreadSleep(period * 1000); // Sleep for 'period' seconds
506 char ts[15];
507
508 getTimestamp(ts, sizeof(ts));
509 com::SafeArray<BSTR> retNames;
510 com::SafeIfaceArray<IUnknown> retObjects;
511 com::SafeArray<BSTR> retUnits;
512 com::SafeArray<ULONG> retScales;
513 com::SafeArray<ULONG> retSequenceNumbers;
514 com::SafeArray<ULONG> retIndices;
515 com::SafeArray<ULONG> retLengths;
516 com::SafeArray<LONG> retData;
517 CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
518 ComSafeArrayAsInParam(objects),
519 ComSafeArrayAsOutParam(retNames),
520 ComSafeArrayAsOutParam(retObjects),
521 ComSafeArrayAsOutParam(retUnits),
522 ComSafeArrayAsOutParam(retScales),
523 ComSafeArrayAsOutParam(retSequenceNumbers),
524 ComSafeArrayAsOutParam(retIndices),
525 ComSafeArrayAsOutParam(retLengths),
526 ComSafeArrayAsOutParam(retData)) );
527 for (unsigned j = 0; j < retNames.size(); j++)
528 {
529 Bstr metricUnit(retUnits[j]);
530 Bstr metricName(retNames[j]);
531 RTPrintf("%-12s %-10ls %-20ls ", ts, getObjectName(aVirtualBox, retObjects[j]).raw(), metricName.raw());
532 const char *separator = "";
533 for (unsigned k = 0; k < retLengths[j]; k++)
534 {
535 if (retScales[j] == 1)
536 RTPrintf("%s%d %ls", separator, retData[retIndices[j] + k], metricUnit.raw());
537 else
538 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[j] + k] / retScales[j],
539 (retData[retIndices[j] + k] * 100 / retScales[j]) % 100, metricUnit.raw());
540 separator = ", ";
541 }
542 RTPrintf("\n");
543 }
544 RTStrmFlush(g_pStdOut);
545 }
546
547#ifdef RT_OS_WINDOWS
548 SetConsoleCtrlHandler(ctrlHandler, false);
549#endif /* RT_OS_WINDOWS */
550
551 return 0;
552}
553
554/**
555 * Enable metrics
556 */
557static int handleMetricsEnable(int argc, char *argv[],
558 ComPtr<IVirtualBox> aVirtualBox,
559 ComPtr<IPerformanceCollector> performanceCollector)
560{
561 HRESULT rc;
562 com::SafeArray<BSTR> metrics;
563 com::SafeArray<BSTR> baseMetrics;
564 com::SafeIfaceArray<IUnknown> objects;
565 bool listMatches = false;
566 int i;
567
568 for (i = 1; i < argc; i++)
569 {
570 if ( !strcmp(argv[i], "--list")
571 || !strcmp(argv[i], "-list"))
572 listMatches = true;
573 else
574 break; /* The rest of params should define the filter */
575 }
576
577 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
578 ComSafeArrayAsOutParam(metrics),
579 ComSafeArrayAsOutParam(baseMetrics),
580 ComSafeArrayAsOutParam(objects));
581 if (FAILED(rc))
582 return 1;
583
584 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
585 CHECK_ERROR(performanceCollector,
586 EnableMetrics(ComSafeArrayAsInParam(metrics),
587 ComSafeArrayAsInParam(objects),
588 ComSafeArrayAsOutParam(affectedMetrics)));
589 if (FAILED(rc))
590 return 2;
591
592 if (listMatches)
593 listAffectedMetrics(aVirtualBox,
594 ComSafeArrayAsInParam(affectedMetrics));
595
596 return 0;
597}
598
599/**
600 * Disable metrics
601 */
602static int handleMetricsDisable(int argc, char *argv[],
603 ComPtr<IVirtualBox> aVirtualBox,
604 ComPtr<IPerformanceCollector> performanceCollector)
605{
606 HRESULT rc;
607 com::SafeArray<BSTR> metrics;
608 com::SafeArray<BSTR> baseMetrics;
609 com::SafeIfaceArray<IUnknown> objects;
610 bool listMatches = false;
611 int i;
612
613 for (i = 1; i < argc; i++)
614 {
615 if ( !strcmp(argv[i], "--list")
616 || !strcmp(argv[i], "-list"))
617 listMatches = true;
618 else
619 break; /* The rest of params should define the filter */
620 }
621
622 rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
623 ComSafeArrayAsOutParam(metrics),
624 ComSafeArrayAsOutParam(baseMetrics),
625 ComSafeArrayAsOutParam(objects));
626 if (FAILED(rc))
627 return 1;
628
629 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
630 CHECK_ERROR(performanceCollector,
631 DisableMetrics(ComSafeArrayAsInParam(metrics),
632 ComSafeArrayAsInParam(objects),
633 ComSafeArrayAsOutParam(affectedMetrics)));
634 if (FAILED(rc))
635 return 2;
636
637 if (listMatches)
638 listAffectedMetrics(aVirtualBox,
639 ComSafeArrayAsInParam(affectedMetrics));
640
641 return 0;
642}
643
644
645int handleMetrics(HandlerArg *a)
646{
647 int rc;
648
649 /* at least one option: subcommand name */
650 if (a->argc < 1)
651 return errorSyntax(USAGE_METRICS, "Subcommand missing");
652
653 ComPtr<IPerformanceCollector> performanceCollector;
654 CHECK_ERROR(a->virtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam()));
655
656 if (!strcmp(a->argv[0], "list"))
657 rc = handleMetricsList(a->argc, a->argv, a->virtualBox, performanceCollector);
658 else if (!strcmp(a->argv[0], "setup"))
659 rc = handleMetricsSetup(a->argc, a->argv, a->virtualBox, performanceCollector);
660 else if (!strcmp(a->argv[0], "query"))
661 rc = handleMetricsQuery(a->argc, a->argv, a->virtualBox, performanceCollector);
662 else if (!strcmp(a->argv[0], "collect"))
663 rc = handleMetricsCollect(a->argc, a->argv, a->virtualBox, performanceCollector);
664 else if (!strcmp(a->argv[0], "enable"))
665 rc = handleMetricsEnable(a->argc, a->argv, a->virtualBox, performanceCollector);
666 else if (!strcmp(a->argv[0], "disable"))
667 rc = handleMetricsDisable(a->argc, a->argv, a->virtualBox, performanceCollector);
668 else
669 return errorSyntax(USAGE_METRICS, "Invalid subcommand '%s'", a->argv[0]);
670
671 return rc;
672}
673
674#endif /* VBOX_ONLY_DOCS */
675
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