00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include <string.h>
00036 #include <sys/wait.h>
00037 #include <stdio.h>
00038 #include <errno.h>
00039
00040 #include <fstream>
00041 #include <iostream>
00042 #include <string>
00043
00044 using std::ifstream ;
00045 using std::ofstream ;
00046 using std::cout ;
00047 using std::endl ;
00048 using std::cerr ;
00049 using std::flush;
00050 using std::string ;
00051
00052 #include "config.h"
00053 #include "ServerExitConditions.h"
00054 #include "BESServerUtils.h"
00055
00056 #define BES_SERVER_ROOT "BES_SERVER_ROOT"
00057 #define BES_SERVER "/beslistener"
00058 #define BES_SERVER_PID "bes.pid"
00059
00060 int daemon_init() ;
00061 int mount_server( char ** ) ;
00062 int pr_exit( int status ) ;
00063 void store_listener_id( int pid ) ;
00064 bool load_names() ;
00065
00066 string NameProgram ;
00067
00068
00069 string server_name ;
00070 string file_for_listener ;
00071
00072 char **arguments = 0 ;
00073
00074 int
00075 main(int argc, char *argv[])
00076 {
00077 NameProgram = argv[0] ;
00078
00079
00080 if( !load_names() )
00081 return 1 ;
00082
00083 arguments = new char *[argc+1] ;
00084
00085
00086 char temp_name[1024] ;
00087 strcpy( temp_name, server_name.c_str() ) ;
00088 arguments[0] = temp_name ;
00089
00090
00091
00092 for( int i = 1; i < argc; i++ )
00093 {
00094 arguments[i] = argv[i] ;
00095 }
00096 arguments[argc] = NULL ;
00097
00098
00099
00100 int c = 0 ;
00101 while( ( c = getopt( argc, argv, "hvsd:c:p:u:" ) ) != EOF )
00102 {
00103 switch( c )
00104 {
00105 case 'v':
00106 BESServerUtils::show_version( NameProgram ) ;
00107 break ;
00108 case '?':
00109 case 'h':
00110 BESServerUtils::show_usage( NameProgram ) ;
00111 break ;
00112 default:
00113 break ;
00114 }
00115 }
00116
00117 if( !access( file_for_listener.c_str(), F_OK ) )
00118 {
00119 ifstream temp( file_for_listener.c_str() ) ;
00120 cout << NameProgram
00121 << ": there seems to be a BES daemon already running at " ;
00122 char buf[500] ;
00123 temp.getline( buf, 500 ) ;
00124 cout << buf << endl ;
00125 temp.close() ;
00126 return 1 ;
00127 }
00128
00129 daemon_init() ;
00130
00131 int restart = mount_server( arguments ) ;
00132 if( restart == 2 )
00133 {
00134 cout << NameProgram
00135 << ": server can not mount at first try (core dump). "
00136 << "Please correct problems on the process manager "
00137 << server_name << endl ;
00138 return 0 ;
00139 }
00140 while( restart )
00141 {
00142 sleep( 5 ) ;
00143 restart = mount_server( arguments ) ;
00144 }
00145 delete [] arguments; arguments = 0 ;
00146
00147 if( !access( file_for_listener.c_str(), F_OK ) )
00148 {
00149 remove( file_for_listener.c_str() ) ;
00150 }
00151
00152 return 0 ;
00153 }
00154
00155 int
00156 daemon_init()
00157 {
00158 pid_t pid ;
00159 if( ( pid = fork() ) < 0 )
00160 return -1 ;
00161 else if( pid != 0 )
00162 exit( 0 ) ;
00163 setsid() ;
00164 return 0 ;
00165 }
00166
00167 int
00168 mount_server(char* *arguments)
00169 {
00170 const char *perror_string = 0 ;
00171 pid_t pid ;
00172 int status ;
00173 if( ( pid = fork() ) < 0 )
00174 {
00175 cerr << NameProgram << ": fork error " ;
00176 perror_string = strerror( errno ) ;
00177 if( perror_string )
00178 cerr << perror_string ;
00179 cerr << endl ;
00180 return 1 ;
00181 }
00182 else if( pid == 0 )
00183 {
00184 execvp( arguments[0], arguments ) ;
00185 cerr << NameProgram
00186 << ": mounting listener, subprocess failed: " ;
00187 perror_string = strerror( errno ) ;
00188 if( perror_string )
00189 cerr << perror_string ;
00190 cerr << endl ;
00191 exit( 1 ) ;
00192 }
00193 store_listener_id( pid ) ;
00194 if( ( pid = waitpid( pid, &status, 0 ) ) < 0 )
00195 {
00196 cerr << NameProgram << ": waitpid error " ;
00197 perror_string = strerror( errno ) ;
00198 if( perror_string )
00199 cerr << perror_string ;
00200 cerr << endl ;
00201 return 1 ;
00202 }
00203 int child_status = pr_exit( status ) ;
00204 return child_status ;
00205 }
00206
00207 int
00208 pr_exit(int status)
00209 {
00210 if( WIFEXITED( status ) )
00211 {
00212 int status_to_be_returned = SERVER_EXIT_UNDEFINED_STATE ;
00213 switch( WEXITSTATUS( status ) )
00214 {
00215 case SERVER_EXIT_NORMAL_SHUTDOWN:
00216 status_to_be_returned = 0 ;
00217 break ;
00218 case SERVER_EXIT_FATAL_CAN_NOT_START:
00219 {
00220 cerr << NameProgram
00221 << ": server can not start, exited with status "
00222 << WEXITSTATUS( status ) << endl ;
00223 cerr << "Please check all error messages "
00224 << "and adjust server installation" << endl ;
00225 status_to_be_returned = 0 ;
00226 }
00227 break;
00228 case SERVER_EXIT_ABNORMAL_TERMINATION:
00229 {
00230 cerr << NameProgram
00231 << ": abnormal server termination, exited with status "
00232 << WEXITSTATUS( status ) << endl ;
00233 status_to_be_returned = 1 ;
00234 }
00235 break;
00236 case SERVER_EXIT_RESTART:
00237 {
00238 cout << NameProgram
00239 << ": server has been requested to re-start." << endl ;
00240 status_to_be_returned = 1 ;
00241 }
00242 break;
00243 default:
00244 status_to_be_returned = 1 ;
00245 break;
00246 }
00247
00248 return status_to_be_returned;
00249 }
00250 else if( WIFSIGNALED( status ) )
00251 {
00252 cerr << NameProgram
00253 << ": abnormal server termination, signaled with signal number "
00254 << WTERMSIG( status ) << endl ;
00255 #ifdef WCOREDUMP
00256 if( WCOREDUMP( status ) )
00257 {
00258 cerr << NameProgram << ": server dumped core." << endl ;
00259 return 2 ;
00260 }
00261 #endif
00262 return 1;
00263 }
00264 else if( WIFSTOPPED( status ) )
00265 {
00266 cerr << NameProgram
00267 << ": abnormal server termination, stopped with signal number "
00268 << WSTOPSIG( status ) << endl ;
00269 return 1 ;
00270 }
00271 return 0 ;
00272 }
00273
00274 void
00275 store_listener_id( int pid )
00276 {
00277 const char *perror_string = 0 ;
00278 ofstream f( file_for_listener.c_str() ) ;
00279 if( !f )
00280 {
00281 cerr << NameProgram << ": unable to create pid file "
00282 << file_for_listener << ": " ;
00283 perror_string = strerror( errno ) ;
00284 if( perror_string )
00285 cerr << perror_string ;
00286 cerr << " ... Continuing" << endl ;
00287 cerr << endl ;
00288 }
00289 else
00290 {
00291 f << "PID: " << pid << " UID: " << getuid() << endl ;
00292 f.close() ;
00293 }
00294 }
00295
00296 bool
00297 load_names()
00298 {
00299 char *xdap_root = 0 ;
00300 string bindir = "/bin";
00301 xdap_root = getenv( BES_SERVER_ROOT ) ;
00302 if( xdap_root )
00303 {
00304 server_name = xdap_root ;
00305 server_name += bindir ;
00306 file_for_listener = xdap_root ;
00307 }
00308 else
00309 {
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 server_name = BES_BIN_DIR ;
00323 file_for_listener = BES_STATE_DIR ;
00324 }
00325 if( server_name == "" )
00326 {
00327 server_name = "." ;
00328 server_name += bindir ;
00329 file_for_listener = "." ;
00330 }
00331
00332 server_name += BES_SERVER ;
00333 file_for_listener += "/run/" ;
00334 file_for_listener += BES_SERVER_PID ;
00335
00336 if( access( server_name.c_str(), F_OK ) != 0 )
00337 {
00338 cerr << NameProgram
00339 << ": can not start." << server_name << endl
00340 << "Please set environment variable "
00341 << BES_SERVER_ROOT << " to the location of your listener "
00342 << endl ;
00343 return false ;
00344 }
00345 return true ;
00346 }
00347