Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/jcl/common/mgmthypervisor.c
6000 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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-exception
21
*******************************************************************************/
22
23
#include <assert.h>
24
25
#include "j9.h"
26
#include "j9jclnls.h"
27
#include "portnls.h"
28
#include "j9port.h"
29
#include "jclglob.h"
30
#include "jclprots.h"
31
#include "jni.h"
32
33
/* Macro for the error code for Hypervisor detection not supported
34
* NOTE: This error code should be in sync with the HypervisorMXBeanImpl.java
35
*/
36
#define HYPERVISOR_UNSUPPORTED -100001
37
38
#define MESSAGE_STRING_LENGTH 512
39
40
/**
41
* Checks if running on a Virtualized environment or not. i.e On a Hypervisor or not
42
*
43
* Class: com_ibm_virtualization_management_internal_HypervisorMXBeanImpl
44
* Method: isEnvironmentVirtual
45
*
46
* @param[in] env The JNI env.
47
* @param[in] obj The this pointer.
48
*
49
* @return - 0 - If not running on a Hypervisor, 1- If Running on a Hypervisor
50
* Negative value on Error.
51
*/
52
jint JNICALL
53
Java_com_ibm_virtualization_management_internal_HypervisorMXBeanImpl_isEnvironmentVirtualImpl(JNIEnv *env, jobject obj)
54
{
55
PORT_ACCESS_FROM_ENV(env);
56
IDATA rc = 0;
57
rc = j9hypervisor_hypervisor_present();
58
59
/* Return Hypervisor detection not supported */
60
if (rc == J9PORT_ERROR_HYPERVISOR_UNSUPPORTED) {
61
return (jint)(HYPERVISOR_UNSUPPORTED);
62
}
63
/* Return the value stored returned by j9hypervisor_hypervisor_present for all other cases */
64
return (jint)rc;
65
}
66
67
/**
68
* Retrieves the Hypervisor Vendor Name
69
*
70
* Class: com_ibm_virtualization_management_internal_HypervisorMXBeanImpl
71
* Method: getVendor
72
*
73
* @param[in] env The JNI env.
74
* @param[in] obj The this pointer.
75
*
76
* @return - String containing the Hypervisor Vendor Name, NULL in case of No Hypervisor
77
*/
78
jstring JNICALL
79
Java_com_ibm_virtualization_management_internal_HypervisorMXBeanImpl_getVendorImpl(JNIEnv *env, jobject obj)
80
{
81
PORT_ACCESS_FROM_ENV(env);
82
J9HypervisorVendorDetails vendor;
83
if(0 == j9hypervisor_get_hypervisor_info(&vendor)) {
84
return ((*env)->NewStringUTF(env, (char *)vendor.hypervisorName));
85
}
86
return NULL; /* Error returned by j9hypervisor_get_hypervisor_info, Hypervisor name is NULL */
87
}
88
89
static const struct { char *name; } objType[] = {
90
{ "GuestOS Processor Usage" },
91
{ "GuestOS Memory Usage" },
92
};
93
94
typedef enum {
95
GUEST_PROCESSOR = 0,
96
GUEST_MEMORY
97
} objTypes;
98
99
/**
100
* @internal Throw appropriate exception based on the error code passed
101
*
102
* @param error Error code from port library
103
* @param type Error when retrieving either GUEST_PROCESSOR or GUEST_MEMORY statistics
104
*
105
* @return Always returns 0
106
*/
107
static jint
108
handle_error(JNIEnv *env, IDATA error, jint type)
109
{
110
PORT_ACCESS_FROM_ENV(env);
111
jclass exceptionClass = NULL;
112
const char *formatString = NULL;
113
char exceptionMessage[MESSAGE_STRING_LENGTH] = {0};
114
115
assert((type == GUEST_PROCESSOR || type == GUEST_MEMORY));
116
117
/* If out of memory setup a pending OutOfMemoryError */
118
if (J9PORT_ERROR_HYPERVISOR_MEMORY_ALLOC_FAILED == error) {
119
((J9VMThread *)env)->javaVM->internalVMFunctions->throwNativeOOMError(env, J9NLS_PORT_HYPERVISOR_OUT_OF_MEMORY_ERROR_MSG);
120
return 0;
121
}
122
123
/* For all other errors setup a GuestOSInfoRetrievalException exception */
124
/* Read in the generic usage retrieval error string */
125
formatString = j9nls_lookup_message(J9NLS_DO_NOT_PRINT_MESSAGE_TAG | J9NLS_DO_NOT_APPEND_NEWLINE,
126
J9NLS_JCL_HYPERVISOR_USAGE_RETRIEVAL_ERROR_MSG,
127
NULL);
128
/* Add in the specific error and the type. Append the port library specific error. */
129
j9str_printf(PORTLIB,
130
exceptionMessage,
131
sizeof(exceptionMessage),
132
(char *)formatString,
133
error,
134
objType[type].name,
135
j9error_last_error_message());
136
137
exceptionClass = (*env)->FindClass(env, "com/ibm/virtualization/management/GuestOSInfoRetrievalException");
138
if (NULL != exceptionClass) {
139
(*env)->ThrowNew(env, exceptionClass, exceptionMessage);
140
}
141
142
return 0;
143
}
144
145
/**
146
* Returns guest processor usage statistics as reported by the hypervisor host
147
*
148
* @param[in] env The JNI env.
149
* @param[in] beanInstance The this pointer.
150
* @param[in/out] procUsageObject User supplied J9GuestProcessorUsage object
151
*
152
* @return J9GuestProcessorUsage object on success or NULL on error
153
*/
154
jobject JNICALL
155
Java_com_ibm_virtualization_management_internal_GuestOS_retrieveProcessorUsageImpl(JNIEnv *env, jobject beanInstance, jobject procUsageObject)
156
{
157
PORT_ACCESS_FROM_ENV(env);
158
IDATA rc = 0;
159
jmethodID MID_updateValues = NULL;
160
jclass CLS_GuestOSProcessorUsage = NULL;
161
J9GuestProcessorUsage procUsage;
162
163
/* Check if the GuestOSProcessorUsage class has been cached */
164
CLS_GuestOSProcessorUsage = JCL_CACHE_GET(env, CLS_java_com_ibm_virtualization_management_GuestOSProcessorUsage);
165
if (NULL == CLS_GuestOSProcessorUsage) {
166
jclass GuestOSProcessorUsageID = NULL;
167
168
/* Get the class ID */
169
GuestOSProcessorUsageID = (*env)->GetObjectClass(env, procUsageObject);
170
if (NULL == GuestOSProcessorUsageID) {
171
return NULL;
172
}
173
174
/* Convert to a global reference and delete the local one */
175
CLS_GuestOSProcessorUsage = (*env)->NewGlobalRef(env, GuestOSProcessorUsageID);
176
(*env)->DeleteLocalRef(env, GuestOSProcessorUsageID);
177
if (NULL == CLS_GuestOSProcessorUsage) {
178
return NULL;
179
}
180
181
JCL_CACHE_SET(env, CLS_java_com_ibm_virtualization_management_GuestOSProcessorUsage, CLS_GuestOSProcessorUsage);
182
183
/* Get the method ID for updateValues() method */
184
MID_updateValues = (*env)->GetMethodID(env, CLS_GuestOSProcessorUsage, "updateValues", "(JJFJ)V");
185
if (NULL == MID_updateValues) {
186
return NULL;
187
}
188
JCL_CACHE_SET(env, MID_java_com_ibm_virtualization_management_GuestOSProcessorUsage_updateValues, MID_updateValues);
189
} else {
190
MID_updateValues = JCL_CACHE_GET(env, MID_java_com_ibm_virtualization_management_GuestOSProcessorUsage_updateValues);
191
}
192
193
/* Call port library routine to get guest processor usage statistics */
194
rc = j9hypervisor_get_guest_processor_usage(&procUsage);
195
if (0 != rc) {
196
handle_error(env, rc, GUEST_PROCESSOR);
197
return NULL;
198
}
199
200
/* Call the update values method to update the object with the values obtained */
201
(*env)->CallVoidMethod(env,
202
procUsageObject,
203
MID_updateValues,
204
(jlong)procUsage.cpuTime,
205
(jlong)procUsage.timestamp,
206
(jfloat)procUsage.cpuEntitlement,
207
(jlong)procUsage.hostCpuClockSpeed);
208
209
return procUsageObject;
210
}
211
212
/**
213
* Returns guest memory usage statistics as reported by the hypervisor host
214
*
215
* @param[in] env The JNI env.
216
* @param[in] beanInstance The this pointer.
217
* @param[in/out] memUsageObject User supplied J9GuestMemoryUsage object
218
*
219
* @return J9GuestMemoryUsage object on success or NULL on error
220
*/
221
jobject JNICALL
222
Java_com_ibm_virtualization_management_internal_GuestOS_retrieveMemoryUsageImpl(JNIEnv *env, jobject beanInstance, jobject memUsageObject)
223
{
224
PORT_ACCESS_FROM_ENV(env);
225
IDATA rc = 0;
226
jmethodID MID_updateValues = NULL;
227
J9GuestMemoryUsage memUsage;
228
jclass CLS_GuestOSMemoryUsage = NULL;
229
230
/* Check if the GuestOSMemoryUsage class has been cached */
231
CLS_GuestOSMemoryUsage = JCL_CACHE_GET(env, CLS_java_com_ibm_virtualization_management_GuestOSMemoryUsage);
232
if (NULL == CLS_GuestOSMemoryUsage)
233
{
234
jclass GuestOSMemoryUsageID = NULL;
235
236
/* Get the class ID */
237
GuestOSMemoryUsageID = (*env)->GetObjectClass(env, memUsageObject);
238
if (NULL == GuestOSMemoryUsageID) {
239
return NULL;
240
}
241
242
/* Convert to a global reference and delete the local one */
243
CLS_GuestOSMemoryUsage = (*env)->NewGlobalRef(env, GuestOSMemoryUsageID);
244
(*env)->DeleteLocalRef(env, GuestOSMemoryUsageID);
245
if (NULL == CLS_GuestOSMemoryUsage) {
246
return NULL;
247
}
248
249
JCL_CACHE_SET(env, CLS_java_com_ibm_virtualization_management_GuestOSMemoryUsage, CLS_GuestOSMemoryUsage);
250
251
/* Get the method ID for updateValues() method */
252
MID_updateValues = (*env)->GetMethodID(env, CLS_GuestOSMemoryUsage, "updateValues", "(JJJ)V");
253
if (NULL == MID_updateValues) {
254
return NULL;
255
}
256
JCL_CACHE_SET(env, MID_java_com_ibm_virtualization_management_GuestOSMemoryUsage_updateValues, MID_updateValues);
257
} else {
258
MID_updateValues = JCL_CACHE_GET(env, MID_java_com_ibm_virtualization_management_GuestOSMemoryUsage_updateValues);
259
}
260
261
/* Call port library routine to get guest memory usage statistics */
262
rc = j9hypervisor_get_guest_memory_usage(&memUsage);
263
if (0 != rc) {
264
handle_error(env, rc, GUEST_MEMORY);
265
return NULL;
266
}
267
268
/* Call the update values method to update the object with the values obtained */
269
(*env)->CallVoidMethod(env,
270
memUsageObject,
271
MID_updateValues,
272
(jlong)memUsage.memUsed,
273
(jlong)memUsage.timestamp,
274
(jlong)memUsage.maxMemLimit);
275
276
return memUsageObject;
277
}
278
279