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