1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2003 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
41
#include "basis_types.h"
42
#include "sge_qmaster_threads.h"
44
#include "sge_mt_init.h"
47
#include "sge_unistd.h"
48
#include "sge_answer.h"
49
#include "setup_qmaster.h"
50
#include "sge_security.h"
51
#include "sge_manop.h"
52
#include "sge_mtutil.h"
54
#include "sge_qmaster_process_message.h"
55
#include "sge_event_master.h"
56
#include "sge_persistence_qmaster.h"
57
#include "sge_reporting_qmaster.h"
58
#include "sge_qmaster_timed_event.h"
59
#include "sge_host_qmaster.h"
60
#include "sge_userprj_qmaster.h"
61
#include "sge_give_jobs.h"
62
#include "sge_all_listsL.h"
63
#include "sge_calendar_qmaster.h"
66
#include "qmaster_heartbeat.h"
68
#include "sge_spool.h"
69
#include "cl_commlib.h"
70
#include "sge_uidgid.h"
71
#include "sge_bootstrap.h"
72
#include "msg_common.h"
73
#include "msg_qmaster.h"
74
#include "msg_daemons_common.h"
75
#include "msg_utilib.h" /* remove once 'sge_daemonize_qmaster' did become 'sge_daemonize' */
77
#include "sge_qmod_qmaster.h"
78
#include "reschedule.h"
79
#include "sge_job_qmaster.h"
80
#include "sge_profiling.h"
81
#include "sgeobj/sge_conf.h"
83
#include "setup_path.h"
84
#include "sge_advance_reservation_qmaster.h"
85
#include "sge_sched_process_events.h"
86
#include "sge_follow.h"
87
#include "configuration_qmaster.h"
88
#include "sge_thread_main.h"
89
#include "sge_thread_jvm.h"
91
#include "uti/sge_os.h"
92
#include "uti/sge_string.h"
93
#include "uti/sge_thread_ctrl.h"
94
#include "uti/sge_dstring.h"
96
#include "sgeobj/config.h"
99
master_jvm_class_t Master_Jvm = {
100
PTHREAD_MUTEX_INITIALIZER,
101
PTHREAD_COND_INITIALIZER,
108
static bool shutdown_main(void);
109
static void *sge_jvm_main(void *arg);
111
/****** qmaster/threads/sge_jvm_terminate() ***********************************
113
* sge_jvm_terminate() -- trigger termination of JVM
116
* void sge_jvm_terminate(sge_gdi_ctx_class_t *ctx)
119
* A call of this function triggers the termination of the JVM thread .
121
* If ther JVM is running then JVM will be notified to terminate.
122
* The thread running the JVM will get a cancel signal.
124
* If the JVM should be running but if it was not able to start due
125
* to some reason (missing library; wrong jvm parameters; ...) then
126
* the JVM thread is waiting only for a termination call which will be
127
* send by this function.
129
* 'Master_Scheduler' is accessed by this function.
132
* sge_gdi_ctx_class_t *ctx - context object
133
* lList **answer_list - answer list
139
* MT-NOTE: sge_jvm_terminate() is MT safe
142
* qmaster/threads/sge_jvm_initialize()
143
* qmaster/threads/sge_jvm_cleanup_thread()
144
* qmaster/threads/sge_jvm_terminate()
145
* qmaster/threads/sge_jvm_wait_for_terminate()
146
* qmaster/threads/sge_jvm_main()
147
*******************************************************************************/
149
sge_jvm_terminate(sge_gdi_ctx_class_t *ctx, lList **answer_list)
152
DENTER(TOP_LAYER, "sge_jvm_terminate");
154
sge_mutex_lock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
156
if (Master_Jvm.is_running) {
158
cl_thread_settings_t* thread = NULL;
161
* store thread id to use it later on
163
thread = cl_thread_list_get_first_thread(Main_Control.jvm_thread_pool);
164
thread_id = *(thread->thread_pointer);
168
* trigger shutdown in the JVM
169
* and signal the continuation to realease the JVM thread if it was unable to setup the JVM
171
pthread_cancel(thread_id);
173
Master_Jvm.shutdown_started = true;
174
pthread_cond_broadcast(&Master_Jvm.cond_var);
177
* cl_thread deletion and cl_thread_pool deletion will be done at
178
* JVM threads cancelation point in sge_jvm_cleanup_thread() ...
179
* ... therefore we have nothing more to do.
181
sge_mutex_unlock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
184
* after releasing the lock it is safe to wait for the termination.
185
* doing this inside the critical section (before the lock) could
186
* rise a deadlock situtaion this function would be called within a GDI request!
188
pthread_join(thread_id, NULL);
190
INFO((SGE_EVENT, MSG_THREAD_XTERMINATED_S, threadnames[JVM_THREAD]));
191
answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_INFO);
193
sge_mutex_unlock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
195
ERROR((SGE_EVENT, MSG_THREAD_XNOTRUNNING_S, threadnames[JVM_THREAD]));
196
answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
202
/****** qmaster/threads/sge_jvm_initialize() ************************************
204
* sge_jvm_initialize() -- setup and start the JVM thread
207
* void sge_jvm_initialize(sge_gdi_ctx_class_t *ctx)
210
* A call to this function initializes the JVM thread if it is not
213
* The first call to this function (during qmaster start) starts
214
* the JVM thread only if it is enabled in bootstrap configuration
215
* file. Otherwise the JVM will not be started.
217
* Each subsequent call (triggered via GDI) will definitely try to
218
* start the JVM tread if it is not running.
220
* Main routine for the created thread is sge_jvm_main().
222
* 'Master_Jvm' is accessed by this function.
225
* sge_gdi_ctx_class_t *ctx - context object
226
* lList **answer_list - answer list
232
* MT-NOTE: sge_jvm_initialize() is MT safe
235
* qmaster/threads/sge_jvm_initialize()
236
* qmaster/threads/sge_jvm_cleanup_thread()
237
* qmaster/threads/sge_jvm_terminate()
238
* qmaster/threads/sge_jvm_wait_for_terminate()
239
* qmaster/threads/sge_jvm_main()
240
*******************************************************************************/
242
sge_jvm_initialize(sge_gdi_ctx_class_t *ctx, lList **answer_list)
244
DENTER(TOP_LAYER, "sge_jvm_initialize");
246
sge_mutex_lock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
248
if (Master_Jvm.is_running == false) {
249
bool start_thread = true;
252
* when this function is called the first time we will use the setting from
253
* the bootstrap file to identify if the Jvm should be started or not
254
* otherwise we have to start the thread due to a manual request through GDI.
255
* There is no option. We have to start it.
257
if (Master_Jvm.use_bootstrap == true) {
258
start_thread = ((ctx->get_jvm_thread_count(ctx) > 0) ? true : false);
259
Master_Jvm.use_bootstrap = false;
262
if (start_thread == true) {
263
cl_thread_settings_t* dummy_thread_p = NULL;
264
dstring thread_name = DSTRING_INIT;
267
* initialize the thread pool
269
cl_thread_list_setup(&(Main_Control.jvm_thread_pool), "thread pool");
272
* prepare a unique jvm thread name for each instance
274
sge_dstring_sprintf(&thread_name, "%s%03d", threadnames[JVM_THREAD],
275
Master_Jvm.thread_id);
278
* start the JVM thread
280
cl_thread_list_create_thread(Main_Control.jvm_thread_pool, &dummy_thread_p,
281
NULL, sge_dstring_get_string(&thread_name),
282
Master_Jvm.thread_id, sge_jvm_main, NULL, NULL);
283
sge_dstring_free(&thread_name);
286
* Increase the thread id so that the next instance of a jvm will have a
287
* different name and flag that jvm is running and that shutdown has not been
290
Master_Jvm.shutdown_started = false;
291
Master_Jvm.thread_id++;
292
Master_Jvm.is_running = true;
294
INFO((SGE_EVENT, MSG_THREAD_XHASSTARTED_S, threadnames[JVM_THREAD]));
295
answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_INFO);
297
INFO((SGE_EVENT, MSG_THREAD_XSTARTDISABLED_S, threadnames[JVM_THREAD]));
298
answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_INFO);
301
ERROR((SGE_EVENT, MSG_THREAD_XISRUNNING_S, threadnames[JVM_THREAD]));
302
answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
304
sge_mutex_unlock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
331
typedef int (*JNI_CreateJavaVM_Func)(JavaVM **pvm, void **penv, void *args);
332
typedef int (*JNI_GetCreatedJavaVMs_Func)(JavaVM **pvm, jsize size, jsize *real_size);
334
static void *libjvm_handle = NULL;
335
static JNI_CreateJavaVM_Func sge_JNI_CreateJavaVM = NULL;
336
static JNI_GetCreatedJavaVMs_Func sge_JNI_GetCreatedJavaVMs = NULL;
337
static pthread_mutex_t libjvm_mutex = PTHREAD_MUTEX_INITIALIZER;
339
static JavaVM* myjvm = NULL;
340
static pthread_mutex_t myjvm_mutex = PTHREAD_MUTEX_INITIALIZER;
342
static JNIEnv* create_vm(const char *libjvm_path, int argc, char** argv);
343
static int invoke_main(JNIEnv* env, jclass main_class, int argc, char** argv);
347
int JNI_CreateJavaVM_Impl(JavaVM **pvm, void **penv, void *args);
351
sge_run_jvm(sge_gdi_ctx_class_t *ctx, void *anArg, monitoring_t *monitor);
354
sge_jvm_cleanup_monitor(monitoring_t *monitor)
356
DENTER(TOP_LAYER, "cleanup_monitor");
357
sge_monitor_free(monitor);
361
/*-------------------------------------------------------------------------*
363
* shutdown_main - invoke the shutdown method of com.sun.grid.jgdi.management.JGDIAgent
365
* env - the JNI environment
366
* argc - number of arguments for the main method
367
* argv - the arguments for the main method
371
* exit code of the JVM
376
*-------------------------------------------------------------------------*/
377
static bool shutdown_main(void)
379
char main_class_name[] = "com/sun/grid/jgdi/management/JGDIAgent";
380
jmethodID shutdown_mid = NULL;
384
bool error_occured = false;
385
JavaVMAttachArgs attach_args = { JNI_VERSION_1_2, NULL, NULL };
387
DENTER(TOP_LAYER, "shutdown_main");
389
pthread_mutex_lock(&myjvm_mutex);
392
pthread_mutex_unlock(&myjvm_mutex);
396
ret = (*myjvm)->AttachCurrentThread(myjvm, (void**) &env, &attach_args);
399
CRITICAL((SGE_EVENT, "could not attach thread to vm\n"));
400
pthread_mutex_unlock(&myjvm_mutex);
405
main_class = (*env)->FindClass(env, main_class_name);
406
if (main_class != NULL) {
407
shutdown_mid = (*env)->GetStaticMethodID(env, main_class, "shutdown", "()V");
408
if (shutdown_mid == NULL) {
409
CRITICAL((SGE_EVENT, "class has no shutdown method\n"));
410
error_occured = true;
413
CRITICAL((SGE_EVENT, "main_class is NULL\n"));
414
error_occured = true;
417
if (!error_occured) {
418
(*env)->CallStaticVoidMethod(env, main_class, shutdown_mid);
420
if ((*env)->ExceptionOccurred(env)) {
421
(*env)->ExceptionClear(env);
422
CRITICAL((SGE_EVENT, "unexpected jvm exception\n"));
423
error_occured = true;
428
ret = (*myjvm)->DetachCurrentThread(myjvm);
430
CRITICAL((SGE_EVENT, "could not detach thread from vm\n"));
431
error_occured = true;
434
pthread_mutex_unlock(&myjvm_mutex);
443
static jint (JNICALL printVMErrors)(FILE *fp, const char *format, va_list args) {
445
const char* str = NULL;
446
dstring ds = DSTRING_INIT;
448
DENTER(TOP_LAYER, "printVMErrors");
449
str = sge_dstring_vsprintf(&ds, format, args);
452
DPRINTF(("%s\n", str));
453
CRITICAL((SGE_EVENT, "JVM message: %s", str));
455
sge_dstring_free(&ds);
460
static void (JNICALL exitVM)(jint code) {
461
DENTER(TOP_LAYER, "exitVM");
462
DPRINTF(("CALLED exitVM %d\n", (int)code));
469
/*-------------------------------------------------------------------------*
471
* create_vm - create a jvm
473
* argc - number of arguments for the jvm
474
* argv - arguments for the jvm
478
* NULL - jvm could not be created
479
* else - jvm has been created
485
* options[1].optionString = "exit";
486
* options[1].extraInfo = exitVM;
488
*-------------------------------------------------------------------------*/
489
static JNIEnv* create_vm(const char *libjvm_path, int argc, char** argv)
495
JavaVMOption* options = NULL;
496
const int extraOptionCount = 1;
498
DENTER(GDI_LAYER, "create_vm");
500
options = (JavaVMOption*)malloc((argc+extraOptionCount)*sizeof(JavaVMOption));
502
/* There is a new JNI_VERSION_1_4, but it doesn't add anything for the purposes of our example. */
503
args.version = JNI_VERSION_1_2;
504
args.nOptions = argc+extraOptionCount;
505
options[0].optionString = "vfprintf";
506
options[0].extraInfo = (void*)printVMErrors;
507
for(i=0; i < argc; i++) {
508
/*printf("argv[%d] = %s\n", i, argv[i]);*/
509
options[i+extraOptionCount].optionString = argv[i];
512
args.options = options;
513
args.ignoreUnrecognized = JNI_FALSE;
515
pthread_mutex_lock(&libjvm_mutex);
516
if (libjvm_handle == NULL) {
517
/* build the full name of the shared lib - append architecture dependent
522
** need to switch to start user for HP
524
sge_switch2start_user();
527
/* open the shared lib */
529
# ifdef RTLD_NODELETE
530
libjvm_handle = dlopen(libjvm_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
532
libjvm_handle = dlopen(libjvm_path, RTLD_NOW | RTLD_GLOBAL );
533
# endif /* RTLD_NODELETE */
534
# elif defined(HP11) || defined(HP1164)
535
# ifdef RTLD_NODELETE
536
libjvm_handle = dlopen(libjvm_path, RTLD_LAZY | RTLD_NODELETE);
538
libjvm_handle = dlopen(libjvm_path, RTLD_LAZY );
539
# endif /* RTLD_NODELETE */
541
# ifdef RTLD_NODELETE
542
libjvm_handle = dlopen(libjvm_path, RTLD_LAZY | RTLD_NODELETE);
544
libjvm_handle = dlopen(libjvm_path, RTLD_LAZY);
545
# endif /* RTLD_NODELETE */
550
** switch back to admin user for HP
552
sge_switch2admin_user();
554
if (libjvm_handle == NULL) {
555
CRITICAL((SGE_EVENT, "could not load libjvm %s", dlerror()));
559
/* retrieve function pointer of get_method function in shared lib */
563
** for darwin there exists no JNI_CreateJavaVM, Why not maybe a fix in the future ???
565
const char* JNI_CreateJavaVM_FuncName = "JNI_CreateJavaVM_Impl";
566
const char* JNI_GetCreatedJavaVMs_FuncName = "JNI_GetCreatedJavaVMs_Impl";
568
const char* JNI_CreateJavaVM_FuncName = "JNI_CreateJavaVM";
569
const char* JNI_GetCreatedJavaVMs_FuncName = "JNI_GetCreatedJavaVMs";
571
sge_JNI_CreateJavaVM = (JNI_CreateJavaVM_Func)dlsym(libjvm_handle, JNI_CreateJavaVM_FuncName);
572
if (sge_JNI_CreateJavaVM == NULL) {
573
CRITICAL((SGE_EVENT, "could not load sge_JNI_CreateJavaVM %s", dlerror()));
577
sge_JNI_GetCreatedJavaVMs = (JNI_GetCreatedJavaVMs_Func)dlsym(libjvm_handle, JNI_GetCreatedJavaVMs_FuncName);
578
if (sge_JNI_GetCreatedJavaVMs == NULL) {
579
CRITICAL((SGE_EVENT, "could not load sge_JNI_GetCreatedJavaVMs %s", dlerror()));
584
pthread_mutex_unlock(&libjvm_mutex);
588
JavaVMAttachArgs attach_args = { JNI_VERSION_1_2, NULL, NULL };
591
pthread_mutex_lock(&myjvm_mutex);
592
i = sge_JNI_GetCreatedJavaVMs(&jvm, 1, &have_jvm);
594
if (have_jvm && jvm != NULL) {
595
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2) == JNI_EDETACHED) {
596
if ((i = (*jvm)->AttachCurrentThread(jvm, (void**) &env, &attach_args)) < 0) {
597
CRITICAL((SGE_EVENT, "can not get JNIEnv (error code %d)\n", i));
607
if ((i = sge_JNI_CreateJavaVM(&jvm, (void **)&env, &args)) < 0) {
608
CRITICAL((SGE_EVENT, "can not create JVM (error code %d)\n", i));
615
pthread_mutex_unlock(&myjvm_mutex);
622
/*-------------------------------------------------------------------------*
624
* invoke_main - invoke the main method of com.sun.grid.jgdi.management.JGDIAgent
626
* env - the JNI environment
627
* argc - number of arguments for the main method
628
* argv - the arguments for the main method
632
* exit code of the JVM
637
*-------------------------------------------------------------------------*/
638
static int invoke_main(JNIEnv* env, jclass main_class, int argc, char** argv)
641
jobjectArray main_args;
644
DENTER(TOP_LAYER, "invoke_main");
646
main_mid = (*env)->GetStaticMethodID(env, main_class, "main", "([Ljava/lang/String;)V");
647
if (main_mid == NULL) {
648
CRITICAL((SGE_EVENT, "class has no main method\n"));
652
main_args = (*env)->NewObjectArray(env, argc, (*env)->FindClass(env, "java/lang/String"), NULL);
654
for(i=0; i < argc; i++) {
655
jstring str = (*env)->NewStringUTF(env, argv[i]);
656
DPRINTF(("argv[%d] = %s\n", i, argv[i]));
657
(*env)->SetObjectArrayElement(env, main_args, i, str);
660
INFO((SGE_EVENT, "Starting up jvm thread\n"));
661
(*env)->CallStaticVoidMethod(env, main_class, main_mid, main_args);
663
if ((*env)->ExceptionOccurred(env)) {
664
(*env)->ExceptionClear(env);
665
CRITICAL((SGE_EVENT, "unexpected exception in invoke_main\n"));
674
sge_run_jvm(sge_gdi_ctx_class_t *ctx, void *anArg, monitoring_t *monitor)
677
dstring ds = DSTRING_INIT;
678
const char *libjvm_path = NULL;
683
char main_class_name[] = "com/sun/grid/jgdi/management/JGDIAgent";
685
jobject main_class = NULL;
686
char* additional_jvm_args = NULL;
687
char** additional_jvm_argv = NULL;
688
int additional_jvm_argc = 0;
689
lListElem *confEntry = NULL;
690
const int fixed_jvm_argc = 16;
693
DENTER(TOP_LAYER, "sge_run_jvm");
695
confEntry = sge_get_configuration_entry_by_name(ctx->get_qualified_hostname(ctx), "libjvm_path");
696
if (confEntry != NULL) {
697
const char *confVal = lGetString(confEntry, CF_value);
698
if (confVal && *confVal != '\0') {
699
libjvm_path = strdup(confVal);
701
lFreeElem(&confEntry);
704
if (libjvm_path == NULL) {
705
WARNING((SGE_EVENT, "libjvm_path is NULL\n"));
710
** get additional jvm args from configuration
712
confEntry = sge_get_configuration_entry_by_name(ctx->get_qualified_hostname(ctx), "additional_jvm_args");
713
if (confEntry != NULL) {
714
const char *confVal = lGetString(confEntry, CF_value);
715
if (confVal && *confVal != '\0') {
716
additional_jvm_args = strdup(confVal);
718
lFreeElem(&confEntry);
721
if (additional_jvm_args != NULL) {
722
DPRINTF(("additional_jvm_args: >%s<\n", additional_jvm_args));
723
additional_jvm_argv = string_list(additional_jvm_args, " ", NULL);
725
for (i=0; additional_jvm_argv[i] != NULL; i++) {
726
DPRINTF(("additional jvm arg[%d]: %s\n", i, additional_jvm_argv[i]));
727
additional_jvm_argc++;
729
jvm_argc = fixed_jvm_argc + additional_jvm_argc;
731
additional_jvm_argv = NULL;
732
jvm_argc = fixed_jvm_argc;
733
additional_jvm_argc = 0;
736
DPRINTF(("fixed_jvm_argc + additional_jvm_argc = jvm_argc: %d + %d = %d\n", fixed_jvm_argc, additional_jvm_argc, jvm_argc));
738
jvm_argv = (char**)sge_malloc(jvm_argc * sizeof(char*));
740
** adjust fixed_jvm_argc if an additional fixed argument line is added
742
jvm_argv[0] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.grid.jgdi.sgeRoot=%s", ctx->get_sge_root(ctx)));
743
jvm_argv[1] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.grid.jgdi.sgeCell=%s", ctx->get_default_cell(ctx)));
744
jvm_argv[2] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.grid.jgdi.caTop=%s", ctx->get_ca_root(ctx)));
745
jvm_argv[3] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.grid.jgdi.serverKeystore=%s/private/keystore", ctx->get_ca_local_root(ctx)));
746
jvm_argv[4] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.grid.jgdi.sgeQmasterSpoolDir=%s", ctx->get_qmaster_spool_dir(ctx)));
747
jvm_argv[5] = strdup(sge_dstring_sprintf(&ds, "-Djava.class.path=%s/lib/jgdi.jar:%s/lib/juti.jar", ctx->get_sge_root(ctx), ctx->get_sge_root(ctx)));
748
jvm_argv[6] = strdup(sge_dstring_sprintf(&ds, "-Djava.security.policy=%s/common/jmx/java.policy", ctx->get_cell_root(ctx)));
749
jvm_argv[7] = strdup("-Djava.security.manager=com.sun.grid.jgdi.management.JGDISecurityManager");
750
jvm_argv[8] = strdup(sge_dstring_sprintf(&ds, "-Djava.rmi.server.codebase=file://%s/lib/jgdi.jar file://%s/lib/juti.jar", ctx->get_sge_root(ctx), ctx->get_sge_root(ctx)));
751
jvm_argv[9] = strdup(sge_dstring_sprintf(&ds, "-Djava.library.path=%s/lib/%s", ctx->get_sge_root(ctx), sge_get_arch()));
752
jvm_argv[10] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.management.jmxremote.access.file=%s/common/jmx/jmxremote.access", ctx->get_cell_root(ctx)));
753
jvm_argv[11] = strdup(sge_dstring_sprintf(&ds, "-Dcom.sun.management.jmxremote.password.file=%s/common/jmx/jmxremote.password", ctx->get_cell_root(ctx)));
754
jvm_argv[12] = strdup(sge_dstring_sprintf(&ds, "-Djava.security.auth.login.config=%s/common/jmx/jaas.config", ctx->get_cell_root(ctx)));
755
jvm_argv[13] = strdup(sge_dstring_sprintf(&ds, "-Djava.util.logging.config.file=%s/common/jmx/logging.properties", ctx->get_cell_root(ctx)));
756
/* jvm_argv[13] = strdup("-Djava.util.logging.manager=com.sun.grid.jgdi.util.JGDILogManager"); */
757
jvm_argv[14] = strdup("-Djava.util.logging.manager=java.util.logging.LogManager");
758
jvm_argv[15] = strdup("-Xrs");
761
** add additional_jvm_args
763
for (i=0; i < additional_jvm_argc; i++) {
764
jvm_argv[fixed_jvm_argc+i] = strdup(additional_jvm_argv[i]);
765
additional_jvm_argv[i] = NULL;
767
FREE(additional_jvm_argv);
770
** process arguments of main method
772
main_argv[0] = strdup(sge_dstring_sprintf(&ds, "internal://%s@%s:"sge_u32, ctx->get_sge_root(ctx),
773
ctx->get_default_cell(ctx), ctx->get_sge_qmaster_port(ctx)));
775
sge_dstring_free(&ds);
781
for (i=0; i<jvm_argc; i++) {
782
DPRINTF(("jvm_argv[%d]: %s\n", i, jvm_argv[i]));
785
for (i=0; i<sizeof(main_argv)/sizeof(char*); i++) {
786
DPRINTF(("main_argv[%d]: %s\n", i, main_argv[i]));
789
env = create_vm(libjvm_path, jvm_argc, jvm_argv);
793
main_class = (*env)->FindClass(env, main_class_name);
794
if (main_class != NULL) {
795
if (invoke_main(env, main_class, sizeof(main_argv)/sizeof(char*), main_argv) != 0) {
796
CRITICAL((SGE_EVENT, "invoke_main failed\n"));
800
CRITICAL((SGE_EVENT, "main_class is NULL\n"));
809
** free allocated jvm args
811
for (i=0; i<jvm_argc; i++) {
817
** free main_argv[0] argument
824
/****** qmaster/threads/sge_jvm_wait_for_terminate() ****************************
826
* sge_jvm_wait_for_terminate() -- blocks the executing thread till shutdown
829
* void sge_jvm_wait_for_terminate(void)
832
* A call of this finction blocks the executing thread until termination
835
* The sign to continue execution can be triggered by signalling the
836
* condition 'Master_Jvm.cond_var'.
838
* This function should only be called thy the JVM thread.
847
* MT-NOTE: sge_jvm_wait_for_terminate() is MT safe
850
* qmaster/threads/sge_jvm_initialize()
851
* qmaster/threads/sge_jvm_cleanup_thread()
852
* qmaster/threads/sge_jvm_terminate()
853
* qmaster/threads/sge_jvm_wait_for_terminate()
854
* qmaster/threads/sge_jvm_main()
855
*******************************************************************************/
857
sge_jvm_wait_for_terminate(void)
859
DENTER(TOP_LAYER, "sge_thread_wait_for_signal");
861
sge_mutex_lock("master jvm struct", SGE_FUNC, __LINE__, &Master_Jvm.mutex);
863
while (Master_Jvm.shutdown_started == false) {
864
pthread_cond_wait(&Master_Jvm.cond_var, &Master_Jvm.mutex);
867
sge_mutex_unlock("master jvm struct", SGE_FUNC, __LINE__, &Master_Jvm.mutex);
873
/****** qmaster/threads/sge_jvm_cleanup_thread() ********************************
875
* sge_jvm_cleanup_thread() -- cleanup routine for the JVM thread
878
* void sge_jvm_cleanup_thread(void)
881
* Cleanup JVM thread related stuff.
883
* This function has to be executed only by the JVM thread.
884
* Ideally it should be the last function executed when the
885
* pthreads cancelation point is passed.
887
* 'Master_Jvm' is accessed by this function.
896
* MT-NOTE: sge_jvm_wait_for_terminate() is MT safe
899
* qmaster/threads/sge_jvm_initialize()
900
* qmaster/threads/sge_jvm_cleanup_thread()
901
* qmaster/threads/sge_jvm_terminate()
902
* qmaster/threads/sge_jvm_wait_for_terminate()
903
* qmaster/threads/sge_jvm_main()
904
*******************************************************************************/
906
sge_jvm_cleanup_thread(void *ctx_ref)
908
DENTER(TOP_LAYER, "sge_jvm_cleanup_thread");
910
sge_mutex_lock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
912
if (Master_Jvm.is_running) {
913
cl_thread_settings_t* thread = NULL;
916
* The JVM thread itself executes this function (sge_jvm_cleanup_thread())
917
* at the cancelation point as part of the cleanup.
918
* Therefore it has to unset the thread config before the
919
* cl_thread is deleted. Otherwise we might run into a race condition when logging
920
* is used after the call of cl_thread_list_delete_thread_without_join()
922
cl_thread_unset_thread_config();
925
* Delete the jvm thread but don't wait for termination
927
thread = cl_thread_list_get_first_thread(Main_Control.jvm_thread_pool);
928
cl_thread_list_delete_thread_without_join(Main_Control.jvm_thread_pool, thread);
931
* Trash the thread pool
933
cl_thread_list_cleanup(&Main_Control.jvm_thread_pool);
936
* now a new jvm can start
938
Master_Jvm.is_running = false;
943
sge_gdi_ctx_class_destroy((sge_gdi_ctx_class_t **)ctx_ref);
946
sge_mutex_unlock("master jvm struct", SGE_FUNC, __LINE__, &(Master_Jvm.mutex));
952
/****** qmaster/threads/sge_jvm_main() ******************************************
954
* sge_jvm_main() -- jvm thread function
957
* static void* sge_jvm_main(void* arg)
960
* The main function for the JVM thread
969
* MT-NOTE: sge_scheduler_main() is MT safe
971
* MT-NOTE: this is a thread function. Do NOT use this function
972
* MT-NOTE: in any other way!
975
* qmaster/threads/sge_jvm_initialize()
976
* qmaster/threads/sge_jvm_cleanup_thread()
977
* qmaster/threads/sge_jvm_terminate()
978
* qmaster/threads/sge_jvm_wait_for_terminate()
979
* qmaster/threads/sge_jvm_main()
980
*******************************************************************************/
982
sge_jvm_main(void *arg)
984
cl_thread_settings_t *thread_config = (cl_thread_settings_t*)arg;
985
time_t next_prof_output = 0;
986
monitoring_t monitor;
987
sge_gdi_ctx_class_t *ctx = NULL;
988
bool jvm_started = false;
989
bool do_endlessly = true;
991
DENTER(TOP_LAYER, "sge_jvm_main");
993
cl_thread_func_startup(thread_config);
994
sge_monitor_init(&monitor, thread_config->thread_name, GDI_EXT, MT_WARNING, MT_ERROR);
995
sge_qmaster_thread_init(&ctx, QMASTER, JVM_THREAD, true);
997
set_thread_name(pthread_self(), "JVM Thread");
998
conf_update_thread_profiling("JVM Thread");
1001
* main loop of the JVM thread
1003
while (do_endlessly) {
1006
thread_start_stop_profiling();
1008
if (jvm_started == false) {
1009
jvm_started = sge_run_jvm(ctx, arg, &monitor);
1012
thread_output_profiling("JVM thread profiling summary:\n", &next_prof_output);
1013
sge_monitor_output(&monitor);
1016
* to prevent high cpu load if jvm is not started
1018
sge_jvm_wait_for_terminate();
1021
* pthread cancelation point
1025
* sge_jvm_cleanup_thread() is the last function which should
1026
* be called so it is pushed first
1028
pthread_cleanup_push(sge_jvm_cleanup_thread, (void*)&ctx);
1029
pthread_cleanup_push((void (*)(void *))sge_jvm_cleanup_monitor, (void *)&monitor);
1030
cl_thread_func_testcancel(thread_config);
1031
pthread_cleanup_pop(execute);
1032
pthread_cleanup_pop(execute);
1033
} while (sge_thread_has_shutdown_started());
1037
* Don't add cleanup code here. It will never be executed. Instead register
1038
* a cleanup function with pthread_cleanup_push()/pthread_cleanup_pop() before
1039
* the call of cl_thread_func_testcancel()
1041
* NOTE: number of pthread_cleanup_push() and pthread_cleanup_pop() calls have
1042
* no be equivalent. If this is not the case you might get funny
1043
* COMPILER ERRORS here.