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