| 7589 | | static int parseFilterParameters(int argc, char *argv[], |
|---|
| 7590 | | ComPtr<IVirtualBox> aVirtualBox, |
|---|
| 7591 | | ComSafeArrayOut(BSTR, outMetrics), |
|---|
| 7592 | | ComSafeArrayOut(IUnknown *, outObjects)) |
|---|
| 7593 | | { |
|---|
| 7594 | | HRESULT rc = S_OK; |
|---|
| 7595 | | com::SafeArray<BSTR> retMetrics(1); |
|---|
| 7596 | | com::SafeIfaceArray <IUnknown> retObjects; |
|---|
| 7597 | | |
|---|
| 7598 | | Bstr metricNames; |
|---|
| 7599 | | |
|---|
| 7600 | | /* Metric list */ |
|---|
| 7601 | | if (argc > 1) |
|---|
| 7602 | | metricNames = argv[1]; |
|---|
| 7603 | | else |
|---|
| 7604 | | metricNames = L"*"; |
|---|
| 7605 | | metricNames.cloneTo(&retMetrics[0]); |
|---|
| 7606 | | |
|---|
| 7607 | | /* Object name */ |
|---|
| 7608 | | if (argc > 0 && strcmp(argv[0], "*")) |
|---|
| 7609 | | { |
|---|
| 7610 | | if (!strcmp(argv[0], "host")) |
|---|
| 7611 | | { |
|---|
| 7612 | | ComPtr<IHost> host; |
|---|
| 7613 | | CHECK_ERROR(aVirtualBox, COMGETTER(Host)(host.asOutParam())); |
|---|
| 7614 | | retObjects.reset(1); |
|---|
| 7615 | | host.queryInterfaceTo(&retObjects[0]); |
|---|
| 7616 | | } |
|---|
| 7617 | | else |
|---|
| 7618 | | { |
|---|
| 7619 | | ComPtr <IMachine> machine; |
|---|
| 7620 | | rc = aVirtualBox->FindMachine(Bstr(argv[0]), machine.asOutParam()); |
|---|
| 7621 | | if (SUCCEEDED (rc)) |
|---|
| 7622 | | { |
|---|
| 7623 | | retObjects.reset(1); |
|---|
| 7624 | | machine.queryInterfaceTo(&retObjects[0]); |
|---|
| 7625 | | } |
|---|
| 7626 | | else |
|---|
| 7627 | | { |
|---|
| 7628 | | errorArgument("Invalid machine name: '%s'", argv[0]); |
|---|
| 7629 | | return rc; |
|---|
| 7630 | | } |
|---|
| 7631 | | } |
|---|
| 7632 | | |
|---|
| 7633 | | } |
|---|
| 7634 | | |
|---|
| 7635 | | retMetrics.detachTo(outMetrics); |
|---|
| 7636 | | retObjects.detachTo(outObjects); |
|---|
| 7637 | | |
|---|
| 7638 | | return rc; |
|---|
| 7639 | | } |
|---|
| 7640 | | |
|---|
| 7641 | | static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox, |
|---|
| 7642 | | ComPtr<IUnknown> aObject) |
|---|
| 7643 | | { |
|---|
| 7644 | | HRESULT rc; |
|---|
| 7645 | | |
|---|
| 7646 | | ComPtr<IHost> host = aObject; |
|---|
| 7647 | | if (!host.isNull()) |
|---|
| 7648 | | return Bstr("host"); |
|---|
| 7649 | | |
|---|
| 7650 | | ComPtr<IMachine> machine = aObject; |
|---|
| 7651 | | if (!machine.isNull()) |
|---|
| 7652 | | { |
|---|
| 7653 | | Bstr name; |
|---|
| 7654 | | CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam())); |
|---|
| 7655 | | if (SUCCEEDED(rc)) |
|---|
| 7656 | | return name; |
|---|
| 7657 | | } |
|---|
| 7658 | | return Bstr("unknown"); |
|---|
| 7659 | | } |
|---|
| 7660 | | |
|---|
| 7661 | | static int handleMetrics(int argc, char *argv[], |
|---|
| 7662 | | ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession) |
|---|
| 7663 | | { |
|---|
| 7664 | | HRESULT rc; |
|---|
| 7665 | | com::SafeArray<BSTR> metrics; |
|---|
| 7666 | | com::SafeIfaceArray<IUnknown> objects; |
|---|
| 7667 | | |
|---|
| 7668 | | /* at least one option: sub-command name */ |
|---|
| 7669 | | if (argc < 1) |
|---|
| 7670 | | return errorSyntax(USAGE_METRICS, "Sub-command missing"); |
|---|
| 7671 | | |
|---|
| 7672 | | ComPtr<IPerformanceCollector> performanceCollector; |
|---|
| 7673 | | CHECK_ERROR(aVirtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam())); |
|---|
| 7674 | | |
|---|
| 7675 | | if (!strcmp(argv[0], "list")) |
|---|
| 7676 | | { |
|---|
| 7677 | | /********************************************************************* |
|---|
| 7678 | | * list * |
|---|
| 7679 | | *********************************************************************/ |
|---|
| 7680 | | rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox, |
|---|
| 7681 | | ComSafeArrayAsOutParam(metrics), |
|---|
| 7682 | | ComSafeArrayAsOutParam(objects)); |
|---|
| 7683 | | if (FAILED(rc)) |
|---|
| 7684 | | return 1; |
|---|
| 7685 | | |
|---|
| 7686 | | com::SafeIfaceArray<IPerformanceMetric> metricInfo; |
|---|
| 7687 | | |
|---|
| 7688 | | CHECK_ERROR(performanceCollector, |
|---|
| 7689 | | GetMetrics(ComSafeArrayAsInParam(metrics), |
|---|
| 7690 | | ComSafeArrayAsInParam(objects), |
|---|
| 7691 | | ComSafeArrayAsOutParam(metricInfo))); |
|---|
| 7692 | | |
|---|
| 7693 | | ComPtr<IUnknown> object; |
|---|
| 7694 | | Bstr metricName, unit; |
|---|
| 7695 | | ULONG period, count; |
|---|
| 7696 | | LONG minimum, maximum; |
|---|
| 7697 | | RTPrintf("Object Metric Unit Minimum Maximum Period Count\n" |
|---|
| 7698 | | "---------- -------------------- ---- ---------- ---------- ---------- ----------\n"); |
|---|
| 7699 | | for (size_t i = 0; i < metricInfo.size(); i++) |
|---|
| 7700 | | { |
|---|
| 7701 | | CHECK_ERROR(metricInfo[i], COMGETTER(Object)(object.asOutParam())); |
|---|
| 7702 | | CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricName.asOutParam())); |
|---|
| 7703 | | CHECK_ERROR(metricInfo[i], COMGETTER(Period)(&period)); |
|---|
| 7704 | | CHECK_ERROR(metricInfo[i], COMGETTER(Count)(&count)); |
|---|
| 7705 | | CHECK_ERROR(metricInfo[i], COMGETTER(MinimumValue)(&minimum)); |
|---|
| 7706 | | CHECK_ERROR(metricInfo[i], COMGETTER(MaximumValue)(&maximum)); |
|---|
| 7707 | | CHECK_ERROR(metricInfo[i], COMGETTER(Unit)(unit.asOutParam())); |
|---|
| 7708 | | RTPrintf("%-10ls %-20ls %-4ls %10d %10d %10u %10u\n", |
|---|
| 7709 | | getObjectName(aVirtualBox, object), metricName.raw(), unit.raw(), |
|---|
| 7710 | | minimum, maximum, period, count); |
|---|
| 7711 | | } |
|---|
| 7712 | | } |
|---|
| 7713 | | else if (!strcmp(argv[0], "setup")) |
|---|
| 7714 | | { |
|---|
| 7715 | | /********************************************************************* |
|---|
| 7716 | | * setup * |
|---|
| 7717 | | *********************************************************************/ |
|---|
| 7718 | | if (argc < 3) |
|---|
| 7719 | | return errorSyntax(USAGE_METRICS, "Missing parameters for '%s' subcommand", argv[0]); |
|---|
| 7720 | | |
|---|
| 7721 | | ULONG period, count; |
|---|
| 7722 | | char *endptr = NULL; |
|---|
| 7723 | | |
|---|
| 7724 | | period = strtoul (argv[1], &endptr, 10); |
|---|
| 7725 | | if (!endptr || *endptr) |
|---|
| 7726 | | return errorArgument("Invalid value for 'period' parameter: '%s'", argv[1]); |
|---|
| 7727 | | |
|---|
| 7728 | | count = strtoul (argv[2], &endptr, 10); |
|---|
| 7729 | | if (!endptr || *endptr) |
|---|
| 7730 | | return errorArgument("Invalid value for 'count' parameter: '%s'", argv[2]); |
|---|
| 7731 | | |
|---|
| 7732 | | rc = parseFilterParameters(argc - 3, &argv[3], aVirtualBox, |
|---|
| 7733 | | ComSafeArrayAsOutParam(metrics), |
|---|
| 7734 | | ComSafeArrayAsOutParam(objects)); |
|---|
| 7735 | | if (FAILED(rc)) |
|---|
| 7736 | | return 1; |
|---|
| 7737 | | |
|---|
| 7738 | | CHECK_ERROR(performanceCollector, |
|---|
| 7739 | | SetupMetrics(ComSafeArrayAsInParam(metrics), |
|---|
| 7740 | | ComSafeArrayAsInParam(objects), period, count)); |
|---|
| 7741 | | } |
|---|
| 7742 | | else if (!strcmp(argv[0], "query")) |
|---|
| 7743 | | { |
|---|
| 7744 | | /********************************************************************* |
|---|
| 7745 | | * query * |
|---|
| 7746 | | *********************************************************************/ |
|---|
| 7747 | | rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox, |
|---|
| 7748 | | ComSafeArrayAsOutParam(metrics), |
|---|
| 7749 | | ComSafeArrayAsOutParam(objects)); |
|---|
| 7750 | | if (FAILED(rc)) |
|---|
| 7751 | | return 1; |
|---|
| 7752 | | |
|---|
| 7753 | | com::SafeArray<BSTR> retNames; |
|---|
| 7754 | | com::SafeIfaceArray<IUnknown> retObjects; |
|---|
| 7755 | | com::SafeArray<ULONG> retIndices; |
|---|
| 7756 | | com::SafeArray<ULONG> retLengths; |
|---|
| 7757 | | com::SafeArray<LONG> retData; |
|---|
| 7758 | | CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics), |
|---|
| 7759 | | ComSafeArrayAsInParam(objects), |
|---|
| 7760 | | ComSafeArrayAsOutParam(retNames), |
|---|
| 7761 | | ComSafeArrayAsOutParam(retObjects), |
|---|
| 7762 | | ComSafeArrayAsOutParam(retIndices), |
|---|
| 7763 | | ComSafeArrayAsOutParam(retLengths), |
|---|
| 7764 | | ComSafeArrayAsOutParam(retData)) ); |
|---|
| 7765 | | |
|---|
| 7766 | | RTPrintf("Object Metric Values\n" |
|---|
| 7767 | | "---------- -------------------- --------------------------------------------\n"); |
|---|
| 7768 | | for (unsigned i = 0; i < retNames.size(); i++) |
|---|
| 7769 | | { |
|---|
| 7770 | | // Get info for the metric |
|---|
| 7771 | | com::SafeArray<BSTR> nameOfMetric(1); |
|---|
| 7772 | | Bstr tmpName(retNames[i]); |
|---|
| 7773 | | tmpName.detachTo (&nameOfMetric[0]); |
|---|
| 7774 | | com::SafeIfaceArray<IUnknown> anObject(1); |
|---|
| 7775 | | ComPtr<IUnknown> tmpObject(retObjects[i]); |
|---|
| 7776 | | tmpObject.queryInterfaceTo(&anObject[0]); |
|---|
| 7777 | | com::SafeIfaceArray <IPerformanceMetric> metricInfo; |
|---|
| 7778 | | CHECK_RC_BREAK (performanceCollector->GetMetrics( ComSafeArrayAsInParam(nameOfMetric), |
|---|
| 7779 | | ComSafeArrayAsInParam(anObject), |
|---|
| 7780 | | ComSafeArrayAsOutParam(metricInfo) )); |
|---|
| 7781 | | BSTR metricUnitBSTR; |
|---|
| 7782 | | CHECK_RC_BREAK (metricInfo[0]->COMGETTER(Unit) (&metricUnitBSTR)); |
|---|
| 7783 | | Bstr metricUnit(metricUnitBSTR); |
|---|
| 7784 | | Bstr metricName(retNames[i]); |
|---|
| 7785 | | LONG minVal, maxVal; |
|---|
| 7786 | | CHECK_RC_BREAK (metricInfo[0]->COMGETTER(MinimumValue) (&minVal)); |
|---|
| 7787 | | CHECK_RC_BREAK (metricInfo[0]->COMGETTER(MaximumValue) (&maxVal)); |
|---|
| 7788 | | RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]), metricName.raw()); |
|---|
| 7789 | | const char *separator = ""; |
|---|
| 7790 | | for (unsigned j = 0; j < retLengths[i]; j++) |
|---|
| 7791 | | { |
|---|
| 7792 | | if (strcmp((const char *)metricUnit.raw(), "%")) |
|---|
| 7793 | | RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw()); |
|---|
| 7794 | | else |
|---|
| 7795 | | RTPrintf("%s%d.%02d%%", separator, retData[retIndices[i] + j] / 1000, retData[retIndices[i] + j] % 100); |
|---|
| 7796 | | separator = ", "; |
|---|
| 7797 | | } |
|---|
| 7798 | | RTPrintf("\n"); |
|---|
| 7799 | | } |
|---|
| 7800 | | } |
|---|
| 7801 | | else |
|---|
| 7802 | | { |
|---|
| 7803 | | return errorSyntax(USAGE_METRICS, "Invalid subcommand '%s'", argv[0]); |
|---|
| 7804 | | } |
|---|
| 7805 | | |
|---|
| 7806 | | return SUCCEEDED(rc) ? 0 : 1; |
|---|
| 7807 | | } |
|---|
| 7808 | | |
|---|