/* #define SERVER_DEBUG 1 */ int main(int argc, char *argv[]) { int status; rsComm_t rsComm; char *tmpStr; ProcessType = AGENT_PT; #ifdef RUN_SERVER_AS_ROOT #ifndef windows_platform if (initServiceUser() < 0) { exit (1); } #endif #endif #ifdef windows_platform iRODSNtAgentInit(argc, argv); #endif #ifndef windows_platform signal(SIGINT, signalExit); signal(SIGHUP, signalExit); signal(SIGTERM, signalExit); /* set to SIG_DFL as recommended by andy.salnikov so that system() * call returns real values instead of 1 */ signal(SIGCHLD, SIG_DFL); signal(SIGUSR1, signalExit); signal(SIGPIPE, rsPipSigalHandler); #endif #ifndef windows_platform #ifdef SERVER_DEBUG if (isPath ("/tmp/rodsdebug")) sleep (20); #endif #endif #ifdef SYS_TIMING rodsLogLevel(LOG_NOTICE); printSysTiming ("irodsAgent", "exec", 1); #endif memset (&rsComm, 0, sizeof (rsComm)); status = initRsCommWithStartupPack (&rsComm, NULL); if (status < 0) { sendVersion (rsComm.sock, status, 0, NULL, 0); cleanupAndExit (status); } /* Handle option to log sql commands */ tmpStr = getenv (SP_LOG_SQL); if (tmpStr != NULL) { #ifdef IRODS_SYSLOG int j = atoi(tmpStr); rodsLogSqlReq(j); #else rodsLogSqlReq(1); #endif } /* Set the logging level */ tmpStr = getenv (SP_LOG_LEVEL); if (tmpStr != NULL) { int i; i = atoi(tmpStr); rodsLogLevel(i); } else { rodsLogLevel(LOG_NOTICE); /* default */ } #ifdef IRODS_SYSLOG /* Open a connection to syslog */ #ifdef SYSLOG_FACILITY_CODE openlog("rodsAgent",LOG_ODELAY|LOG_PID,SYSLOG_FACILITY_CODE); #else openlog("rodsAgent",LOG_ODELAY|LOG_PID,LOG_DAEMON); #endif #endif status = getRodsEnv (&rsComm.myEnv); if (status < 0) { sendVersion (rsComm.sock, SYS_AGENT_INIT_ERR, 0, NULL, 0); cleanupAndExit (status); } #if RODS_CAT if (strstr(rsComm.myEnv.rodsDebug, "CAT") != NULL) { chlDebug(rsComm.myEnv.rodsDebug); } #endif #ifdef RULE_ENGINE_N status = initAgent (RULE_ENGINE_TRY_CACHE, &rsComm); #else status = initAgent (&rsComm); #endif #ifdef SYS_TIMING printSysTiming ("irodsAgent", "initAgent", 0); #endif if (status < 0) { sendVersion (rsComm.sock, SYS_AGENT_INIT_ERR, 0, NULL, 0); cleanupAndExit (status); } /* move configConnectControl behind initAgent for now. need zoneName if * the user does not specify one in the input */ initConnectControl (); if (rsComm.clientUser.userName[0] != '\0') { status = chkAllowedUser (rsComm.clientUser.userName, rsComm.clientUser.rodsZone); if (status < 0) { sendVersion (rsComm.sock, status, 0, NULL, 0); cleanupAndExit (status); } } /* send the server version and atatus as part of the protocol. Put * rsComm.reconnPort as the status */ status = sendVersion (rsComm.sock, status, rsComm.reconnPort, rsComm.reconnAddr, rsComm.cookie); if (status < 0) { sendVersion (rsComm.sock, SYS_AGENT_INIT_ERR, 0, NULL, 0); cleanupAndExit (status); } #ifdef SYS_TIMING printSysTiming ("irodsAgent", "sendVersion", 0); #endif logAgentProc (&rsComm); status = agentMain (&rsComm); cleanupAndExit (status); return (status); }
int readAndProcClientMsg( rsComm_t * rsComm, int flags ) { int status = 0; msgHeader_t myHeader; bytesBuf_t inputStructBBuf, bsBBuf, errorBBuf; bzero( &inputStructBBuf, sizeof( inputStructBBuf ) ); bzero( &bsBBuf, sizeof( bsBBuf ) ); bzero( &errorBBuf, sizeof( errorBBuf ) ); svrChkReconnAtReadStart( rsComm ); /* everything else are set in readMsgBody */ /* read the header */ // =-=-=-=-=-=-=- // create a network object irods::network_object_ptr net_obj; irods::error ret = irods::network_factory( rsComm, net_obj ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } if ( ( flags & READ_HEADER_TIMEOUT ) != 0 ) { int retryCnt = 0; struct timeval tv; tv.tv_sec = READ_HEADER_TIMEOUT_IN_SEC; tv.tv_usec = 0; while ( 1 ) { ret = readMsgHeader( net_obj, &myHeader, &tv ); if ( !ret.ok() ) { if ( isL1descInuse() && retryCnt < MAX_READ_HEADER_RETRY ) { rodsLogError( LOG_ERROR, status, "readAndProcClientMsg:readMsgHeader error. status = %d", ret.code() ); retryCnt++; continue; } if ( ret.code() == USER_SOCK_CONNECT_TIMEDOUT ) { rodsLog( LOG_ERROR, "readAndProcClientMsg: readMsgHeader by pid %d timedout", getpid() ); return ret.code(); } } break; } // while 1 } else { ret = readMsgHeader( net_obj, &myHeader, NULL ); } if ( !ret.ok() ) { irods::log( PASS( ret ) ); /* attempt to accept reconnect. ENOENT result from * user cntl-C */ if ( rsComm->reconnSock > 0 ) { int savedStatus = ret.code(); /* try again. the socket might have changed */ boost::unique_lock< boost::mutex > boost_lock( *rsComm->thread_ctx->lock ); rodsLog( LOG_DEBUG, "readAndProcClientMsg: svrSwitchConnect. cliState = %d,agState=%d", rsComm->clientState, rsComm->agentState ); svrSwitchConnect( rsComm ); boost_lock.unlock(); ret = readMsgHeader( net_obj, &myHeader, NULL ); if ( !ret.ok() ) { svrChkReconnAtReadEnd( rsComm ); return savedStatus; } } else { svrChkReconnAtReadEnd( rsComm ); return ret.code(); } } // if !ret.ok() #ifdef SYS_TIMING if ( strcmp( myHeader.type, RODS_API_REQ_T ) == 0 ) { /* Get the total time of AUTH_REQUEST_AN and AUTH_RESPONSE_AN */ if ( myHeader.intInfo != AUTH_RESPONSE_AN ) { initSysTiming( "irodsAgent", "recv request", 0 ); } } #endif ret = readMsgBody( net_obj, &myHeader, &inputStructBBuf, &bsBBuf, &errorBBuf, rsComm->irodsProt, NULL ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); svrChkReconnAtReadEnd( rsComm ); return ret.code(); } svrChkReconnAtReadEnd( rsComm ); /* handler switch by msg type */ if ( strcmp( myHeader.type, RODS_API_REQ_T ) == 0 ) { status = rsApiHandler( rsComm, myHeader.intInfo, &inputStructBBuf, &bsBBuf ); #ifdef SYS_TIMING char tmpStr[NAME_LEN]; snprintf( tmpStr, NAME_LEN, "handle API %d", myHeader.intInfo ); printSysTiming( "irodsAgent", tmpStr, 0 ); #endif clearBBuf( &inputStructBBuf ); clearBBuf( &bsBBuf ); clearBBuf( &errorBBuf ); if ( ( flags & RET_API_STATUS ) != 0 ) { return status; } else { return 0; } } else if ( strcmp( myHeader.type, RODS_DISCONNECT_T ) == 0 ) { rodsLog( LOG_NOTICE, "readAndProcClientMsg: received disconnect msg from client" ); return DISCONN_STATUS; } else if ( strcmp( myHeader.type, RODS_RECONNECT_T ) == 0 ) { rodsLog( LOG_NOTICE, "readAndProcClientMsg: received reconnect msg from client" ); /* call itself again. be careful */ status = readAndProcClientMsg( rsComm, flags ); return status; } else { rodsLog( LOG_NOTICE, "agentMain: msg type %s not support by server", myHeader.type ); return USER_MSG_TYPE_NO_SUPPORT; } }