00001
00002
00003
00004 #include "rodsServer.h"
00005 #include "resource.h"
00006 #include "miscServerFunct.h"
00007
00008 #include <syslog.h>
00009
00010 #ifndef SINGLE_SVR_THR
00011 #include <pthread.h>
00012 #endif
00013 #ifndef windows_platform
00014 #include <sys/socket.h>
00015 #include <netinet/in.h>
00016 #include <arpa/inet.h>
00017 #endif
00018
00019 #ifdef windows_platform
00020 #include "irodsntutil.h"
00021 #endif
00022
00023
00024
00025 #include "eirods_client_server_negotiation.h"
00026 #include "eirods_network_factory.h"
00027
00028
00029
00030 uint ServerBootTime;
00031 int SvrSock;
00032
00033 agentProc_t *ConnectedAgentHead = NULL;
00034 agentProc_t *ConnReqHead = NULL;
00035 agentProc_t *SpawnReqHead = NULL;
00036 agentProc_t *BadReqHead = NULL;
00037
00038 #ifndef SINGLE_SVR_THR
00039 #include <boost/thread/thread.hpp>
00040 #include <boost/thread/mutex.hpp>
00041 #include <boost/thread/condition.hpp>
00042 boost::mutex ConnectedAgentMutex;
00043 boost::mutex BadReqMutex;
00044 boost::thread* ReadWorkerThread[NUM_READ_WORKER_THR];
00045 boost::thread* SpawnManagerThread;
00046 boost::thread* PurgeLockFileThread;
00047 #endif
00048
00049 boost::mutex ReadReqCondMutex;
00050 boost::mutex SpawnReqCondMutex;
00051 boost::condition_variable ReadReqCond;
00052 boost::condition_variable SpawnReqCond;
00053
00054 #ifndef windows_platform
00055 int
00056 main(int argc, char **argv)
00057 #else
00058 int irodsWinMain(int argc, char **argv)
00059 #endif
00060 {
00061 int c;
00062 int uFlag = 0;
00063 char tmpStr1[100], tmpStr2[100];
00064 char *logDir = NULL;
00065 char *tmpStr;
00066
00067
00068 ProcessType = SERVER_PT;
00069
00070 #ifdef RUN_SERVER_AS_ROOT
00071 #ifndef windows_platform
00072 if (initServiceUser() < 0) {
00073 exit (1);
00074 }
00075 #endif
00076 #endif
00077
00078 tmpStr = getenv (SP_LOG_LEVEL);
00079 if (tmpStr != NULL) {
00080 int i;
00081 i = atoi(tmpStr);
00082 rodsLogLevel(i);
00083 } else {
00084 rodsLogLevel(LOG_NOTICE);
00085 }
00086
00087 #ifdef IRODS_SYSLOG
00088
00089 openlog("rodsServer",LOG_ODELAY|LOG_PID,LOG_DAEMON);
00090 #endif
00091
00092 ServerBootTime = time (0);
00093 while ((c = getopt(argc, argv,"uvVqsh")) != EOF) {
00094 switch (c) {
00095 case 'u':
00096 uFlag = 1;
00097 break;
00098 case 'D':
00099 logDir = strdup (optarg);
00100 break;
00101 case 'v':
00102 snprintf(tmpStr1,100,"%s=%d",SP_LOG_LEVEL, LOG_NOTICE);
00103 putenv(tmpStr1);
00104 rodsLogLevel(LOG_NOTICE);
00105 break;
00106 case 'V':
00107 snprintf(tmpStr1,100,"%s=%d",SP_LOG_LEVEL, LOG_DEBUG1);
00108 putenv(tmpStr1);
00109 rodsLogLevel(LOG_DEBUG1);
00110 break;
00111 case 'q':
00112 snprintf(tmpStr1,100,"%s=%d",SP_LOG_LEVEL, LOG_ERROR);
00113 putenv(tmpStr1);
00114 rodsLogLevel(LOG_ERROR);
00115 break;
00116 case 's':
00117 snprintf(tmpStr2,100,"%s=%d",SP_LOG_SQL, 1);
00118 putenv(tmpStr2);
00119 break;
00120 case 'h':
00121 usage (argv[0]);
00122 exit (0);
00123 default:
00124 usage (argv[0]);
00125 exit (1);
00126 }
00127 }
00128
00129 if (uFlag == 0) {
00130 if (serverize (logDir) < 0) {
00131 exit (1);
00132 }
00133 }
00134
00135
00136 #ifndef _WIN32
00137 signal(SIGTTIN, SIG_IGN);
00138 signal(SIGTTOU, SIG_IGN);
00139 signal(SIGCHLD, SIG_DFL);
00140 signal(SIGPIPE, SIG_IGN);
00141 #ifdef osx_platform
00142 #if 0
00143 signal(SIGINT, (void *) serverExit);
00144 signal(SIGHUP, (void *)serverExit);
00145 signal(SIGTERM, (void *)serverExit);
00146 #else
00147 signal(SIGINT, (sig_t) serverExit);
00148 signal(SIGHUP, (sig_t)serverExit);
00149 signal(SIGTERM, (sig_t) serverExit);
00150 #endif
00151 #else
00152 signal(SIGINT, serverExit);
00153 signal(SIGHUP, serverExit);
00154 signal(SIGTERM, serverExit);
00155 #endif
00156 #endif
00157
00158
00159 #ifndef _WIN32
00160
00161 if (getenv ("ServerTimeOut") != NULL) {
00162 int serverTimeOut;
00163 serverTimeOut = atoi (getenv ("ServerTimeOut"));
00164 if (serverTimeOut < MIN_AGENT_TIMEOUT_TIME) {
00165 rodsLog (LOG_NOTICE,
00166 "ServerTimeOut %d is less than min of %d",
00167 serverTimeOut, MIN_AGENT_TIMEOUT_TIME);
00168 serverTimeOut = MIN_AGENT_TIMEOUT_TIME;
00169 }
00170 rodsLog (LOG_NOTICE,
00171 "ServerTimeOut has been set to %d seconds",
00172 serverTimeOut);
00173 }
00174 #endif
00175
00176 serverMain (logDir);
00177 exit (0);
00178 }
00179
00180 int
00181 serverize (char *logDir)
00182 {
00183 char *logFile = NULL;
00184
00185 #ifdef windows_platform
00186 if(iRODSNtServerRunningConsoleMode())
00187 return;
00188 #endif
00189
00190 getLogfileName (&logFile, logDir, RODS_LOGFILE);
00191
00192 #ifndef windows_platform
00193 #ifdef IRODS_SYSLOG
00194 LogFd = 0;
00195 #else
00196 LogFd = open (logFile, O_CREAT|O_WRONLY|O_APPEND, 0644);
00197 #endif
00198 #else
00199 LogFd = iRODSNt_open(logFile, O_CREAT|O_APPEND|O_WRONLY, 1);
00200 #endif
00201
00202 if (LogFd < 0) {
00203 rodsLog (LOG_NOTICE, "logFileOpen: Unable to open %s. errno = %d",
00204 logFile, errno);
00205 return (-1);
00206 }
00207
00208 #ifndef windows_platform
00209 if (fork()) {
00210 exit (0);
00211 } else {
00212 if (setsid() < 0) {
00213 rodsLog (LOG_NOTICE,
00214 "serverize: setsid failed, errno = %d\n", errno);
00215 exit(1);
00216 }
00217
00218
00219
00220
00221
00222 #ifndef IRODS_SYSLOG
00223 (void) dup2 (LogFd, 0);
00224 (void) dup2 (LogFd, 1);
00225 (void) dup2 (LogFd, 2);
00226 close (LogFd);
00227 LogFd = 2;
00228 #endif
00229 }
00230 #else
00231 _close(LogFd);
00232 #endif
00233
00234 #ifdef IRODS_SYSLOG
00235 return (0);
00236 #else
00237 return (LogFd);
00238 #endif
00239 }
00240
00241 int
00242 serverMain (char *logDir)
00243 {
00244 int status;
00245 rsComm_t svrComm;
00246 fd_set sockMask;
00247 int numSock;
00248 int newSock;
00249 int loopCnt = 0;
00250 int acceptErrCnt = 0;
00251 #ifdef SYS_TIMING
00252 int connCnt = 0;
00253 #endif
00254
00255
00256 status = initServerMain (&svrComm);
00257 if (status < 0) {
00258 rodsLog (LOG_ERROR, "serverMain: initServerMain error. status = %d",
00259 status);
00260 exit (1);
00261 }
00262 #ifndef SINGLE_SVR_THR
00263 startProcConnReqThreads ();
00264 #if RODS_CAT // JMC - backport 4612
00265 PurgeLockFileThread = new boost::thread( purgeLockFileWorkerTask );
00266 #endif
00267 #endif
00268
00269 FD_ZERO(&sockMask);
00270
00271 SvrSock = svrComm.sock;
00272 while (1) {
00273 FD_SET(svrComm.sock, &sockMask);
00274 while ((numSock = select (svrComm.sock + 1, &sockMask,
00275 (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) NULL)) < 0) {
00276
00277 if (errno == EINTR) {
00278 rodsLog (LOG_NOTICE, "serverMain: select() interrupted");
00279 FD_SET(svrComm.sock, &sockMask);
00280 continue;
00281 } else {
00282 rodsLog (LOG_NOTICE, "serverMain: select() error, errno = %d",
00283 errno);
00284 return (-1);
00285 }
00286 }
00287
00288 procChildren (&ConnectedAgentHead);
00289 #ifdef SYS_TIMING
00290 initSysTiming ("irodsServer", "recv connection", 0);
00291 #endif
00292
00293 newSock = rsAcceptConn (&svrComm);
00294
00295 if (newSock < 0) {
00296 acceptErrCnt ++;
00297 if (acceptErrCnt > MAX_ACCEPT_ERR_CNT) {
00298 rodsLog (LOG_ERROR,
00299 "serverMain: Too many socket accept error. Exiting");
00300 break;
00301 } else {
00302 rodsLog (LOG_NOTICE,
00303 "serverMain: acceptConn () error, errno = %d", errno);
00304 continue;
00305 }
00306 } else {
00307 acceptErrCnt = 0;
00308 }
00309
00310 status = chkAgentProcCnt ();
00311 if (status < 0) {
00312 rodsLog (LOG_NOTICE,
00313 "serverMain: chkAgentProcCnt failed status = %d", status);
00314
00315
00316
00317
00318
00319 eirods::network_object_ptr net_obj;
00320 eirods::error ret = eirods::network_factory( &svrComm, net_obj );
00321 if( !ret.ok() ) {
00322 eirods::log( PASS( ret ) );
00323 } else {
00324 ret = sendVersion (net_obj, status, 0, NULL, 0 );
00325 if( !ret.ok() ) {
00326 eirods::log( PASS( ret ) );
00327 }
00328 }
00329 status = mySockClose (newSock);
00330 printf ("close status = %d\n", status);
00331 continue;
00332 }
00333
00334 addConnReqToQue (&svrComm, newSock);
00335
00336 #ifdef SYS_TIMING
00337 connCnt ++;
00338 rodsLog (LOG_NOTICE, "irodsServer: agent proc count = %d, connCnt = %d",
00339 getAgentProcCnt (ConnectedAgentHead), connCnt);
00340 #endif
00341
00342 #ifdef SINGLE_SVR_THR
00343 procSingleConnReq (ConnReqHead);
00344 ConnReqHead = NULL;
00345 #endif
00346
00347 #ifndef windows_platform
00348 loopCnt++;
00349 if (loopCnt >= LOGFILE_CHK_CNT) {
00350 chkLogfileName (logDir, RODS_LOGFILE);
00351 loopCnt = 0;
00352 }
00353 #endif
00354 }
00355
00356
00357 return(0);
00358 }
00359
00360 void
00361 #if defined(linux_platform) || defined(aix_platform) || defined(solaris_platform) || defined(linux_platform) || defined(osx_platform)
00362 serverExit (int sig)
00363 #else
00364 serverExit ()
00365 #endif
00366 {
00367 #ifndef windows_platform
00368 rodsLog (LOG_NOTICE, "rodsServer caught signal %d, exiting", sig);
00369 #else
00370 rodsLog (LOG_NOTICE, "rodsServer is exiting.");
00371 #endif
00372 recordServerProcess(NULL);
00373 exit (1);
00374 }
00375
00376 void
00377 usage (char *prog)
00378 {
00379 printf ("Usage: %s [-uvVqs]\n", prog);
00380 printf (" -u user command level, remain attached to the tty\n");
00381 printf (" -v verbose (LOG_NOTICE)\n");
00382 printf (" -V very verbose (LOG_DEBUG1)\n");
00383 printf (" -q quiet (LOG_ERROR)\n");
00384 printf (" -s log SQL commands\n");
00385
00386 }
00387
00388 int
00389 procChildren (agentProc_t **agentProcHead)
00390 {
00391 int childPid;
00392 agentProc_t *tmpAgentProc;
00393 int status;
00394
00395
00396 #ifndef _WIN32
00397 while ((childPid = waitpid (-1, &status, WNOHANG | WUNTRACED)) > 0) {
00398 tmpAgentProc = getAgentProcByPid (childPid, agentProcHead);
00399 if (tmpAgentProc != NULL) {
00400 rodsLog (LOG_NOTICE, "Agent process %d exited with status %d",
00401 childPid, status);
00402 free (tmpAgentProc);
00403 } else {
00404 rodsLog (LOG_NOTICE,
00405 "Agent process %d exited with status %d but not in queue",
00406 childPid, status);
00407 }
00408 rmProcLog (childPid);
00409 }
00410 #endif
00411
00412 return (0);
00413 }
00414
00415
00416 agentProc_t *
00417 getAgentProcByPid (int childPid, agentProc_t **agentProcHead)
00418 {
00419 agentProc_t *tmpAgentProc, *prevAgentProc;
00420 prevAgentProc = NULL;
00421
00422 #ifndef SINGLE_SVR_THR
00423 boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
00424 #endif
00425 tmpAgentProc = *agentProcHead;
00426
00427 while (tmpAgentProc != NULL) {
00428 if (childPid == tmpAgentProc->pid) {
00429 if (prevAgentProc == NULL) {
00430 *agentProcHead = tmpAgentProc->next;
00431 } else {
00432 prevAgentProc->next = tmpAgentProc->next;
00433 }
00434 break;
00435 }
00436 prevAgentProc = tmpAgentProc;
00437 tmpAgentProc = tmpAgentProc->next;
00438 }
00439 #ifndef SINGLE_SVR_THR
00440 con_agent_lock.unlock();
00441 #endif
00442 return (tmpAgentProc);
00443 }
00444
00445
00446 int
00447 spawnAgent (agentProc_t *connReq, agentProc_t **agentProcHead)
00448 {
00449 int childPid;
00450 int newSock;
00451 startupPack_t *startupPack;
00452
00453 if (connReq == NULL) return USER__NULL_INPUT_ERR;
00454
00455 newSock = connReq->sock;
00456 startupPack = &connReq->startupPack;
00457
00458 #ifndef windows_platform
00459 childPid = fork ();
00460
00461
00462 if (childPid < 0) {
00463 return SYS_FORK_ERROR -errno;
00464 } else if (childPid == 0) {
00465 agentProc_t *tmpAgentProc;
00466 close (SvrSock);
00467 #ifdef SYS_TIMING
00468 printSysTiming ("irodsAgent", "after fork", 0);
00469 initSysTiming ("irodsAgent", "after fork", 1);
00470 #endif
00471
00472 #ifndef SINGLE_SVR_THR
00473
00474
00475 tmpAgentProc = ConnReqHead;
00476 while (tmpAgentProc != NULL) {
00477 if (tmpAgentProc->sock == -1) break;
00478 close (tmpAgentProc->sock);
00479 tmpAgentProc->sock = -1;
00480 tmpAgentProc = tmpAgentProc->next;
00481 }
00482 tmpAgentProc = SpawnReqHead;
00483 while (tmpAgentProc != NULL) {
00484 if (tmpAgentProc->sock == -1) break;
00485 close (tmpAgentProc->sock);
00486 tmpAgentProc->sock = -1;
00487 tmpAgentProc = tmpAgentProc->next;
00488 }
00489 #endif
00490 execAgent (newSock, startupPack);
00491 } else {
00492 #ifdef SYS_TIMING
00493 printSysTiming ("irodsServer", "fork agent", 0);
00494 #endif
00495 queConnectedAgentProc (childPid, connReq, agentProcHead);
00496 }
00497 #else
00498 childPid = execAgent (newSock, startupPack);
00499 queConnectedAgentProc (childPid, connReq, agentProcHead);
00500 #endif
00501
00502 return (childPid);
00503 }
00504
00505 int
00506 execAgent (int newSock, startupPack_t *startupPack)
00507 {
00508 #if windows_platform
00509 char *myArgv[3];
00510 char console_buf[20];
00511 #else
00512 char *myArgv[2];
00513 #endif
00514 int status;
00515 char buf[NAME_LEN];
00516
00517 mySetenvInt (SP_NEW_SOCK, newSock);
00518 mySetenvInt (SP_PROTOCOL, startupPack->irodsProt);
00519 mySetenvInt (SP_RECONN_FLAG, startupPack->reconnFlag);
00520 mySetenvInt (SP_CONNECT_CNT, startupPack->connectCnt);
00521 mySetenvStr (SP_PROXY_USER, startupPack->proxyUser);
00522 mySetenvStr (SP_PROXY_RODS_ZONE, startupPack->proxyRodsZone);
00523 mySetenvStr (SP_CLIENT_USER, startupPack->clientUser);
00524 mySetenvStr (SP_CLIENT_RODS_ZONE, startupPack->clientRodsZone);
00525 mySetenvStr (SP_REL_VERSION, startupPack->relVersion);
00526 mySetenvStr (SP_API_VERSION, startupPack->apiVersion);
00527
00528
00529
00530
00531 std::string opt_str( startupPack->option );
00532 size_t pos = opt_str.find( REQ_SVR_NEG );
00533 if( std::string::npos != pos ) {
00534 std::string trunc_str = opt_str.substr( 0, pos );
00535 mySetenvStr( SP_OPTION, trunc_str.c_str() );
00536 mySetenvStr( eirods::RODS_CS_NEG, REQ_SVR_NEG );
00537
00538 } else {
00539 mySetenvStr (SP_OPTION, startupPack->option);
00540
00541 }
00542
00543 mySetenvInt (SERVER_BOOT_TIME, ServerBootTime);
00544
00545 #if 0
00546 char *myBuf;
00547 myBuf = malloc (NAME_LEN * 2);
00548 snprintf (myBuf, NAME_LEN * 2, "%s=%d", SP_NEW_SOCK, newSock);
00549 putenv (myBuf);
00550
00551 myBuf = malloc (NAME_LEN * 2);
00552 snprintf (myBuf, NAME_LEN * 2, "%s=%d", SP_PROTOCOL,
00553 startupPack->irodsProt);
00554 putenv (myBuf);
00555
00556 myBuf = malloc (NAME_LEN * 2);
00557 snprintf (myBuf, NAME_LEN * 2, "%s=%d", SP_RECONN_FLAG,
00558 startupPack->reconnFlag);
00559 putenv (myBuf);
00560
00561 myBuf = malloc (NAME_LEN * 2);
00562 snprintf (myBuf, NAME_LEN * 2, "%s=%d", SP_CONNECT_CNT,
00563 startupPack->connectCnt);
00564 putenv (myBuf);
00565
00566 myBuf = malloc (NAME_LEN * 2);
00567 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_PROXY_USER,
00568 startupPack->proxyUser);
00569 putenv (myBuf);
00570
00571 myBuf = malloc (NAME_LEN * 2);
00572 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_PROXY_RODS_ZONE,
00573 startupPack->proxyRodsZone);
00574 putenv (myBuf);
00575
00576 myBuf = malloc (NAME_LEN * 2);
00577 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_CLIENT_USER,
00578 startupPack->clientUser);
00579 putenv (myBuf);
00580
00581 myBuf = malloc (NAME_LEN * 2);
00582 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_CLIENT_RODS_ZONE,
00583 startupPack->clientRodsZone);
00584 putenv (myBuf);
00585
00586 myBuf = malloc (NAME_LEN * 2);
00587 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_REL_VERSION,
00588 startupPack->relVersion);
00589 putenv (myBuf);
00590
00591 myBuf = malloc (NAME_LEN * 2);
00592 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_API_VERSION,
00593 startupPack->apiVersion);
00594 putenv (myBuf);
00595
00596 myBuf = malloc (NAME_LEN * 2);
00597 snprintf (myBuf, NAME_LEN * 2, "%s=%s", SP_OPTION,
00598 startupPack->option);
00599 putenv (myBuf);
00600
00601 myBuf = malloc (NAME_LEN * 2);
00602 snprintf (myBuf, NAME_LEN * 2, "%s=%d", SERVER_BOOT_TIME,
00603 ServerBootTime);
00604 putenv (myBuf);
00605 #endif
00606
00607 #ifdef windows_platform
00608 iRODSNtGetAgentExecutableWithPath(buf, AGENT_EXE);
00609 myArgv[0] = buf;
00610 if(iRODSNtServerRunningConsoleMode())
00611 {
00612 strcpy(console_buf, "console");
00613 myArgv[1]= console_buf;
00614 myArgv[2] = NULL;
00615 }
00616 else
00617 {
00618 myArgv[1] = NULL;
00619 myArgv[2] = NULL;
00620 }
00621 #else
00622 rstrcpy (buf, AGENT_EXE, NAME_LEN);
00623 myArgv[0] = buf;
00624 myArgv[1] = NULL;
00625 #endif
00626
00627 #if windows_platform
00628 return (int)_spawnv(_P_NOWAIT,myArgv[0], myArgv);
00629 #else
00630 status = execv(myArgv[0], myArgv);
00631 if (status < 0) {
00632 rodsLog (LOG_ERROR, "execAgent: execv error errno=%d", errno);
00633 exit (1);
00634 }
00635 return (0);
00636 #endif
00637 }
00638
00639 int
00640 queConnectedAgentProc (int childPid, agentProc_t *connReq,
00641 agentProc_t **agentProcHead)
00642 {
00643 if (connReq == NULL)
00644 return USER__NULL_INPUT_ERR;
00645
00646 connReq->pid = childPid;
00647 #ifndef SINGLE_SVR_THR
00648 boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
00649 #endif
00650
00651 queAgentProc (connReq, agentProcHead, TOP_POS);
00652
00653 #ifndef SINGLE_SVR_THR
00654 con_agent_lock.unlock();
00655 #endif
00656
00657 return (0);
00658 }
00659
00660 int
00661 getAgentProcCnt ()
00662 {
00663 agentProc_t *tmpAagentProc;
00664 int count = 0;
00665
00666 #ifndef SINGLE_SVR_THR
00667 boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
00668 #endif
00669
00670 tmpAagentProc = ConnectedAgentHead;
00671 while (tmpAagentProc != NULL) {
00672 count++;
00673 tmpAagentProc = tmpAagentProc->next;
00674 }
00675 #ifndef SINGLE_SVR_THR
00676 con_agent_lock.unlock();
00677 #endif
00678
00679 return count;
00680 }
00681
00682 int
00683 chkAgentProcCnt ()
00684 {
00685 int count;
00686
00687 if (MaxConnections == NO_MAX_CONNECTION_LIMIT) return 0;
00688 count = getAgentProcCnt ();
00689 if (count >= MaxConnections) {
00690 chkConnectedAgentProcQue ();
00691 count = getAgentProcCnt ();
00692 if (count >= MaxConnections) {
00693 return SYS_MAX_CONNECT_COUNT_EXCEEDED;
00694 } else {
00695 return 0;
00696 }
00697 } else {
00698 return 0;
00699 }
00700 }
00701
00702 int
00703 chkConnectedAgentProcQue ()
00704 {
00705 agentProc_t *tmpAgentProc, *prevAgentProc, *unmatchedAgentProc;
00706 prevAgentProc = NULL;
00707
00708 #ifndef SINGLE_SVR_THR
00709 boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
00710 #endif
00711 tmpAgentProc = ConnectedAgentHead;
00712
00713 while (tmpAgentProc != NULL) {
00714 char procPath[MAX_NAME_LEN];
00715
00716 snprintf (procPath, MAX_NAME_LEN, "%s/%-d", ProcLogDir,
00717 tmpAgentProc->pid);
00718 path p (procPath);
00719 if (!exists (p)) {
00720
00721 unmatchedAgentProc = tmpAgentProc;
00722 rodsLog (LOG_DEBUG,
00723 "Agent process %d in Connected queue but not in ProcLogDir",
00724 tmpAgentProc->pid);
00725 if (prevAgentProc == NULL) {
00726 ConnectedAgentHead = tmpAgentProc->next;
00727 } else {
00728 prevAgentProc->next = tmpAgentProc->next;
00729 }
00730 tmpAgentProc = tmpAgentProc->next;
00731 free (unmatchedAgentProc);
00732 } else {
00733 prevAgentProc = tmpAgentProc;
00734 tmpAgentProc = tmpAgentProc->next;
00735 }
00736 }
00737 #ifndef SINGLE_SVR_THR
00738 con_agent_lock.unlock();
00739 #endif
00740 return 0;
00741 }
00742
00743 int
00744 initServer ( rsComm_t *svrComm)
00745 {
00746 int status;
00747 rodsServerHost_t *rodsServerHost = NULL;
00748
00749 #ifdef windows_platform
00750 status = startWinsock();
00751 if(status !=0)
00752 {
00753 rodsLog (LOG_NOTICE, "initServer: startWinsock() failed. status=%d", status);
00754 return -1;
00755 }
00756 #endif
00757
00758 status = initServerInfo (svrComm);
00759 if (status < 0) {
00760 rodsLog (LOG_NOTICE,
00761 "initServer: initServerInfo error, status = %d",
00762 status);
00763 return (status);
00764 }
00765
00766
00767 resc_mgr.print_local_resources();
00768
00769 printZoneInfo ();
00770
00771 status = getRcatHost (MASTER_RCAT, NULL, &rodsServerHost);
00772
00773 if (status < 0 || NULL == rodsServerHost ) {
00774 return (status);
00775 }
00776
00777 if (rodsServerHost->localFlag == LOCAL_HOST) {
00778 #if RODS_CAT
00779 disconnectRcat (svrComm);
00780 #endif
00781 } else {
00782 if (rodsServerHost->conn != NULL) {
00783 rcDisconnect (rodsServerHost->conn);
00784 rodsServerHost->conn = NULL;
00785 }
00786 }
00787 initConnectControl ();
00788
00789 #if RODS_CAT // JMC - backport 4612
00790 purgeLockFileDir (0);
00791 #endif
00792
00793 return (status);
00794 }
00795
00796
00797
00798
00799 int
00800 recordServerProcess(rsComm_t *svrComm) {
00801 #ifndef windows_platform
00802 int myPid;
00803 FILE *fd;
00804 DIR *dirp;
00805 static char filePath[100]="";
00806 char cwd[1000];
00807 char stateFile[]="irodsServer";
00808 char *tmp;
00809 char *cp;
00810
00811 if (svrComm == NULL) {
00812 if (filePath[0]!='\0') {
00813 unlink(filePath);
00814 }
00815 return 0;
00816 }
00817 rodsEnv *myEnv = &(svrComm->myEnv);
00818
00819
00820 dirp = opendir("/usr/tmp");
00821 if (dirp!=NULL) {
00822 tmp="/usr/tmp";
00823 (void)closedir( dirp );
00824 }
00825 else {
00826 tmp="/tmp";
00827 }
00828
00829 sprintf (filePath, "%s/%s.%d", tmp, stateFile, myEnv->rodsPort);
00830
00831 unlink(filePath);
00832
00833 myPid=getpid();
00834 cp = getcwd(cwd, 1000);
00835 if (cp != NULL) {
00836 fd = fopen (filePath, "w");
00837 if (fd != NULL) {
00838 fprintf(fd, "%d %s\n", myPid, cwd);
00839 fclose(fd);
00840 chmod(filePath, 0664);
00841 }
00842 }
00843 #endif
00844 return 0;
00845 }
00846
00847 int
00848 initServerMain (rsComm_t *svrComm)
00849 {
00850 int status;
00851 rodsServerHost_t *reServerHost = NULL;
00852 rodsServerHost_t *xmsgServerHost = NULL;
00853
00854 bzero (svrComm, sizeof (rsComm_t));
00855
00856 status = getRodsEnv (&svrComm->myEnv);
00857
00858 if (status < 0) {
00859 rodsLog (LOG_ERROR, "initServerMain: getRodsEnv error. status = %d",
00860 status);
00861 return status;
00862 }
00863 initAndClearProcLog ();
00864
00865 setRsCommFromRodsEnv (svrComm);
00866
00867 status = initServer (svrComm);
00868
00869 if (status < 0) {
00870 rodsLog (LOG_ERROR, "initServerMain: initServer error. status = %d",
00871 status);
00872 exit (1);
00873 }
00874 svrComm->sock = sockOpenForInConn (svrComm, &svrComm->myEnv.rodsPort,
00875 NULL, SOCK_STREAM);
00876
00877 if (svrComm->sock < 0) {
00878 rodsLog (LOG_ERROR,
00879 "initServerMain: sockOpenForInConn error. status = %d",
00880 svrComm->sock);
00881 return svrComm->sock;
00882 }
00883
00884 listen (svrComm->sock, MAX_LISTEN_QUE);
00885
00886 rodsLog (LOG_NOTICE,
00887 "rodsServer Release version %s - API Version %s is up",
00888 RODS_REL_VERSION, RODS_API_VERSION);
00889
00890
00891 recordServerProcess(svrComm);
00892
00893 #ifndef windows_platform
00894 getReHost (&reServerHost);
00895 if (reServerHost != NULL && reServerHost->localFlag == LOCAL_HOST) {
00896 if (RODS_FORK () == 0) {
00897 char *reServerOption = NULL;
00898 char *av[NAME_LEN];
00899
00900 close (svrComm->sock);
00901 memset (av, 0, sizeof (av));
00902 reServerOption = getenv ("reServerOption");
00903 setExecArg (reServerOption, av);
00904 rodsLog(LOG_NOTICE, "Starting irodsReServer");
00905 av[0] = "irodsReServer";
00906 execv(av[0], av);
00907 exit(1);
00908 }
00909 }
00910 getXmsgHost (&xmsgServerHost);
00911 if (xmsgServerHost != NULL && xmsgServerHost->localFlag == LOCAL_HOST) {
00912 if (RODS_FORK () == 0) {
00913 char *av[NAME_LEN];
00914
00915 close (svrComm->sock);
00916 memset (av, 0, sizeof (av));
00917 rodsLog(LOG_NOTICE, "Starting irodsXmsgServer");
00918 av[0] = "irodsXmsgServer";
00919 execv(av[0], av);
00920 exit(1);
00921 }
00922 }
00923 #endif
00924
00925 return status;
00926 }
00927
00928
00929
00930 int
00931 addConnReqToQue (rsComm_t *rsComm, int sock)
00932 {
00933 agentProc_t *myConnReq;
00934
00935 #ifndef SINGLE_SVR_THR
00936 boost::unique_lock< boost::mutex > read_req_lock( ReadReqCondMutex );
00937 #endif
00938 myConnReq = (agentProc_t*)calloc (1, sizeof (agentProc_t));
00939
00940 myConnReq->sock = sock;
00941 myConnReq->remoteAddr = rsComm->remoteAddr;
00942 queAgentProc (myConnReq, &ConnReqHead, BOTTOM_POS);
00943
00944 #ifndef SINGLE_SVR_THR
00945 ReadReqCond.notify_all();
00946 read_req_lock.unlock();
00947 #endif
00948
00949 return (0);
00950 }
00951
00952 int
00953 initConnThreadEnv ()
00954 {
00955 return (0);
00956 }
00957
00958 agentProc_t *
00959 getConnReqFromQue ()
00960 {
00961 agentProc_t *myConnReq = NULL;
00962
00963 while (myConnReq == NULL) {
00964 #ifndef SINGLE_SVR_THR
00965 boost::unique_lock<boost::mutex> read_req_lock( ReadReqCondMutex );
00966 #endif
00967 if (ConnReqHead != NULL) {
00968 myConnReq = ConnReqHead;
00969 ConnReqHead = ConnReqHead->next;
00970 #ifndef SINGLE_SVR_THR
00971 read_req_lock.unlock();
00972 #endif
00973 break;
00974 }
00975
00976 #ifndef SINGLE_SVR_THR
00977 ReadReqCond.wait( read_req_lock );
00978 #endif
00979 if (ConnReqHead == NULL) {
00980 #ifndef SINGLE_SVR_THR
00981 read_req_lock.unlock();
00982 #endif
00983 continue;
00984 } else {
00985 myConnReq = ConnReqHead;
00986 ConnReqHead = ConnReqHead->next;
00987 #ifndef SINGLE_SVR_THR
00988 read_req_lock.unlock();
00989 #endif
00990 break;
00991 }
00992 }
00993
00994 return (myConnReq);
00995 }
00996
00997 int
00998 startProcConnReqThreads ()
00999 {
01000 int status = 0;
01001 int i;
01002
01003 initConnThreadEnv ();
01004 for (i = 0; i < NUM_READ_WORKER_THR; i++) {
01005 ReadWorkerThread[i] = new boost::thread( readWorkerTask );
01006 if (status < 0) {
01007 rodsLog (LOG_ERROR,
01008 "pthread_create of readWorker %d failed, errno = %d",
01009 i, errno);
01010 }
01011 }
01012 SpawnManagerThread = new boost::thread( spawnManagerTask );
01013
01014 return (status);
01015 }
01016
01017 void
01018 readWorkerTask ()
01019 {
01020 agentProc_t *myConnReq = NULL;
01021 startupPack_t *startupPack;
01022 int newSock = 0;
01023 int status = 0;
01024 struct timeval tv;
01025
01026
01027
01028
01029
01030 rcComm_t tmp_comm;
01031 bzero( &tmp_comm, sizeof( rcComm_t ) );
01032
01033 eirods::network_object_ptr net_obj;
01034 eirods::error ret = eirods::network_factory( &tmp_comm, net_obj );
01035 if( !ret.ok() || !net_obj.get() ) {
01036 eirods::log( PASS( ret ) );
01037 return;
01038 }
01039
01040 tv.tv_sec = READ_STARTUP_PACK_TOUT_SEC;
01041 tv.tv_usec = 0;
01042 while (1) {
01043 myConnReq = getConnReqFromQue ();
01044 if (myConnReq == NULL) {
01045
01046 continue;
01047 }
01048
01049 newSock = myConnReq->sock;
01050
01051
01052
01053
01054 net_obj->socket_handle( newSock );
01055 status = readStartupPack( net_obj, &startupPack, &tv );
01056
01057 if( status < 0 ) {
01058 rodsLog( LOG_ERROR, "readWorkerTask - readStartupPack failed. %d", status );
01059 sendVersion ( net_obj, status, 0, NULL, 0);
01060 #ifndef SINGLE_SVR_THR
01061 boost::unique_lock<boost::mutex> bad_req_lock( BadReqMutex );
01062 #endif
01063 queAgentProc (myConnReq, &BadReqHead, TOP_POS);
01064 #ifndef SINGLE_SVR_THR
01065 bad_req_lock.unlock();
01066 #endif
01067 mySockClose (newSock);
01068 } else if (startupPack->connectCnt > MAX_SVR_SVR_CONNECT_CNT) {
01069 sendVersion( net_obj, SYS_EXCEED_CONNECT_CNT, 0, NULL, 0 );
01070 mySockClose (newSock);
01071 free (myConnReq);
01072 } else {
01073 if (startupPack->clientUser[0] == '\0') {
01074 status = chkAllowedUser (startupPack->clientUser,
01075 startupPack->clientRodsZone);
01076 if (status < 0) {
01077 sendVersion (net_obj, status, 0, NULL, 0);
01078 mySockClose (newSock);
01079 free (myConnReq);
01080 }
01081 }
01082
01083 myConnReq->startupPack = *startupPack;
01084 free (startupPack);
01085 #ifndef SINGLE_SVR_THR
01086 boost::unique_lock< boost::mutex > spwn_req_lock( SpawnReqCondMutex );
01087 #endif
01088 queAgentProc (myConnReq, &SpawnReqHead, BOTTOM_POS);
01089 #ifndef SINGLE_SVR_THR
01090 SpawnReqCond.notify_all();
01091 #endif
01092 }
01093
01094 }
01095
01096 }
01097
01098 void
01099 spawnManagerTask ()
01100 {
01101 agentProc_t *mySpawnReq = NULL;
01102 int status;
01103 uint curTime;
01104 uint agentQueChkTime = 0;
01105 while (1) {
01106 #ifndef SINGLE_SVR_THR
01107 boost::unique_lock<boost::mutex> spwn_req_lock( SpawnReqCondMutex );
01108 SpawnReqCond.wait( spwn_req_lock );
01109 #endif
01110 while (SpawnReqHead != NULL) {
01111 mySpawnReq = SpawnReqHead;
01112 SpawnReqHead = mySpawnReq->next;
01113 #ifndef SINGLE_SVR_THR
01114 spwn_req_lock.unlock();
01115 #endif
01116 status = spawnAgent (mySpawnReq, &ConnectedAgentHead);
01117 close (mySpawnReq->sock);
01118
01119 if (status < 0) {
01120 rodsLog (LOG_NOTICE,
01121 "spawnAgent error for puser=%s and cuser=%s from %s, stat=%d",
01122 mySpawnReq->startupPack.proxyUser,
01123 mySpawnReq->startupPack.clientUser,
01124 inet_ntoa (mySpawnReq->remoteAddr.sin_addr), status);
01125 free (mySpawnReq);
01126 } else {
01127 rodsLog (LOG_NOTICE,
01128 "Agent process %d started for puser=%s and cuser=%s from %s",
01129 mySpawnReq->pid, mySpawnReq->startupPack.proxyUser,
01130 mySpawnReq->startupPack.clientUser,
01131 inet_ntoa (mySpawnReq->remoteAddr.sin_addr));
01132 }
01133 #ifndef SINGLE_SVR_THR
01134 spwn_req_lock.lock();
01135 #endif
01136 }
01137 #ifndef SINGLE_SVR_THR
01138 spwn_req_lock.unlock();
01139 #endif
01140 curTime = time (0);
01141 if (curTime > agentQueChkTime + AGENT_QUE_CHK_INT) {
01142 agentQueChkTime = curTime;
01143 procBadReq ();
01144 #if 0
01145 chkConnectedAgentProcQue ();
01146 #endif
01147 }
01148 }
01149 }
01150
01151 int
01152 procSingleConnReq (agentProc_t *connReq)
01153 {
01154 startupPack_t *startupPack;
01155 int newSock;
01156 int status;
01157
01158 if (connReq == NULL) return USER__NULL_INPUT_ERR;
01159
01160 newSock = connReq->sock;
01161
01162
01163
01164
01165
01166 rcComm_t tmp_comm;
01167 bzero( &tmp_comm, sizeof( rcComm_t ) );
01168
01169 eirods::network_object_ptr net_obj;
01170 eirods::error ret = eirods::network_factory( &tmp_comm, net_obj );
01171 if( !ret.ok() ) {
01172 eirods::log( PASS( ret ) );
01173 return -1;
01174 }
01175
01176 net_obj->socket_handle( newSock );
01177
01178 status = readStartupPack( net_obj, &startupPack, NULL );
01179
01180 if (status < 0) {
01181 rodsLog (LOG_NOTICE, "readStartupPack error from %s, status = %d",
01182 inet_ntoa (connReq->remoteAddr.sin_addr), status);
01183 sendVersion( net_obj, status, 0, NULL, 0 );
01184 mySockClose (newSock);
01185 return status;
01186 }
01187 #ifdef SYS_TIMING
01188 printSysTiming ("irodsServer", "read StartupPack", 0);
01189 #endif
01190 if (startupPack->connectCnt > MAX_SVR_SVR_CONNECT_CNT) {
01191 sendVersion ( net_obj, SYS_EXCEED_CONNECT_CNT, 0, NULL, 0);
01192 mySockClose (newSock);
01193 return SYS_EXCEED_CONNECT_CNT;
01194 }
01195
01196 connReq->startupPack = *startupPack;
01197 free (startupPack);
01198 status = spawnAgent (connReq, &ConnectedAgentHead);
01199
01200 #ifndef windows_platform
01201 close (newSock);
01202 #endif
01203 if (status < 0) {
01204 rodsLog (LOG_NOTICE,
01205 "spawnAgent error for puser=%s and cuser=%s from %s, status = %d",
01206 connReq->startupPack.proxyUser, connReq->startupPack.clientUser,
01207 inet_ntoa (connReq->remoteAddr.sin_addr), status);
01208 } else {
01209 rodsLog (LOG_NOTICE,
01210 "Agent process %d started for puser=%s and cuser=%s from %s",
01211 connReq->pid, connReq->startupPack.proxyUser,
01212 connReq->startupPack.clientUser,
01213 inet_ntoa (connReq->remoteAddr.sin_addr));
01214 }
01215 return status;
01216 }
01217
01218
01219 int
01220 procBadReq ()
01221 {
01222 agentProc_t *tmpConnReq, *nextConnReq;
01223
01224 #ifndef SINGLE_SVR_THR
01225 boost::unique_lock< boost::mutex > bad_req_lock( BadReqMutex );
01226 #endif
01227 tmpConnReq = BadReqHead;
01228 while (tmpConnReq != NULL) {
01229 nextConnReq = tmpConnReq->next;
01230 free (tmpConnReq);
01231 tmpConnReq = nextConnReq;
01232 }
01233 BadReqHead = NULL;
01234 #ifndef SINGLE_SVR_THR
01235 bad_req_lock.unlock();
01236 #endif
01237
01238 return 0;
01239 }
01240
01241
01242
01243 void
01244 purgeLockFileWorkerTask ()
01245 {
01246 int status;
01247 while (1) {
01248 rodsSleep (LOCK_FILE_PURGE_TIME, 0);
01249 status = purgeLockFileDir (1);
01250 if (status < 0) {
01251 rodsLogError (LOG_ERROR, status,
01252 "purgeLockFileWorkerTask: purgeLockFileDir failed");
01253 }
01254 }
01255 }
01256