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