~ubuntu-core-dev/ubuntu/maverick/eucalyptus/devel

« back to all changes in this revision

Viewing changes to .pc/10-disable-iscsi.patch/clc/modules/bootstrap/eucalyptus-bootstrap.c

  • Committer: Dustin Kirkland
  • Date: 2010-07-22 08:41:57 UTC
  • mfrom: (1050.1.19 ubuntu)
  • Revision ID: kirkland@x200-20100722084157-zh2p8dkawznvxxpn
Approving Dave Walker's merge of new upstream Eucalyptus 2.0 release.

Dustin Kirkland <kirkland@canonical.com>

* New major upstream version merge, 2.0 (r1211).
  - 01-wsdl-stubs.patch, debian/wsdl.md5sums: wsdl stubs updated.
  - 11-state-cleanup-memleakfix.patch: Removed, fixed upstream.
  - 21-eucalyptus-1.7-with-gwt-1.6.4.patch: New patch, allows 
    eucalyptus-1.7 to be built against gwt 1.6.4. Based on patch courtesy 
    of Dmitrii Zagorodnov, upstream. (LP: #597330)
* debian/eucalyptus-java-common.links: 
  - Changed symlink for groovy, point to groovy.all.jar, making compatiable 
    with groovy versions >1.7. (LP: #595421)
  - Added ant.jar & jetty-rewrite-handler.jar as they are now required.
* debian/control
  - & debian/build-jars: Added libjavassist-java and libjetty-extra-java as 
    build dependencies.
  - Added libjetty-extra-java as a dependency of eucalyptus-java-common
* The binary resulting jar's have been renamed from eucalyptus-*-1.6.2.jar
  to eucalyptus-*-main.jar:    
  - debian/eucalyptus-cc.upstart
  - debian/eucalyptus-cloud.install
  - debian/eucalyptus-common.eucalyptus.upstart
  - debian/eucalyptus-java-common.install
  - debian/eucalyptus-network.upstart
  - debian/eucalyptus-sc.install
  - debian/eucalyptus-walrus.install
* debian/eucalyptus-java-common.install: New upstream jars that have been
  installed:
  - eucalyptus-db-hsqldb-ext-main.jar
  - eucalyptus-component-main.jar
* debian/control:
  - Updated Standards Version to 3.8.4 (no change)
  - Updated the upstream Homepage to: http://open.eucalyptus.com/
  - Changed Vcs-Bzr to reflect new location of Ubuntu hosted development branch.
  - Made the Build Dependency of groovy and the binary eucalyptus-java-common
    package depend on version >=1.7.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*******************************************************************************
2
 
 * Copyright (c) 2009  Eucalyptus Systems, Inc.
3
 
 *
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.
7
 
 *
8
 
 *
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
12
 
 * for more details.
13
 
 *
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/>.
16
 
 *
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.
20
 
 *
21
 
 *
22
 
 * Support for dropping privileges is derived from
23
 
 * commons-daemon's jsvc. (http://commons.apache.org/daemon/)
24
 
 *
25
 
 * Copyright 2001-2004 The Apache Software Foundation.
26
 
 *
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
30
 
 *
31
 
 *        http://www.apache.org/licenses/LICENSE-2.0
32
 
 *
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.
38
 
 *
39
 
 ******************************************************************************
40
 
 * Author: chris grzegorczyk grze@eucalyptus.com
41
 
 ******************************************************************************/
42
 
#include "eucalyptus-bootstrap.h"
43
 
 
44
 
#include <time.h>
45
 
#include <string.h>
46
 
#include <dlfcn.h>
47
 
#include <signal.h>
48
 
#include <libgen.h>
49
 
#include <unistd.h>
50
 
#include <sys/types.h>
51
 
#include <sys/stat.h>
52
 
#include <sys/dir.h>
53
 
#include <sys/wait.h>
54
 
#include <fcntl.h>
55
 
#include <stdio.h>
56
 
#include <pwd.h>
57
 
#include <grp.h>
58
 
#include <sys/prctl.h>
59
 
#include <sys/syscall.h>
60
 
#define _LINUX_FS_H 
61
 
 
62
 
extern char **environ;
63
 
pid_t child_pid = 0;
64
 
char *java_library(euca_opts*, java_home_t*);
65
 
int java_init(euca_opts*, java_home_t*);
66
 
int JVM_destroy(int);
67
 
 
68
 
static void java_fail(void) { exit(1); }
69
 
 
70
 
static java_home_t *get_java_home( char *path ) {
71
 
        java_home_t *data = NULL;
72
 
        char buf[ 1024 ];
73
 
        int x = -1, k = 0, i = 0;
74
 
 
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 );
80
 
        data->jvms = NULL;
81
 
        data->jnum = 0;
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 );
89
 
                        char *dir, *base;
90
 
                        dir = dirname(buf);
91
 
                        base = basename(dir);
92
 
                        data->jvms[ i ]->name = base;
93
 
                        data->jvms[ ++i ] = NULL;
94
 
                        data->jnum = i;
95
 
                        return data;
96
 
                }
97
 
        }
98
 
        return data;
99
 
}
100
 
 
101
 
static void handler( int sig ) {
102
 
        switch( sig ) {
103
 
                case SIGTERM:
104
 
                        __debug( "Caught SIGTERM: Scheduling a shutdown" );
105
 
                        if( stopping == 1 ) __error( "Shutdown or reload already scheduled" );
106
 
                        else stopping = 1;
107
 
                        break;
108
 
                case SIGINT:
109
 
                        __debug( "Caught SIGINT: Scheduling a shutdown" );
110
 
                        if( stopping == 1 ) __error( "Shutdown or reload already scheduled" );
111
 
                        else stopping = 1;
112
 
                        break;
113
 
                case SIGHUP:
114
 
                        __debug( "Caught SIGHUP: Scheduling a reload" );
115
 
                        if( stopping == 1 ) __error( "Shutdown or reload already scheduled" );
116
 
                        else stopping = 1,doreload = 1;
117
 
                        break;
118
 
                default:
119
 
                        __debug( "Caught unknown signal %d", sig );
120
 
                        break;
121
 
        }
122
 
}
123
 
 
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 );
129
 
        return 0;
130
 
}
131
 
static int set_caps(int caps)
132
 
{
133
 
        struct __user_cap_header_struct caphead;
134
 
        struct __user_cap_data_struct cap;
135
 
 
136
 
        memset(&caphead, 0, sizeof caphead);
137
 
        caphead.version = _LINUX_CAPABILITY_VERSION;
138
 
        caphead.pid = 0;
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");
145
 
                return -1;
146
 
        }
147
 
        return 0;
148
 
}
149
 
 
150
 
static int set_keys_ownership(char *home, int uid, int gid){
151
 
  char filename[2048];
152
 
  int rc;
153
 
  
154
 
  snprintf(filename, 2047, "%s/var/lib/eucalyptus/keys/euca.p12", home);
155
 
  rc = chown(filename, uid, gid);
156
 
  
157
 
  return(0);
158
 
}
159
 
 
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");
165
 
        return 0;
166
 
}
167
 
static int checkuser( char *user, uid_t *uid, gid_t *gid ) {
168
 
        struct passwd *pwds = NULL;
169
 
        int status = 0;
170
 
        pid_t pid = 0;
171
 
        __abort(1, user == NULL,"" );
172
 
        pwds = getpwnam( user );
173
 
        __abort(0, (pwds == NULL ),"Invalid user name '%s' specified", user );
174
 
        *uid = pwds->pw_uid;
175
 
        *gid = pwds->pw_gid;
176
 
        pid = fork( );
177
 
        __abort(0,( pid == -1 ), "Cannot validate user name" );
178
 
        if( pid == 0 ) {
179
 
                __die( set_user_group( user, *uid, *gid ) != 0,"set_user_group failed." );
180
 
                exit( 0 );
181
 
        }
182
 
        while( waitpid( pid, &status, 0 ) != pid );
183
 
        if( WIFEXITED( status ) ) {
184
 
                status = WEXITSTATUS( status );
185
 
                __abort(0, (status != 0),"User '%s' validated", user );
186
 
        }
187
 
        return 1;
188
 
}
189
 
 
190
 
static void controller( int sig ) {
191
 
        switch( sig ) {
192
 
        case SIGTERM:
193
 
        case SIGINT:
194
 
        case SIGHUP:
195
 
                __debug( "Forwarding signal %d to process %d", sig, child_pid );
196
 
                kill( child_pid, sig );
197
 
                signal( sig, controller );
198
 
                break;
199
 
        default:
200
 
                __debug( "Caught unknown signal %d", sig );
201
 
                break;
202
 
        }
203
 
}
204
 
 
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 )
209
 
                hand = NULL;
210
 
        return hand;
211
 
}
212
 
 
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.");
217
 
        fclose( pidfile );
218
 
        __abort(pid,(kill( pid, 0 )==0),"");
219
 
        return -1;
220
 
}
221
 
static int __write_pid( char *pidpath ) {
222
 
        FILE *pidfile;
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);
226
 
        return 0;
227
 
}
228
 
 
229
 
 
230
 
static int wait_child( euca_opts *args, int pid ) {
231
 
        time_t timer=0;
232
 
        int rc=0,status;
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 );
237
 
        }
238
 
        return 1;
239
 
}
240
 
 
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);
246
 
}
247
 
 
248
 
static int child( euca_opts *args, java_home_t *data, uid_t uid, gid_t gid ) {
249
 
        int ret = 0;
250
 
    jboolean r=0;
251
 
        __write_pid( GETARG(args,pidfile) );
252
 
        setpgrp( );
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;
269
 
        else ret = 0;
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" );
272
 
        return ret;
273
 
}
274
 
 
275
 
static FILE *loc_freopen( char *outfile, char *mode, FILE *stream ) {
276
 
        FILE *ftest;
277
 
        __abort(stream,(ftest = fopen( outfile, mode ))==NULL,"Unable to redirect to %s\n", outfile );
278
 
        fclose( ftest );
279
 
        return freopen( outfile, mode, stream );
280
 
}
281
 
 
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 );
289
 
        else {
290
 
                close( 2 );
291
 
                if( dup( 1 ) );//hack
292
 
        }
293
 
        if( strcmp( outfile, "&2" ) == 0 ) {
294
 
                close( 1 );
295
 
                if( dup( 2 ) );//hack
296
 
        }
297
 
}
298
 
 
299
 
int main( int argc, char *argv[ ] ) {
300
 
        euca_opts euca_args;
301
 
        euca_opts *args = &euca_args;
302
 
        java_home_t *data = NULL;
303
 
        int status = 0;
304
 
        pid_t pid = 0;
305
 
        uid_t uid = 0;
306
 
        gid_t gid = 0;
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);
316
 
        }
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);
320
 
        }
321
 
        __debug("TODO: loop through common locations for JVMs here.");
322
 
        if( data == NULL ) {
323
 
                __error( "Cannot locate Java Home" );
324
 
                return 1;
325
 
        }
326
 
        int x;
327
 
        if( debug == 1 ) {
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 ) );
335
 
                }
336
 
                __debug( "+-------------------------------------------------------" );
337
 
        }
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;
341
 
                p1 = strdup( libf );
342
 
                tmp = strrchr( p1, '/' );
343
 
                if( tmp != NULL ) tmp[ 0 ] = '\0';
344
 
                p2 = strdup( p1 );
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) );
349
 
                tmp = strdup( buf );
350
 
 
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" );
356
 
                return 1;
357
 
        }
358
 
        __debug( "Running w/ LD_LIBRARY_PATH=%s", getenv( "LD_LIBRARY_PATH" ) );
359
 
        if(args->fork_flag) {
360
 
                pid = fork( );
361
 
                __die(( pid == -1 ),"Cannot detach from parent process" );
362
 
                if( pid != 0 ) return wait_child( args, pid );
363
 
                setsid( );
364
 
        }
365
 
        set_output(GETARG(args,out), GETARG(args,err));
366
 
        while( ( pid = fork( ) ) != -1 ) {
367
 
                if( pid == 0 ) exit( child( args, data, uid, gid ) );
368
 
                child_pid = pid;
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" );
379
 
                                continue;
380
 
                        }
381
 
                        if( status == 0 ) {
382
 
                                __debug( "Service shut down" );
383
 
                                return 0;
384
 
                        }
385
 
                        __error( "Service exit with a return value of %d", status );
386
 
                        return 1;
387
 
                } else {
388
 
                        __error( "Service did not exit cleanly exit value %d", status );
389
 
                        return 1;
390
 
                }
391
 
        }
392
 
        __error( "Cannot decouple controller/child processes" );
393
 
        return 1;
394
 
}
395
 
 
396
 
 
397
 
int ld_library_path_set=0;
398
 
typedef void *dso_handle;
399
 
 
400
 
int dso_unlink(dso_handle libr) {
401
 
    if (dlclose(libr)==0) return 1;
402
 
    else return 0;
403
 
}
404
 
char *dso_error(void) {
405
 
    return(dlerror());
406
 
}
407
 
 
408
 
static void hello(JNIEnv *env, jobject source) {
409
 
    __error("uid=%d,euid=%d,gid=%d,egid=%d",getuid(),geteuid(),getgid(),getegid());
410
 
}
411
 
 
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 ) );
416
 
}
417
 
 
418
 
 
419
 
char *java_library(euca_opts *args, java_home_t *data) {
420
 
    char *libjvm_path=NULL;
421
 
    int x;
422
 
    if (data->jnum==0) {
423
 
        __error("Cannot find any VM in Java Home %s",data->path);
424
 
                exit(1);
425
 
    }
426
 
    if (args->jvm_name_given==0) {
427
 
        libjvm_path=data->jvms[0]->libjvm_path;
428
 
    } else {
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;
433
 
                break;
434
 
            }
435
 
        }
436
 
    }
437
 
    if (libjvm_path==NULL) {
438
 
        __error("Failed to locate usable JVM %s %s",GETARG(args,jvm_name),libjvm_path);
439
 
        exit(1);
440
 
    }
441
 
    __debug("Using libjvm.so in %s",libjvm_path);
442
 
    return libjvm_path;
443
 
}
444
 
 
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);
450
 
 
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.");
456
 
 
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");
474
 
}
475
 
 
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 );
484
 
    int wb = 0;
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 )  {
491
 
                            char jar[256];
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);
494
 
            }
495
 
    }
496
 
    closedir(lib_dir_p);
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)  {
500
 
                            char jar[256];
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);
503
 
            }
504
 
    }
505
 
    closedir(lib_dir_p);
506
 
    return jar_list;
507
 
}
508
 
 
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");
517
 
    JavaVMInitArgs arg;
518
 
    arg.ignoreUnrecognized=0;
519
 
#if defined(JNI_VERSION_1_4)
520
 
        arg.version=JNI_VERSION_1_4;
521
 
#else
522
 
        arg.version=JNI_VERSION_1_2;
523
 
#endif
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
528
 
    int x = -1, i = 0;
529
 
    opt=(JavaVMOption *)malloc(JVM_MAX_OPTS*sizeof(JavaVMOption));
530
 
    for(i=0;i<JVM_MAX_OPTS;i++) opt[i].extraInfo=NULL;
531
 
    i = -1;
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");
538
 
    } else {
539
 
        if(args->exhaustive_db_flag) {
540
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.db=TRACE");
541
 
        } else {
542
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.db=FATAL");
543
 
        }
544
 
        if(args->exhaustive_cc_flag) {
545
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.cc=TRACE");
546
 
        } else {
547
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.cc=FATAL");
548
 
        }
549
 
        if(args->exhaustive_user_flag) {
550
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.user=TRACE");
551
 
        } else {
552
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.user=FATAL");
553
 
        }
554
 
        if(args->exhaustive_external_flag) {
555
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.external=TRACE");
556
 
        } else {
557
 
                JVM_ARG(opt[++x],"-Deuca.log.exhaustive.external=FATAL");
558
 
        }
559
 
    }
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");
567
 
    }
568
 
    if(args->disable_storage_flag) {
569
 
        JVM_ARG(opt[++x],"-Deuca.disable.storage=true");
570
 
    }
571
 
    if(args->disable_cloud_flag) {
572
 
        JVM_ARG(opt[++x],"-Deuca.disable.eucalyptus=true");
573
 
    }
574
 
    if(args->disable_walrus_flag) {
575
 
        JVM_ARG(opt[++x],"-Deuca.disable.walrus=true");
576
 
    }
577
 
    if(args->remote_dns_flag) {
578
 
        JVM_ARG(opt[++x],"-Deuca.remote.dns=true");
579
 
    }
580
 
    if(args->remote_storage_flag) {
581
 
        JVM_ARG(opt[++x],"-Deuca.remote.storage=true");
582
 
    }
583
 
    if(args->remote_cloud_flag) {
584
 
        JVM_ARG(opt[++x],"-Deuca.remote.cloud=true");
585
 
    }
586
 
    if(args->remote_walrus_flag) {
587
 
        JVM_ARG(opt[++x],"-Deuca.remote.walrus=true");
588
 
    }
589
 
    if(args->disable_iscsi_flag) {
590
 
                JVM_ARG(opt[++x],"-Deuca.disable.iscsi=true");
591
 
    }
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"));
595
 
    }
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));
600
 
    }
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));
606
 
    }
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]);
609
 
 
610
 
    opt[++x].optionString=java_class_path;
611
 
    opt[x].extraInfo=NULL;
612
 
    opt[++x].optionString="abort";
613
 
    opt[x].extraInfo=java_fail;
614
 
 
615
 
    arg.nOptions = x+1;
616
 
    arg.options=opt;
617
 
    if (debug) {
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("+-------------------------------------------------------");
624
 
    }
625
 
    __debug("Starting JVM.");
626
 
    jint ret = 0;
627
 
    while((ret=(*hotspot_main)(&jvm, &env, &arg)==123));
628
 
    __die(ret<0,"Failed to create JVM");
629
 
    java_load_bootstrapper();
630
 
    return 1;
631
 
}
632
 
 
633
 
int JVM_destroy(int code) {
634
 
    jclass system;
635
 
    jmethodID method;
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.");
642
 
    return 1;
643
 
}
644
 
 
645
 
void java_sleep(int wait) {
646
 
    jclass clsThread;
647
 
    jmethodID method;
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);
651
 
}