VirtualBox

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

Last change on this file since 56301 was 56118, checked in by vboxsync, 9 years ago

VBoxManage: A quick command handler return-code cleanup that turned out to be rather tedious.

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