1
/*******************************************************************************
2
* Copyright (c) 2009 Eucalyptus Systems, Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, only version 3 of the License.
9
* This file is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Please contact Eucalyptus Systems, Inc., 130 Castilian
18
* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
19
* if you need additional information or have any questions.
22
* Support for dropping privileges is derived from
23
* commons-daemon's jsvc. (http://commons.apache.org/daemon/)
25
* Copyright 2001-2004 The Apache Software Foundation.
27
* Licensed under the Apache License, Version 2.0 (the "License");
28
* you may not use this file except in compliance with the License.
29
* You may obtain a copy of the License at
31
* http://www.apache.org/licenses/LICENSE-2.0
33
* Unless required by applicable law or agreed to in writing, software
34
* distributed under the License is distributed on an "AS IS" BASIS,
35
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
* See the License for the specific language governing permissions and
37
* limitations under the License.
39
******************************************************************************
40
* Author: chris grzegorczyk grze@eucalyptus.com
41
******************************************************************************/
42
#include "eucalyptus-bootstrap.h"
50
#include <sys/types.h>
58
#include <sys/prctl.h>
59
#include <sys/syscall.h>
62
extern char **environ;
64
char *java_library(euca_opts*, java_home_t*);
65
int java_init(euca_opts*, java_home_t*);
68
static void java_fail(void) { exit(1); }
70
static java_home_t *get_java_home( char *path ) {
71
java_home_t *data = NULL;
73
int x = -1, k = 0, i = 0;
75
if( path == NULL ) return NULL;
76
__debug( "Looking for libjvm in %s", path );
77
__abort(NULL, (CHECK_ISDIR( path ) == 0 ),"Path %s is not a directory", path );
78
data = (java_home_t *) malloc( sizeof(java_home_t) );
79
data->path = strdup( path );
82
while( libjvm_paths[ ++x ] != NULL ) {
83
__abort(NULL, ((k = snprintf( buf, 1024, libjvm_paths[ x ], path ) ) <= 0 ),"Error mangling jvm path" );
84
__debug( "Attempting to locate VM library %s", buf );
85
if( CHECK_ISREG( buf ) == 1 ) {
86
data->jvms = (jvm_info_t **) malloc( 2 * sizeof(jvm_info_t *) );
87
data->jvms[ i ] = (jvm_info_t *) malloc( sizeof(jvm_info_t) );
88
data->jvms[ i ]->libjvm_path = strdup( buf );
92
data->jvms[ i ]->name = base;
93
data->jvms[ ++i ] = NULL;
101
static void handler( int sig ) {
104
__debug( "Caught SIGTERM: Scheduling a shutdown" );
105
if( stopping == 1 ) __error( "Shutdown or reload already scheduled" );
109
__debug( "Caught SIGINT: Scheduling a shutdown" );
110
if( stopping == 1 ) __error( "Shutdown or reload already scheduled" );
114
__debug( "Caught SIGHUP: Scheduling a reload" );
115
if( stopping == 1 ) __error( "Shutdown or reload already scheduled" );
116
else stopping = 1,doreload = 1;
119
__debug( "Caught unknown signal %d", sig );
124
static int set_user_group( char *user, int uid, int gid ) {
125
__abort(0,user==NULL,"No user to setuid to.");
126
__abort(-1, setgid( gid ) != 0,"Cannot set group id for user '%s'", user );
127
if( initgroups( user, gid ) != 0 ) __abort(-1, getuid( ) != uid, "Cannot set supplement group list for user '%s'", user );
128
__abort(-1, setuid( uid ) != 0, "Cannot set user id for user '%s'", user );
131
static int set_caps(int caps)
133
struct __user_cap_header_struct caphead;
134
struct __user_cap_data_struct cap;
136
memset(&caphead, 0, sizeof caphead);
137
caphead.version = _LINUX_CAPABILITY_VERSION;
139
memset(&cap, 0, sizeof cap);
140
cap.effective = caps;
141
cap.permitted = caps;
142
cap.inheritable = caps;
143
if (syscall(__NR_capset, &caphead, &cap) < 0) {
144
__error("syscall failed in set_caps");
150
static int set_keys_ownership(char *home, int uid, int gid){
154
snprintf(filename, 2047, "%s/var/lib/eucalyptus/keys/euca.p12", home);
155
rc = chown(filename, uid, gid);
160
static int linuxset_user_group(char *user, int uid, int gid){
161
if (set_caps(CAPS)!=0) __abort(-1,getuid()!= uid,"set_caps(CAPS) failed");
162
__abort(-1,(prctl(PR_SET_KEEPCAPS,1,0,0,0) < 0),"prctl failed in linuxset_user_group");
163
__abort(-1,(set_user_group(user,uid,gid)!=0),"set_user_group failed in linuxset_user_group");
164
if (set_caps(CAPSMIN)!=0) __abort(-1,(getuid()!= uid),"set_caps(CAPSMIN) failed");
167
static int checkuser( char *user, uid_t *uid, gid_t *gid ) {
168
struct passwd *pwds = NULL;
171
__abort(1, user == NULL,"" );
172
pwds = getpwnam( user );
173
__abort(0, (pwds == NULL ),"Invalid user name '%s' specified", user );
177
__abort(0,( pid == -1 ), "Cannot validate user name" );
179
__die( set_user_group( user, *uid, *gid ) != 0,"set_user_group failed." );
182
while( waitpid( pid, &status, 0 ) != pid );
183
if( WIFEXITED( status ) ) {
184
status = WEXITSTATUS( status );
185
__abort(0, (status != 0),"User '%s' validated", user );
190
static void controller( int sig ) {
195
__debug( "Forwarding signal %d to process %d", sig, child_pid );
196
kill( child_pid, sig );
197
signal( sig, controller );
200
__debug( "Caught unknown signal %d", sig );
205
static void * signal_set( int sig, void * newHandler ) {
206
void *hand = signal( sig, newHandler );
207
if (hand==SIG_ERR) hand=NULL;
208
if( hand == handler || hand == controller )
213
static int __get_pid( char *pidpath ) {
214
FILE* pidfile; int pid;
215
__abort(-1,(pidfile = fopen( pidpath, "r"))==NULL,"");
216
__abort(-1,(fscanf(pidfile,"%d",&pid)<0),"Failed to read pid file.");
218
__abort(pid,(kill( pid, 0 )==0),"");
221
static int __write_pid( char *pidpath ) {
223
__abort(0,__get_pid(pidpath)>0,"");
224
__abort(-1,(pidfile = fopen( pidpath, "w"))==NULL,"");
225
fprintf( pidfile, "%d\n", (int) getpid( ) ),fflush(pidfile),fclose(pidfile);
230
static int wait_child( euca_opts *args, int pid ) {
233
while(rc <= 0 && timer < (15000000)) {
234
usleep(50000),timer += 50000;
235
__die((rc = waitpid(pid, &status, WNOHANG))<0,"Waiting for child failed?!?");
236
if( WIFEXITED( status ) ) return WEXITSTATUS( status );
241
static int stop_child( euca_opts *args ) {
242
int pid = __get_pid( GETARG(args,pidfile) );
243
if( pid <= 0 ) return -1;
244
kill( pid, SIGTERM );
245
return wait_child(args,pid);
248
static int child( euca_opts *args, java_home_t *data, uid_t uid, gid_t gid ) {
251
__write_pid( GETARG(args,pidfile) );
253
__die(java_init( args, data ) != 1, "Failed to initialize Eucalyptus.");
254
__die((r=(*env)->CallBooleanMethod(env,bootstrap.instance,bootstrap.init))==0,"Failed to init Eucalyptus.");
255
__abort(4, set_keys_ownership( GETARG( args, home ), uid, gid ) != 0,"Setting ownership of keyfile failed." );
256
__abort(4, linuxset_user_group( GETARG( args, user ), uid, gid ) != 0,"Setting the user failed." );
257
__abort(4, (set_caps(0)!=0), "set_caps (0) failed");
258
__die((r=(*env)->CallBooleanMethod(env,bootstrap.instance,bootstrap.load))==0,"Failed to load Eucalyptus.");
259
__die((r=(*env)->CallBooleanMethod(env,bootstrap.instance,bootstrap.start))==0,"Failed to start Eucalyptus.");
260
handle._hup = signal_set( SIGHUP, handler );
261
handle._term = signal_set( SIGTERM, handler );
262
handle._int = signal_set( SIGINT, handler );
263
child_pid = getpid( );
264
__debug( "Waiting for a signal to be delivered" );
265
while( !stopping ) sleep( 60 );
266
__debug( "Shutdown or reload requested: exiting" );
267
__die((r=(*env)->CallBooleanMethod(env,bootstrap.instance,bootstrap.stop))==0,"Failed to stop Eucalyptus.");
268
if( doreload == 1 ) ret = EUCA_RET_RELOAD;
270
__die((r=(*env)->CallBooleanMethod(env,bootstrap.instance,bootstrap.destroy))==0,"Failed to destroy Eucalyptus.");
271
__die((JVM_destroy( ret ) != 1), "Failed trying to destroy JVM... bailing out seems like the right thing to do" );
275
static FILE *loc_freopen( char *outfile, char *mode, FILE *stream ) {
277
__abort(stream,(ftest = fopen( outfile, mode ))==NULL,"Unable to redirect to %s\n", outfile );
279
return freopen( outfile, mode, stream );
282
static void set_output( char *outfile, char *errfile ) {
283
if( freopen( "/dev/null", "r", stdin ) );//hack
284
__debug( "redirecting stdout to %s and stderr to %s", outfile, errfile );
285
if( debug == 1 && strcmp( errfile, "/dev/null" ) == 0 ) return;
286
if( strcmp( outfile, "&2" ) == 0 && strcmp( errfile, "&1" ) == 0 ) outfile = "/dev/null";
287
if( strcmp( outfile, "&1" ) != 0 ) loc_freopen( outfile, "a", stdout );
288
if( strcmp( errfile, "&2" ) != 0 ) loc_freopen( errfile, "a", stderr );
291
if( dup( 1 ) );//hack
293
if( strcmp( outfile, "&2" ) == 0 ) {
295
if( dup( 2 ) );//hack
299
int main( int argc, char *argv[ ] ) {
301
euca_opts *args = &euca_args;
302
java_home_t *data = NULL;
307
if( arguments( argc, argv, args ) != 0 ) exit( 1 );
308
debug = args->verbose_flag || args->debug_flag;
309
if( args->stop_flag == 1 ) return stop_child( args );
310
if( checkuser( GETARG( args, user ), &uid, &gid ) == 0 ) return 1;
311
char* java_home_user = GETARG(args,java_home);
312
char* java_home_env = getenv( "JAVA_HOME" );
313
if( java_home_user != NULL ) {
314
__debug("Trying user supplied java home: %s", java_home_user);
315
data = get_java_home(java_home_user);
317
if( data == NULL && java_home_env != NULL ) {
318
__debug("Trying environment JAVA_HOME: %s", java_home_env);
319
data = get_java_home(java_home_env);
321
__debug("TODO: loop through common locations for JVMs here.");
323
__error( "Cannot locate Java Home" );
328
__debug( "+-- DUMPING JAVA HOME STRUCTURE ------------------------" );
329
__debug( "| Java Home: \"%s\"", PRINT_NULL( data->path ) );
330
__debug( "| Found JVMs: %d", data->jnum );
331
for( x = 0; x < data->jnum; x++ ) {
332
jvm_info_t *jvm = data->jvms[ x ];
333
__debug( "| JVM Name: \"%s\"", PRINT_NULL( jvm->name ) );
334
__debug( "| \"%s\"", PRINT_NULL( jvm->libjvm_path ) );
336
__debug( "+-------------------------------------------------------" );
338
if( strcmp( argv[ 0 ], "eucalyptus-cloud" ) != 0 ) {
339
char *oldpath = getenv( "LD_LIBRARY_PATH" ),*libf = java_library( args, data );
340
char *old = argv[ 0 ],buf[ 32768 ],*tmp = NULL,*p1 = NULL,*p2 = NULL;
342
tmp = strrchr( p1, '/' );
343
if( tmp != NULL ) tmp[ 0 ] = '\0';
345
tmp = strrchr( p2, '/' );
346
if( tmp != NULL ) tmp[ 0 ] = '\0';
347
if( oldpath == NULL ) snprintf( buf, 32768, "%s:%s:%s/bin/linux-x64", p1, p2, GETARG(args,profiler_home) );
348
else snprintf( buf, 32768, "%s:%s:%s:%s/bin/linux-x64", oldpath, p1, p2, GETARG(args,profiler_home) );
351
setenv( "LD_LIBRARY_PATH", tmp, 1 );
352
__debug( "Invoking w/ LD_LIBRARY_PATH=%s", getenv( "LD_LIBRARY_PATH" ) );
353
argv[ 0 ] = "eucalyptus-cloud";
354
execve( old, argv, environ );
355
__error( "Cannot execute process" );
358
__debug( "Running w/ LD_LIBRARY_PATH=%s", getenv( "LD_LIBRARY_PATH" ) );
359
if(args->fork_flag) {
361
__die(( pid == -1 ),"Cannot detach from parent process" );
362
if( pid != 0 ) return wait_child( args, pid );
365
set_output(GETARG(args,out), GETARG(args,err));
366
while( ( pid = fork( ) ) != -1 ) {
367
if( pid == 0 ) exit( child( args, data, uid, gid ) );
369
signal( SIGHUP, controller );
370
signal( SIGTERM, controller );
371
signal( SIGINT, controller );
372
while( waitpid( pid, &status, 0 ) != pid );
373
if( WIFEXITED( status ) ) {
374
status = WEXITSTATUS( status );
375
__debug( "Eucalyptus exited with status: %d", status );
376
if( status != 122 ) unlink( GETARG( args, pidfile ) );
377
if( status == 123 ) {
378
__debug( "Reloading service" );
382
__debug( "Service shut down" );
385
__error( "Service exit with a return value of %d", status );
388
__error( "Service did not exit cleanly exit value %d", status );
392
__error( "Cannot decouple controller/child processes" );
397
int ld_library_path_set=0;
398
typedef void *dso_handle;
400
int dso_unlink(dso_handle libr) {
401
if (dlclose(libr)==0) return 1;
404
char *dso_error(void) {
408
static void hello(JNIEnv *env, jobject source) {
409
__error("uid=%d,euid=%d,gid=%d,egid=%d",getuid(),geteuid(),getgid(),getegid());
412
static void shutdown(JNIEnv *env, jobject source, jboolean reload) {
413
__debug("Shutdown requested (reload is %d)",reload);
414
if (reload==1) __debug( "Killing self with HUP signal: %d", kill( child_pid, SIGHUP ) );
415
else __debug( "Killing self with TERM signal: %d", kill( child_pid, SIGTERM ) );
419
char *java_library(euca_opts *args, java_home_t *data) {
420
char *libjvm_path=NULL;
423
__error("Cannot find any VM in Java Home %s",data->path);
426
if (args->jvm_name_given==0) {
427
libjvm_path=data->jvms[0]->libjvm_path;
429
for (x=0; x<data->jnum; x++) {
430
if (data->jvms[x]->name==NULL) continue;
431
if (strcmp(GETARG(args,jvm_name),data->jvms[x]->name)==0) {
432
libjvm_path=data->jvms[x]->libjvm_path;
437
if (libjvm_path==NULL) {
438
__error("Failed to locate usable JVM %s %s",GETARG(args,jvm_name),libjvm_path);
441
__debug("Using libjvm.so in %s",libjvm_path);
445
void euca_load_bootstrapper(void) {
446
__die((bootstrap.class_name=((*env)->NewStringUTF(env,EUCA_MAIN)))==NULL,"Cannot create string for class name.");
447
__die((bootstrap.clazz=((*env)->FindClass(env,EUCA_MAIN)))==NULL,"Cannot find Eucalyptus bootstrapper: %s.",EUCA_MAIN);
448
__debug("Found Eucalyptus bootstrapper: %s",EUCA_MAIN);
449
__die((bootstrap.class_ref = (*env)->NewGlobalRef(env, bootstrap.clazz))==NULL,"Cannot create global ref for %s.",EUCA_MAIN);
451
JNINativeMethod shutdown_method = { "shutdown","(Z)V",shutdown };
452
__die((*env)->RegisterNatives(env,bootstrap.clazz,&shutdown_method,1)!=0,"Cannot register native method: shutdown.");
453
JNINativeMethod hello_method = { "hello","()V",hello };
454
__die((*env)->RegisterNatives(env,bootstrap.clazz,&hello_method,1)!=0,"Cannot register native method: hello.");
455
__debug("Native methods registered.");
457
__die((bootstrap.constructor=(*env)->GetStaticMethodID(env, bootstrap.clazz,euca_get_instance.method_name, euca_get_instance.method_signature))==NULL,"Failed to get reference to default constructor.");
458
__die((bootstrap.instance=(*env)->CallStaticObjectMethod(env,bootstrap.clazz,bootstrap.constructor))==NULL,"Failed to create instance of bootstrapper.");
459
__debug("Created bootstrapper instance.");//TODO: fix all these error messages..
460
__die((bootstrap.init=(*env)->GetMethodID(env,bootstrap.clazz,euca_init.method_name,euca_init.method_signature))==NULL,"Failed to get method reference for load.");
461
__debug("-> bound method: init");
462
__die((bootstrap.load=(*env)->GetMethodID(env,bootstrap.clazz,euca_load.method_name,euca_load.method_signature))==NULL,"Failed to get method reference for load.");
463
__debug("-> bound method: load");
464
__die((bootstrap.start=(*env)->GetMethodID(env,bootstrap.clazz,euca_start.method_name,euca_start.method_signature))==NULL,"Failed to get method reference for start.");
465
__debug("-> bound method: start");
466
__die((bootstrap.stop=(*env)->GetMethodID(env,bootstrap.clazz,euca_stop.method_name,euca_stop.method_signature))==NULL,"Failed to get method reference for stop.");
467
__debug("-> bound method: stop");
468
__die((bootstrap.destroy=(*env)->GetMethodID(env,bootstrap.clazz,euca_destroy.method_name,euca_destroy.method_signature))==NULL,"Failed to get method reference for destroy.");
469
__debug("-> bound method: destroy");
470
__die((bootstrap.check=(*env)->GetMethodID(env,bootstrap.clazz,euca_check.method_name,euca_check.method_signature))==NULL,"Failed to get method reference for check.");
471
__debug("-> bound method: check");
472
__die((bootstrap.version=(*env)->GetMethodID(env,bootstrap.clazz,euca_version.method_name,euca_version.method_signature))==NULL,"Failed to get method reference for version.");
473
__debug("-> bound method: version");
476
char* java_library_path(euca_opts *args) {
477
#define JAVA_PATH_LEN 65536
478
char lib_dir[256],etc_dir[256],script_dir[256],*jar_list=(char*)malloc(JAVA_PATH_LEN*sizeof(char));
479
__die(( strlen(GETARG(args,home))+strlen(EUCA_LIB_DIR)>=254),"Directory path too long: %s/%s", GETARG(args,home), EUCA_LIB_DIR);
480
snprintf(lib_dir,255,"%s%s",GETARG(args,home),EUCA_LIB_DIR);
481
snprintf(etc_dir,255,"%s%s",GETARG(args,home),EUCA_ETC_DIR);
482
snprintf(script_dir,255,"%s%s",GETARG(args,home),EUCA_SCRIPT_DIR);
483
if(!CHECK_ISDIR(lib_dir) ) __die(1,"Can't find library directory %s", lib_dir );
485
wb += snprintf(jar_list+wb,JAVA_PATH_LEN-wb,"-Djava.class.path=%s:",etc_dir);
486
wb += snprintf(jar_list+wb,JAVA_PATH_LEN-wb,"%s",script_dir);
487
DIR* lib_dir_p = opendir(lib_dir);
488
struct direct *dir_ent;
489
while ((dir_ent = readdir(lib_dir_p))!=0) {
490
if (strcmp(dir_ent->d_name,".") != 0 && strcmp(dir_ent->d_name,"..") != 0 && strcmp(dir_ent->d_name,"openjdk-crypto.jar") != 0 && strstr(dir_ent->d_name,"disabled") == NULL && strstr(dir_ent->d_name,"eucalyptus-") != NULL ) {
492
snprintf(jar,255,"%s/%s",lib_dir,dir_ent->d_name);
493
if( (CHECK_ISREG(jar) || CHECK_ISLNK(jar)) ) wb += snprintf(jar_list+wb,JAVA_PATH_LEN-wb,":%s",jar);
497
lib_dir_p = opendir(lib_dir);
498
while ((dir_ent = readdir(lib_dir_p))!=0) {
499
if (strcmp(dir_ent->d_name,".") != 0 && strcmp(dir_ent->d_name,"..") != 0 && strcmp(dir_ent->d_name,"openjdk-crypto.jar") != 0 && strstr(dir_ent->d_name,"disabled") == NULL && strstr(dir_ent->d_name,"eucalyptus-") == NULL) {
501
snprintf(jar,255,"%s/%s",lib_dir,dir_ent->d_name);
502
if( (CHECK_ISREG(jar) || CHECK_ISLNK(jar)) ) wb += snprintf(jar_list+wb,JAVA_PATH_LEN-wb,":%s",jar);
509
int java_init(euca_opts *args, java_home_t *data) {
510
jint (*hotspot_main)(JavaVM **, JNIEnv **, JavaVMInitArgs *);
511
char *libjvm_path=NULL;
512
if ((libjvm_path=java_library(args,data))==NULL) __fail("Cannot locate JVM library file");
513
dso_handle libjvm_handle=NULL;
514
__die((libjvm_handle=dlopen(libjvm_path,RTLD_GLOBAL|RTLD_NOW))==NULL,"Cannot dynamically link to %s\n%s",libjvm_path,dso_error());
515
__debug("JVM library %s loaded",libjvm_path);
516
if ((hotspot_main=dlsym(libjvm_handle,"JNI_CreateJavaVM"))==NULL) __fail("Cannot find JVM library entry point");
518
arg.ignoreUnrecognized=0;
519
#if defined(JNI_VERSION_1_4)
520
arg.version=JNI_VERSION_1_4;
522
arg.version=JNI_VERSION_1_2;
524
JavaVMOption *opt=NULL;
525
char* java_class_path = java_library_path(args);
526
__debug("Using classpath:\n%s",java_class_path);
527
#define JVM_MAX_OPTS 128
529
opt=(JavaVMOption *)malloc(JVM_MAX_OPTS*sizeof(JavaVMOption));
530
for(i=0;i<JVM_MAX_OPTS;i++) opt[i].extraInfo=NULL;
532
while(jvm_default_opts[++i]!= NULL) JVM_ARG(opt[++x],jvm_default_opts[i],GETARG(args,home));
533
if(args->exhaustive_flag) {
534
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.db=TRACE");
535
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.user=TRACE");
536
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.cc=TRACE");
537
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.external=TRACE");
539
if(args->exhaustive_db_flag) {
540
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.db=TRACE");
542
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.db=FATAL");
544
if(args->exhaustive_cc_flag) {
545
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.cc=TRACE");
547
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.cc=FATAL");
549
if(args->exhaustive_user_flag) {
550
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.user=TRACE");
552
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.user=FATAL");
554
if(args->exhaustive_external_flag) {
555
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.external=TRACE");
557
JVM_ARG(opt[++x],"-Deuca.log.exhaustive.external=FATAL");
560
JVM_ARG(opt[++x],"-Deuca.log.level=%1$s",GETARG(args,log_level));
561
JVM_ARG(opt[++x],"-Deuca.log.appender=%1$s",GETARG(args,log_appender));
562
JVM_ARG(opt[++x],"-Deuca.db.port=%1$d",9001);//TODO: add cli parameter
563
JVM_ARG(opt[++x],"-Deuca.db.host=%1$s",GETARG(args,cloud_host));
564
JVM_ARG(opt[++x],"-Deuca.walrus.host=%1$s",GETARG(args,walrus_host));
565
if(args->disable_dns_flag) {
566
JVM_ARG(opt[++x],"-Deuca.disable.dns=true");
568
if(args->disable_storage_flag) {
569
JVM_ARG(opt[++x],"-Deuca.disable.storage=true");
571
if(args->disable_cloud_flag) {
572
JVM_ARG(opt[++x],"-Deuca.disable.eucalyptus=true");
574
if(args->disable_walrus_flag) {
575
JVM_ARG(opt[++x],"-Deuca.disable.walrus=true");
577
if(args->remote_dns_flag) {
578
JVM_ARG(opt[++x],"-Deuca.remote.dns=true");
580
if(args->remote_storage_flag) {
581
JVM_ARG(opt[++x],"-Deuca.remote.storage=true");
583
if(args->remote_cloud_flag) {
584
JVM_ARG(opt[++x],"-Deuca.remote.cloud=true");
586
if(args->remote_walrus_flag) {
587
JVM_ARG(opt[++x],"-Deuca.remote.walrus=true");
589
if(args->disable_iscsi_flag) {
590
JVM_ARG(opt[++x],"-Deuca.disable.iscsi=true");
592
if(args->debug_flag) {
593
JVM_ARG(opt[++x],"-Xdebug");
594
JVM_ARG(opt[++x],"-Xrunjdwp:transport=dt_socket,server=y,suspend=%2$s,address=%1$d",GETARG(args,debug_port),(args->debug_suspend_flag?"y":"n"));
596
if(args->debug_flag||args->profile_flag) {
597
JVM_ARG(opt[++x],"-Dcom.sun.management.jmxremote");
598
JVM_ARG(opt[++x],"-XX:+HeapDumpOnOutOfMemoryError");
599
JVM_ARG(opt[++x],"-XX:HeapDumpPath=%s/var/log/eucalyptus/",GETARG(args,home));
601
if(args->profile_flag && args->agentlib_given ) {
602
JVM_ARG(opt[++x],"-agentlib:%s",GETARG(args,agentlib));
603
} else if(args->profile_flag) {
604
JVM_ARG(opt[++x],"-agentlib:jprofilerti=port=8849");
605
JVM_ARG(opt[++x],"-Xbootclasspath/a:%1$s/bin/agent.jar",GETARG(args,profiler_home));
607
for (i=0; i<args->jvm_args_given; i++) JVM_ARG(opt[++x],"-X%s",args->jvm_args_arg[i]);
608
for (i=0; i<args->define_given; i++) JVM_ARG(opt[++x],"-D%s",args->define_arg[i]);
610
opt[++x].optionString=java_class_path;
611
opt[x].extraInfo=NULL;
612
opt[++x].optionString="abort";
613
opt[x].extraInfo=java_fail;
618
__debug("+-------------------------------------------------------");
619
__debug("| Version: %x", arg.version);
620
__debug("| Ignore Unrecognized Arguments: %d", arg.ignoreUnrecognized);
621
__debug("| Extra options: %d", arg.nOptions);
622
for (x=0; x<arg.nOptions; x++) __debug("| \"%-80.80s\" (0x%p)",opt[x].optionString, opt[x].extraInfo);
623
__debug("+-------------------------------------------------------");
625
__debug("Starting JVM.");
627
while((ret=(*hotspot_main)(&jvm, &env, &arg)==123));
628
__die(ret<0,"Failed to create JVM");
629
java_load_bootstrapper();
633
int JVM_destroy(int code) {
636
__die((system=(*env)->FindClass(env,"java/lang/System"))==NULL,"Cannot find class java/lang/System.");
637
__die((method=(*env)->GetStaticMethodID(env,system,"exit","(I)V"))==NULL,"Cannot find \"System.exit(int)\" entry point.");
638
__debug("Calling System.exit(%d)",code);
639
(*env)->CallStaticVoidMethod(env,system,method,(jint)code);
640
if ((*jvm)->DestroyJavaVM(jvm)!=0) return 0;
641
__debug("JVM destroyed.");
645
void java_sleep(int wait) {
648
__die( ((clsThread = (*env)->FindClass(env,"java/lang/Thread"))==NULL),"Cannot find java/lang/Thread class");
649
__die( ((method=(*env)->GetStaticMethodID(env,clsThread,"sleep","(J)V"))==NULL), "Cannot found the sleep entry point");
650
(*env)->CallStaticVoidMethod(env,clsThread,method,(jlong)wait*1000);