Path: blob/master/runtime/jcl/common/mgmthypervisor.c
6000 views
/*******************************************************************************1* Copyright (c) 1991, 2019 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include <assert.h>2324#include "j9.h"25#include "j9jclnls.h"26#include "portnls.h"27#include "j9port.h"28#include "jclglob.h"29#include "jclprots.h"30#include "jni.h"3132/* Macro for the error code for Hypervisor detection not supported33* NOTE: This error code should be in sync with the HypervisorMXBeanImpl.java34*/35#define HYPERVISOR_UNSUPPORTED -1000013637#define MESSAGE_STRING_LENGTH 5123839/**40* Checks if running on a Virtualized environment or not. i.e On a Hypervisor or not41*42* Class: com_ibm_virtualization_management_internal_HypervisorMXBeanImpl43* Method: isEnvironmentVirtual44*45* @param[in] env The JNI env.46* @param[in] obj The this pointer.47*48* @return - 0 - If not running on a Hypervisor, 1- If Running on a Hypervisor49* Negative value on Error.50*/51jint JNICALL52Java_com_ibm_virtualization_management_internal_HypervisorMXBeanImpl_isEnvironmentVirtualImpl(JNIEnv *env, jobject obj)53{54PORT_ACCESS_FROM_ENV(env);55IDATA rc = 0;56rc = j9hypervisor_hypervisor_present();5758/* Return Hypervisor detection not supported */59if (rc == J9PORT_ERROR_HYPERVISOR_UNSUPPORTED) {60return (jint)(HYPERVISOR_UNSUPPORTED);61}62/* Return the value stored returned by j9hypervisor_hypervisor_present for all other cases */63return (jint)rc;64}6566/**67* Retrieves the Hypervisor Vendor Name68*69* Class: com_ibm_virtualization_management_internal_HypervisorMXBeanImpl70* Method: getVendor71*72* @param[in] env The JNI env.73* @param[in] obj The this pointer.74*75* @return - String containing the Hypervisor Vendor Name, NULL in case of No Hypervisor76*/77jstring JNICALL78Java_com_ibm_virtualization_management_internal_HypervisorMXBeanImpl_getVendorImpl(JNIEnv *env, jobject obj)79{80PORT_ACCESS_FROM_ENV(env);81J9HypervisorVendorDetails vendor;82if(0 == j9hypervisor_get_hypervisor_info(&vendor)) {83return ((*env)->NewStringUTF(env, (char *)vendor.hypervisorName));84}85return NULL; /* Error returned by j9hypervisor_get_hypervisor_info, Hypervisor name is NULL */86}8788static const struct { char *name; } objType[] = {89{ "GuestOS Processor Usage" },90{ "GuestOS Memory Usage" },91};9293typedef enum {94GUEST_PROCESSOR = 0,95GUEST_MEMORY96} objTypes;9798/**99* @internal Throw appropriate exception based on the error code passed100*101* @param error Error code from port library102* @param type Error when retrieving either GUEST_PROCESSOR or GUEST_MEMORY statistics103*104* @return Always returns 0105*/106static jint107handle_error(JNIEnv *env, IDATA error, jint type)108{109PORT_ACCESS_FROM_ENV(env);110jclass exceptionClass = NULL;111const char *formatString = NULL;112char exceptionMessage[MESSAGE_STRING_LENGTH] = {0};113114assert((type == GUEST_PROCESSOR || type == GUEST_MEMORY));115116/* If out of memory setup a pending OutOfMemoryError */117if (J9PORT_ERROR_HYPERVISOR_MEMORY_ALLOC_FAILED == error) {118((J9VMThread *)env)->javaVM->internalVMFunctions->throwNativeOOMError(env, J9NLS_PORT_HYPERVISOR_OUT_OF_MEMORY_ERROR_MSG);119return 0;120}121122/* For all other errors setup a GuestOSInfoRetrievalException exception */123/* Read in the generic usage retrieval error string */124formatString = j9nls_lookup_message(J9NLS_DO_NOT_PRINT_MESSAGE_TAG | J9NLS_DO_NOT_APPEND_NEWLINE,125J9NLS_JCL_HYPERVISOR_USAGE_RETRIEVAL_ERROR_MSG,126NULL);127/* Add in the specific error and the type. Append the port library specific error. */128j9str_printf(PORTLIB,129exceptionMessage,130sizeof(exceptionMessage),131(char *)formatString,132error,133objType[type].name,134j9error_last_error_message());135136exceptionClass = (*env)->FindClass(env, "com/ibm/virtualization/management/GuestOSInfoRetrievalException");137if (NULL != exceptionClass) {138(*env)->ThrowNew(env, exceptionClass, exceptionMessage);139}140141return 0;142}143144/**145* Returns guest processor usage statistics as reported by the hypervisor host146*147* @param[in] env The JNI env.148* @param[in] beanInstance The this pointer.149* @param[in/out] procUsageObject User supplied J9GuestProcessorUsage object150*151* @return J9GuestProcessorUsage object on success or NULL on error152*/153jobject JNICALL154Java_com_ibm_virtualization_management_internal_GuestOS_retrieveProcessorUsageImpl(JNIEnv *env, jobject beanInstance, jobject procUsageObject)155{156PORT_ACCESS_FROM_ENV(env);157IDATA rc = 0;158jmethodID MID_updateValues = NULL;159jclass CLS_GuestOSProcessorUsage = NULL;160J9GuestProcessorUsage procUsage;161162/* Check if the GuestOSProcessorUsage class has been cached */163CLS_GuestOSProcessorUsage = JCL_CACHE_GET(env, CLS_java_com_ibm_virtualization_management_GuestOSProcessorUsage);164if (NULL == CLS_GuestOSProcessorUsage) {165jclass GuestOSProcessorUsageID = NULL;166167/* Get the class ID */168GuestOSProcessorUsageID = (*env)->GetObjectClass(env, procUsageObject);169if (NULL == GuestOSProcessorUsageID) {170return NULL;171}172173/* Convert to a global reference and delete the local one */174CLS_GuestOSProcessorUsage = (*env)->NewGlobalRef(env, GuestOSProcessorUsageID);175(*env)->DeleteLocalRef(env, GuestOSProcessorUsageID);176if (NULL == CLS_GuestOSProcessorUsage) {177return NULL;178}179180JCL_CACHE_SET(env, CLS_java_com_ibm_virtualization_management_GuestOSProcessorUsage, CLS_GuestOSProcessorUsage);181182/* Get the method ID for updateValues() method */183MID_updateValues = (*env)->GetMethodID(env, CLS_GuestOSProcessorUsage, "updateValues", "(JJFJ)V");184if (NULL == MID_updateValues) {185return NULL;186}187JCL_CACHE_SET(env, MID_java_com_ibm_virtualization_management_GuestOSProcessorUsage_updateValues, MID_updateValues);188} else {189MID_updateValues = JCL_CACHE_GET(env, MID_java_com_ibm_virtualization_management_GuestOSProcessorUsage_updateValues);190}191192/* Call port library routine to get guest processor usage statistics */193rc = j9hypervisor_get_guest_processor_usage(&procUsage);194if (0 != rc) {195handle_error(env, rc, GUEST_PROCESSOR);196return NULL;197}198199/* Call the update values method to update the object with the values obtained */200(*env)->CallVoidMethod(env,201procUsageObject,202MID_updateValues,203(jlong)procUsage.cpuTime,204(jlong)procUsage.timestamp,205(jfloat)procUsage.cpuEntitlement,206(jlong)procUsage.hostCpuClockSpeed);207208return procUsageObject;209}210211/**212* Returns guest memory usage statistics as reported by the hypervisor host213*214* @param[in] env The JNI env.215* @param[in] beanInstance The this pointer.216* @param[in/out] memUsageObject User supplied J9GuestMemoryUsage object217*218* @return J9GuestMemoryUsage object on success or NULL on error219*/220jobject JNICALL221Java_com_ibm_virtualization_management_internal_GuestOS_retrieveMemoryUsageImpl(JNIEnv *env, jobject beanInstance, jobject memUsageObject)222{223PORT_ACCESS_FROM_ENV(env);224IDATA rc = 0;225jmethodID MID_updateValues = NULL;226J9GuestMemoryUsage memUsage;227jclass CLS_GuestOSMemoryUsage = NULL;228229/* Check if the GuestOSMemoryUsage class has been cached */230CLS_GuestOSMemoryUsage = JCL_CACHE_GET(env, CLS_java_com_ibm_virtualization_management_GuestOSMemoryUsage);231if (NULL == CLS_GuestOSMemoryUsage)232{233jclass GuestOSMemoryUsageID = NULL;234235/* Get the class ID */236GuestOSMemoryUsageID = (*env)->GetObjectClass(env, memUsageObject);237if (NULL == GuestOSMemoryUsageID) {238return NULL;239}240241/* Convert to a global reference and delete the local one */242CLS_GuestOSMemoryUsage = (*env)->NewGlobalRef(env, GuestOSMemoryUsageID);243(*env)->DeleteLocalRef(env, GuestOSMemoryUsageID);244if (NULL == CLS_GuestOSMemoryUsage) {245return NULL;246}247248JCL_CACHE_SET(env, CLS_java_com_ibm_virtualization_management_GuestOSMemoryUsage, CLS_GuestOSMemoryUsage);249250/* Get the method ID for updateValues() method */251MID_updateValues = (*env)->GetMethodID(env, CLS_GuestOSMemoryUsage, "updateValues", "(JJJ)V");252if (NULL == MID_updateValues) {253return NULL;254}255JCL_CACHE_SET(env, MID_java_com_ibm_virtualization_management_GuestOSMemoryUsage_updateValues, MID_updateValues);256} else {257MID_updateValues = JCL_CACHE_GET(env, MID_java_com_ibm_virtualization_management_GuestOSMemoryUsage_updateValues);258}259260/* Call port library routine to get guest memory usage statistics */261rc = j9hypervisor_get_guest_memory_usage(&memUsage);262if (0 != rc) {263handle_error(env, rc, GUEST_MEMORY);264return NULL;265}266267/* Call the update values method to update the object with the values obtained */268(*env)->CallVoidMethod(env,269memUsageObject,270MID_updateValues,271(jlong)memUsage.memUsed,272(jlong)memUsage.timestamp,273(jlong)memUsage.maxMemLimit);274275return memUsageObject;276}277278279