Allows to subscribe to receive host OS statistics on a periodic basis.
PRL_HANDLE PrlSrv_SubscribeToHostStatistics( PRL_HANDLE hServer );
PrlApiStat.h
A handle of type PHT_JOB containing the results of this asynchronous operation or PRL_INVALID_HANDLE if there's not enough memory to instantiate the job object.
To obtain statistics, an event handler (callback function) is required. Within the event handler, first check the type of event. Events of type PET_DSP_EVT_HOST_STATISTICS_UPDATED indicate an event containing statistics data. To access the statistics handle (a handle of type PHT_SYSTEM_STATISTICS), first extract the event parameter using PrlEvent_GetParam, then convert the result (which will be a handle to an object of type PHT_EVENT_PARAMETER) to a handle using PrlEvtPrm_ToHandle. The functions that operate on PHT_SYSTEM_STATISTICS references can then be used to obtain statistics data.
For the event handler to be called, it is necessary to register it with PrlSrv_RegEventHandler. When statistics data is no longer required, unsubscribe from statistics events using PrlSrv_UnsubscribeFromHostStatistics. When events are no longer required, unregister the event handler using PrlSrv_UnregEventHandler.
To get the return code from the PHT_JOB object, use the PrlJob_GetRetCode function. Possible values are:
PRL_ERR_INVALID_ARG - invalid handle was passed.
PRL_ERR_SUCCESS - function completed successfully.
The following is a complete example that demonstrates how to obtain statistics data asynchronously using PrlSrv_SubscribeToHostStatistics. Note that the same code could be used to receive statistics data for a virtual machine, instead of the host computer, by using PrlVm_SubscribeToGuestStatistics instead of PrlSrv_SubscribeToHostStatistics, and passing it a handle to a virtual machine that is running. This would also require using PrlVm_UnsubscribeFromGuestStatistics to stop receiving statistics data for the virtual machine.
#include "Parallels.h" #include "Wrappers/SdkWrap/SdkWrap.h" #include <stdio.h> #ifdef _WIN_ #include <windows.h> #else #include <unistd.h> #endif const char *szServer = "123.123.123.123"; const char *szUsername = "Your Username"; const char *szPassword = "Your Password"; // ------------------------------------------------------------------------- // Event handler. // ------------------------------------------------------------------------- // 1. Check for events of type PET_DSP_EVT_HOST_STATISTICS_UPDATES. // 2. Display a header if first call to this event handler. // 3. Get the event param (PHT_EVENT_PARAMETER) from the PHT_EVENT handle. // 4. Convert event param to a handle (will be type PHT_SYSTEM_STATISTICS). // 5. Use PHT_SYSTEM_STATISTICS handle to obtain CPU usage, memory usage, // and disk usage data. // ------------------------------------------------------------------------- static PRL_RESULT OurCallback(PRL_HANDLE handle, void *pData) { PRL_HANDLE_TYPE nHandleType; PRL_RESULT ret = PrlHandle_GetType(handle, &nHandleType); // Check for PrlHandle_GetType error here. if (nHandleType == PHT_EVENT) { PRL_EVENT_TYPE EventType; PrlEvent_GetType(handle, &EventType); // Check if the event type is a statistics update. if (EventType == PET_DSP_EVT_HOST_STATISTICS_UPDATED) { // Output a header if first call to this function. static PRL_BOOL bHeaderHasBeenPrinted = PRL_FALSE; if (!bHeaderHasBeenPrinted) { bHeaderHasBeenPrinted = PRL_TRUE; printf("CPU (%%) Used RAM (MB) Free RAM (MB) Used Disk Space (MB)" " Free Disk Space (MB)\n"); printf("---------------------------------------------------------" "--------------------\n"); } PRL_HANDLE hEventParameters; PRL_HANDLE hServerStatistics; // Get the event parameter (PHT_EVENT_PARAMETER) from the event handle. PrlEvent_GetParam(handle, 0, &hEventParameters); // Convert the event parameter to a handle (PHT_SYSTEM_STATISTICS). PrlEvtPrm_ToHandle(hEventParameters, &hServerStatistics); // Get CPU statistics (usage in %). PRL_HANDLE hCpuStatistics; ret = PrlStat_GetCpuStat(hServerStatistics, 0, &hCpuStatistics); PRL_UINT32 nCpuUsage = 0; ret = PrlStatCpu_GetCpuUsage(hCpuStatistics, &nCpuUsage); // Get RAM statistics. PRL_UINT64 nUsedRam, nFreeRam; PrlStat_GetFreeRamSize(hServerStatistics, &nFreeRam); PrlStat_GetUsageRamSize(hServerStatistics, &nUsedRam); nUsedRam /= (1024 * 1024); nFreeRam /= (1024 * 1024); // Get disk space statistics. PRL_UINT64 nFreeDiskSpace, nUsedDiskSpace; PRL_HANDLE hDiskStatistics; PrlStat_GetDiskStat(hServerStatistics, 0, &hDiskStatistics); PrlStatDisk_GetFreeDiskSpace(hDiskStatistics, &nFreeDiskSpace); PrlStatDisk_GetUsageDiskSpace(hDiskStatistics, &nUsedDiskSpace); nUsedDiskSpace /= (1024 * 1024); nFreeDiskSpace /= (1024 * 1024); printf("%7d %10lld %13lld %20lld %20lld\n", nCpuUsage, nUsedRam, nFreeRam, nUsedDiskSpace, nFreeDiskSpace); PrlHandle_Free(hDiskStatistics); PrlHandle_Free(hCpuStatistics); PrlHandle_Free(hServerStatistics); PrlHandle_Free(hEventParameters); } } PrlHandle_Free(handle); return PRL_ERR_SUCCESS; } // ------------------------------- // Program entry point. // ------------------------------- int main(int argc, char* argv[]) { PRL_HANDLE hServer; PRL_RESULT ret; // Use the correct dynamic library depending on the platform. #ifdef _WIN_ #define SDK_LIB_NAME "prl_sdk.dll" #elif defined(_LIN_) #define SDK_LIB_NAME "libprl_sdk.so" #elif defined(_MAC_) #define SDK_LIB_NAME "libprl_sdk.dylib" #endif if (PRL_FAILED(SdkWrap_Load(SDK_LIB_NAME)) && PRL_FAILED(SdkWrap_Load("./" SDK_LIB_NAME))) { fprintf(stderr, "Failed to load " SDK_LIB_NAME "\n"); return -1; } // Initialize the Parallels API. ret = PrlApi_Init(PARALLELS_API_VER); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlApi_Init returned with error: %s.\n", PRL_RESULT_TO_STRING(ret)); PrlApi_Deinit(); SdkWrap_Unload(); return ret; } // Create a server handle. ret = PrlSrv_Create(&hServer); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlSvr_Create failed, error: %s", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } // Log in (PrlSrv is asynchronous). PRL_HANDLE hJob = PrlSrv_Login( hServer, // PRL_HANDLE of type PHT_SERVER. szServer, // Server hostname or IP address. szUsername, // Username. szPassword, // Password. 0, // Deprecated - UUID of previous session. 0, // Optional - port number (0 for default). 0, // Optional - timeout value (0 for default). PSL_LOW_SECURITY); // Security level ret = PrlJob_Wait(hJob, 1000); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlJob_Wait for PrlSrv_Login returned with error: %s\n", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } // Analyze the result of PrlSrv_Login. PRL_RESULT nJobResult; ret = PrlJob_GetRetCode(hJob, &nJobResult); if (PRL_FAILED(nJobResult)) { printf("Login job returned with error: %s\n", PRL_RESULT_TO_STRING(nJobResult)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } else printf("Login was successful.\n"); // ---------------------------------------------------------------------------- // 1. Register our event handler (OurCallback function). // 2. Subscribe to host machine statistics events. // 3. Keep receiving events until user presses <enter> key. // 4. Unsubscribe from statistics events. // 5. Un-register out event handler. // ---------------------------------------------------------------------------- PrlSrv_RegEventHandler(hServer, OurCallback, NULL); PrlSrv_SubscribeToHostStatistics(hServer); char c; scanf(&c, 1); PrlSrv_UnsubscribeFromHostStatistics(hServer); PrlSrv_UnregEventHandler(hServer, OurCallback, NULL); // ---------------------------------------------------------------------------- // Log off. hJob = PrlSrv_Logoff(hServer); ret = PrlJob_Wait(hJob, 1000); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlJob_Wait for PrlSrv_Logoff returned error: %s\n", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } ret = PrlJob_GetRetCode(hJob, &nJobResult); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlJob_GetRetCode failed for PrlSrv_Logoff with error: %s\n", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } // Report success or failure of PrlSrv_Logoff. if (PRL_FAILED(nJobResult)) { fprintf(stderr, "PrlSrv_Logoff failed with error: %s\n", PRL_RESULT_TO_STRING(nJobResult)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } else printf("Logoff was successful.\n"); // Free handles that are no longer required. PrlHandle_Free(hJob); PrlHandle_Free(hServer); // De-initialize the Parallels API, and unload the SDK. PrlApi_Deinit(); SdkWrap_Unload(); return 0; }