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 <unistd.h>
00034 #include <sys/types.h>
00035 #include <signal.h>
00036 #include <sys/wait.h>
00037 #include <errno.h>
00038
00039 #include <sstream>
00040 #include <iostream>
00041
00042 using std::ostringstream ;
00043 using std::cout ;
00044 using std::endl ;
00045 using std::cerr ;
00046
00047 #include "BESServerHandler.h"
00048 #include "Connection.h"
00049 #include "Socket.h"
00050 #include "BESCmdInterface.h"
00051 #include "TheBESKeys.h"
00052 #include "BESException.h"
00053 #include "ServerExitConditions.h"
00054 #include "BESStatusReturn.h"
00055 #include "BESUtil.h"
00056
00057 BESServerHandler::BESServerHandler()
00058 {
00059 bool found = false ;
00060 _method = TheBESKeys::TheKeys()->get_key( "BES.ProcessManagerMethod", found ) ;
00061 if( _method != "multiple" && _method != "single" )
00062 {
00063 cerr << "Unable to determine method to handle clients, "
00064 << "single or multiple as defined by BES.ProcessManagerMethod"
00065 << endl ;
00066 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00067 }
00068 }
00069
00070
00071
00072
00073
00074 void
00075 BESServerHandler::handle( Connection *c )
00076 {
00077 if(_method=="single")
00078 {
00079 execute( c ) ;
00080 }
00081 else
00082 {
00083 int main_process = getpid() ;
00084 pid_t pid ;
00085 if( ( pid = fork() ) < 0 )
00086 {
00087 string error( "fork error" ) ;
00088 const char* error_info = strerror( errno ) ;
00089 if( error_info )
00090 error += " " + (string)error_info ;
00091 throw BESException( error, __FILE__, __LINE__ ) ;
00092 }
00093 else if( pid == 0 )
00094 {
00095 pid_t pid1 ;
00096
00097 if( ( pid1 = fork() ) < 0 )
00098 {
00099
00100
00101 kill( main_process, 9 ) ;
00102 perror( "fork error" ) ;
00103 exit( SERVER_EXIT_CHILD_SUBPROCESS_ABNORMAL_TERMINATION ) ;
00104 }
00105 else if( pid1 == 0 )
00106 {
00107 execute( c ) ;
00108 }
00109 sleep( 1 ) ;
00110 c->closeConnection() ;
00111 exit( SERVER_EXIT_CHILD_SUBPROCESS_NORMAL_TERMINATION ) ;
00112 }
00113 if( waitpid( pid, NULL, 0 ) != pid )
00114 {
00115 string error( "waitpid error" ) ;
00116 const char *error_info = strerror( errno ) ;
00117 if( error_info )
00118 error += " " + (string)error_info ;
00119 throw BESException( error, __FILE__, __LINE__ ) ;
00120 }
00121 c->closeConnection() ;
00122 }
00123 }
00124
00125 void
00126 BESServerHandler::execute( Connection *c )
00127 {
00128 for(;;)
00129 {
00130 ostringstream ss ;
00131
00132 bool isDone = c->receive( &ss ) ;
00133
00134 if( isDone )
00135 {
00136 c->closeConnection() ;
00137 exit( CHILD_SUBPROCESS_READY ) ;
00138 }
00139
00140 int holder = dup( STDOUT_FILENO ) ;
00141 dup2( c->getSocket()->getSocketDescriptor(), STDOUT_FILENO ) ;
00142
00143 BESCmdInterface cmd( BESUtil::www2id( ss.str(), "%", "%20" ) ) ;
00144 int status = cmd.execute_request() ;
00145
00146 fflush( stdout ) ;
00147 dup2( holder, STDOUT_FILENO ) ;
00148 close( holder ) ;
00149
00150 if( status == BES_EXECUTED_OK )
00151 {
00152 c->send( "" ) ;
00153 }
00154 else
00155 {
00156 switch (status)
00157 {
00158 case BES_TERMINATE_IMMEDIATE:
00159 {
00160 cout << "BES server " << getpid()
00161 << ": Status not OK, dispatcher returned value "
00162 << status << endl ;
00163
00164
00165 c->send( "" ) ;
00166 c->sendExit() ;
00167 c->closeConnection() ;
00168 exit( CHILD_SUBPROCESS_READY ) ;
00169 }
00170 break;
00171 case BES_DATA_HANDLER_FAILURE:
00172 {
00173 cout << "BES server " << getpid()
00174 << ": Status not OK, dispatcher returned value "
00175 << status << endl ;
00176
00177
00178 c->send( "" ) ;
00179 c->sendExit() ;
00180 c->closeConnection() ;
00181 exit( CHILD_SUBPROCESS_READY ) ;
00182 }
00183 break;
00184 case BES_REQUEST_INCORRECT:
00185 case BES_MEMORY_EXCEPTION:
00186 case BES_CONTAINER_PERSISTENCE_ERROR:
00187 case BES_INITIALIZATION_FILE_PROBLEM:
00188 case BES_LOG_FILE_PROBLEM:
00189 case BES_AGGREGATION_EXCEPTION:
00190 case BES_FAILED_TO_EXECUTE_COMMIT_COMMAND:
00191 default:
00192 {
00193 c->send( "" ) ;
00194 }
00195 break;
00196 }
00197 }
00198 }
00199 }
00200
00207 void
00208 BESServerHandler::dump( ostream &strm ) const
00209 {
00210 strm << BESIndent::LMarg << "BESServerHandler::dump - ("
00211 << (void *)this << ")" << endl ;
00212 BESIndent::Indent() ;
00213 strm << BESIndent::LMarg << "server method: " << _method << endl ;
00214 BESIndent::UnIndent() ;
00215 }
00216