irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

rodsServer.cpp
Go to the documentation of this file.
1 
4 #include "rcMisc.h"
5 #include "rodsServer.hpp"
6 #include "sharedmemory.hpp"
7 #include "initServer.hpp"
8 #include "miscServerFunct.hpp"
9 
10 #include <syslog.h>
11 
12 #include <pthread.h>
13 
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 
18 // =-=-=-=-=-=-=-
19 //
20 #include "irods_exception.hpp"
21 #include "irods_server_state.hpp"
24 #include "irods_re_plugin.hpp"
27 #include "initServer.hpp"
28 #include "procLog.h"
29 #include "rsGlobalExtern.hpp"
30 #include "locks.hpp"
31 #include "sharedmemory.hpp"
32 
33 #include <boost/filesystem.hpp>
34 #include <boost/filesystem/operations.hpp>
35 #include <boost/filesystem/convenience.hpp>
36 #include <boost/range/iterator_range.hpp>
37 using namespace boost::filesystem;
38 
40 
41 #include "sys/un.h"
42 
43 #include "irods_random.hpp"
44 
45 struct sockaddr_un local_addr{};
48 
50 const char socket_dir_template[]{"/tmp/irods_sockets_XXXXXX"};
52 char agent_factory_socket_file[sizeof(local_addr.sun_path)]{};
53 
55 int SvrSock;
56 
61 
62 #include <boost/thread/thread.hpp>
63 #include <boost/thread/mutex.hpp>
64 #include <boost/thread/condition.hpp>
65 boost::mutex ConnectedAgentMutex;
66 boost::mutex BadReqMutex;
68 boost::thread* SpawnManagerThread;
69 
70 boost::thread* PurgeLockFileThread; // JMC - backport 4612
71 
72 boost::mutex ReadReqCondMutex;
73 boost::mutex SpawnReqCondMutex;
74 boost::condition_variable ReadReqCond;
75 boost::condition_variable SpawnReqCond;
76 
77 std::vector<std::string> setExecArg( const char *commandArgv );
78 
79 int runIrodsAgentFactory(sockaddr_un agent_addr);
80 
82  int childPid,
83  agentProc_t *connReq,
84  agentProc_t **agentProcHead);
85 
86 namespace {
87 // We incorporate the cache salt into the rule engine's named_mutex and shared memory object.
88 // This prevents (most of the time) an orphaned mutex from halting server standup. Issue most often seen
89 // when a running iRODS installation is uncleanly killed (leaving the file system object used to implement
90 // boost::named_mutex e.g. in /var/run/shm) and then the iRODS user account is recreated, yielding a different
91 // UID. The new iRODS user account is then unable to unlock or remove the existing mutex, blocking the server.
92  irods::error createAndSetRECacheSalt() {
93  // Should only ever set the cache salt once
94  try {
95  const auto& existing_salt = irods::get_server_property<const std::string>(irods::CFG_RE_CACHE_SALT_KW);
96  rodsLog( LOG_ERROR, "createAndSetRECacheSalt: salt already set [%s]", existing_salt.c_str() );
97  return ERROR( SYS_ALREADY_INITIALIZED, "createAndSetRECacheSalt: cache salt already set" );
98  } catch ( const irods::exception& ) {
101  if ( !ret.ok() ) {
102  rodsLog( LOG_ERROR, "createAndSetRECacheSalt: failed to generate random bytes" );
103  return PASS( ret );
104  }
105 
106  std::string cache_salt_random;
107  ret = irods::buffer_crypt::hex_encode( buf, cache_salt_random );
108  if ( !ret.ok() ) {
109  rodsLog( LOG_ERROR, "createAndSetRECacheSalt: failed to hex encode random bytes" );
110  return PASS( ret );
111  }
112 
113  std::stringstream cache_salt;
114  cache_salt << "pid"
115  << static_cast<intmax_t>( getpid() )
116  << "_"
117  << cache_salt_random;
118 
119  try {
120  irods::set_server_property<std::string>( irods::CFG_RE_CACHE_SALT_KW, cache_salt.str() );
121  } catch ( const irods::exception& e ) {
122  rodsLog( LOG_ERROR, "createAndSetRECacheSalt: failed to set server_properties" );
123  return irods::error(e);
124  }
125 
126  int ret_int = setenv( SP_RE_CACHE_SALT, cache_salt.str().c_str(), 1 );
127  if ( 0 != ret_int ) {
128  rodsLog( LOG_ERROR, "createAndSetRECacheSalt: failed to set environment variable" );
129  return ERROR( SYS_SETENV_ERR, "createAndSetRECacheSalt: failed to set environment variable" );
130  }
131 
132  return SUCCESS();
133  }
134  }
135 
136  int get64RandomBytes( char *buf ) {
137  const int num_random_bytes = 32;
138  const int num_hex_bytes = 2 * num_random_bytes;
139  unsigned char random_bytes[num_random_bytes];
140  irods::getRandomBytes( random_bytes, sizeof(random_bytes) );
141 
142  std::stringstream ss;
143  for ( size_t i = 0; i < sizeof(random_bytes); ++i ) {
144  ss << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)( random_bytes[i] );
145  }
146 
147  snprintf( buf, num_hex_bytes + 1, "%s", ss.str().c_str() );
148  return 0;
149  }
150 }
151 
153  const char* desired_name = "irodsServer: factory";
154  const auto l_desired = strlen(desired_name);
155  if (l_desired <= info.argv0_size) {
156  strncpy(info.argv0, desired_name, info.argv0_size);
157  }
158 }
159 
160 int
161 main( int argc, char **argv )
162 {
163  int c;
164  int uFlag = 0;
165  char tmpStr1[100], tmpStr2[100];
166  char *logDir = NULL;
167 
168  ProcessType = SERVER_PT; /* I am a server */
169 
170  const char* log_level = getenv(SP_LOG_LEVEL);
171  if (log_level)
172  {
173  rodsLogLevel( atoi( log_level ) );
174  }
175  else
176  {
178  }
179 
180  // Issue #3865 - The mere existence of the environment variable sets
181  // the value to 1. Otherwise it stays at the default level (currently 0).
182  const char* sql_log_level = getenv(SP_LOG_SQL);
183  if (sql_log_level)
184  {
185  rodsLogSqlReq(1);
186  }
187 
188 #ifdef SYSLOG
189  /* Open a connection to syslog */
190  openlog( "rodsServer", LOG_ODELAY | LOG_PID, LOG_DAEMON );
191 #endif
192 
193  ServerBootTime = time( 0 );
194  while ( ( c = getopt( argc, argv, "uvVqsh" ) ) != EOF ) {
195  switch ( c ) {
196  case 'u': /* user command level. without serverized */
197  uFlag = 1;
198  break;
199  case 'D': /* user specified a log directory */
200  logDir = strdup( optarg );
201  break;
202  case 'v': /* verbose Logging */
203  snprintf( tmpStr1, 100, "%s=%d", SP_LOG_LEVEL, LOG_NOTICE );
204  putenv( tmpStr1 );
206  break;
207  case 'V': /* very Verbose */
208  snprintf( tmpStr1, 100, "%s=%d", SP_LOG_LEVEL, LOG_DEBUG10 );
209  putenv( tmpStr1 );
211  break;
212  case 'q': /* quiet (only errors and above) */
213  snprintf( tmpStr1, 100, "%s=%d", SP_LOG_LEVEL, LOG_ERROR );
214  putenv( tmpStr1 );
216  break;
217  case 's': /* log SQL commands */
218  snprintf( tmpStr2, 100, "%s=%d", SP_LOG_SQL, 1 );
219  putenv( tmpStr2 );
220  break;
221  case 'h': /* help */
222  usage( argv[0] );
223  exit( 0 );
224  default:
225  usage( argv[0] );
226  exit( 1 );
227  }
228  }
229 
230  if ( uFlag == 0 ) {
231  if ( serverize( logDir ) < 0 ) {
232  exit( 1 );
233  }
234  }
235 
236  /* start of irodsReServer has been moved to serverMain */
237  signal( SIGTTIN, SIG_IGN );
238  signal( SIGTTOU, SIG_IGN );
239  signal( SIGCHLD, SIG_DFL ); /* SIG_IGN causes autoreap. wait get nothing */
240  signal( SIGPIPE, SIG_IGN );
241 #ifdef osx_platform
242  signal( SIGINT, ( sig_t ) serverExit );
243  signal( SIGHUP, ( sig_t ) serverExit );
244  signal( SIGTERM, ( sig_t ) serverExit );
245 #else
246  signal( SIGINT, serverExit );
247  signal( SIGHUP, serverExit );
248  signal( SIGTERM, serverExit );
249 #endif
250 
251  // Set up local_addr for socket communication
252  memset( &local_addr, 0, sizeof(local_addr) );
253  local_addr.sun_family = AF_UNIX;
254  char random_suffix[65];
255  get64RandomBytes( random_suffix );
256 
257  char mkdtemp_template[sizeof(socket_dir_template)]{};
258  snprintf(mkdtemp_template, sizeof(mkdtemp_template), "%s", socket_dir_template);
259 
260  const char* mkdtemp_result = mkdtemp(mkdtemp_template);
261  if (!mkdtemp_result) {
262  rodsLog(LOG_ERROR, "Error creating tmp directory for iRODS sockets, mkdtemp errno [%d]: [%s]", errno, strerror(errno));
263  free(logDir);
264  return SYS_INTERNAL_ERR;
265  }
266  snprintf(agent_factory_socket_dir, sizeof(agent_factory_socket_dir), "%s", mkdtemp_result);
267  snprintf(agent_factory_socket_file, sizeof(agent_factory_socket_file), "%s/irods_factory_%s", agent_factory_socket_dir, random_suffix);
268  snprintf(local_addr.sun_path, sizeof(local_addr.sun_path), "%s", agent_factory_socket_file);
269 
270  agent_spawning_pid = fork();
271 
272  if ( agent_spawning_pid == 0 ) {
273  // Agent factory process (parent)
275  free( logDir );
277  } else if ( agent_spawning_pid > 0 ) {
278  // Main iRODS server (grandparent)
279  rodsLog( LOG_NOTICE, "Agent factory process pid = [%d]", agent_spawning_pid );
280  agent_conn_socket = socket( AF_UNIX, SOCK_STREAM, 0 );
281 
282  time_t sock_connect_start_time = time( 0 );
283  while (true) {
284  const unsigned int len = sizeof(local_addr);
285  ssize_t status = connect( agent_conn_socket, (const struct sockaddr*) &local_addr, len );
286  if ( status >= 0 ) {
287  break;
288  }
289 
290  int saved_errno = errno;
291  if ( ( time( 0 ) - sock_connect_start_time ) > 5 ) {
292  rodsLog(LOG_ERROR, "Error connecting to agent factory socket, errno = [%d]: %s", saved_errno, strerror( saved_errno ) );
293  free( logDir );
294  return SYS_SOCK_CONNECT_ERR;
295  }
296  }
297  } else {
298  // Error, fork failed
299  rodsLog( LOG_ERROR, "fork() failed when attempting to create agent factory process" );
300  free( logDir );
301  return SYS_FORK_ERROR;
302  }
303 
304  return serverMain( logDir );
305 }
306 
307 int
308 serverize( char *logDir ) {
309  char *logFile = NULL;
310 
311  // [#3563] server process gets unique log
312  getLogfileName( &logFile, logDir, RODS_SERVER_LOGFILE );
313 
314 #ifdef SYSLOG
315  LogFd = 0;
316 #else
317  LogFd = open( logFile, O_CREAT | O_WRONLY | O_APPEND, 0644 );
318 #endif
319 
320  if ( LogFd < 0 ) {
321  rodsLog( LOG_NOTICE, "logFileOpen: Unable to open %s. errno = %d",
322  logFile, errno );
323  free( logFile );
324  return -1;
325  }
326 
327  free( logFile );
328  if ( fork() ) { /* parent */
329  exit( 0 );
330  }
331  else { /* child */
332  if ( setsid() < 0 ) {
334  "serverize: setsid failed, errno = %d\n", errno );
335  exit( 1 );
336  }
337 
338 #ifndef SYSLOG
339  ( void ) dup2( LogFd, 0 );
340  ( void ) dup2( LogFd, 1 );
341  ( void ) dup2( LogFd, 2 );
342  close( LogFd );
343  LogFd = 2;
344 #endif
345  }
346 
347 #ifdef SYSLOG
348  return 0;
349 #else
350  return LogFd;
351 #endif
352 }
353 
354 static bool instantiate_shared_memory_for_plugin( const std::unordered_map<std::string, boost::any>& _plugin_object ) {
355  try {
356  const auto& mem_name = boost::any_cast<const std::string&>(_plugin_object.at(irods::CFG_SHARED_MEMORY_INSTANCE_KW));
357  prepareServerSharedMemory(mem_name);
358  detachSharedMemory(mem_name);
359  } catch ( const std::out_of_range& ) {
360  return false;
361  }
362  return true;
363 }
364 
365 static bool uninstantiate_shared_memory_for_plugin( const std::unordered_map<std::string, boost::any>& _plugin_object ) {
366  try {
367  const auto& mem_name = boost::any_cast<const std::string&>(_plugin_object.at(irods::CFG_SHARED_MEMORY_INSTANCE_KW));
368  removeSharedMemory(mem_name);
369  resetMutex(mem_name.c_str());
370  } catch ( const std::out_of_range& ) {
371  return false;
372  }
373  return true;
374 }
375 
377  try {
378  for ( const auto& item : irods::get_server_property<const std::unordered_map<std::string, boost::any>&>(irods::CFG_PLUGIN_CONFIGURATION_KW) ) {
379  if ( item.first == irods::PLUGIN_TYPE_RULE_ENGINE ) {
380  for ( const auto& plugin : boost::any_cast<const std::vector<boost::any>&>(item.second) ) {
381  instantiate_shared_memory_for_plugin(boost::any_cast<const std::unordered_map<std::string, boost::any>&>(plugin));
382  }
383  } else {
384  for ( const auto& plugin : boost::any_cast<const std::unordered_map<std::string, boost::any>&>(item.second) ) {
385  instantiate_shared_memory_for_plugin(boost::any_cast<const std::unordered_map<std::string, boost::any>&>(plugin.second));
386  }
387  }
388  }
389  } catch ( const boost::bad_any_cast& e ) {
390  return ERROR(INVALID_ANY_CAST, e.what());
391  } catch ( const irods::exception& e ) {
392  return irods::error(e);
393  }
394  return SUCCESS();
395 
396 } // instantiate_shared_memory
397 
399  try {
400  for ( const auto& item : irods::get_server_property<const std::unordered_map<std::string, boost::any>&>(irods::CFG_PLUGIN_CONFIGURATION_KW) ) {
401  if ( item.first == irods::PLUGIN_TYPE_RULE_ENGINE ) {
402  for ( const auto& plugin : boost::any_cast<const std::vector<boost::any>&>(item.second) ) {
403  uninstantiate_shared_memory_for_plugin(boost::any_cast<const std::unordered_map<std::string, boost::any>&>(plugin));
404  }
405  } else {
406  for ( const auto& plugin : boost::any_cast<const std::unordered_map<std::string, boost::any>&>(item.second) ) {
407  uninstantiate_shared_memory_for_plugin(boost::any_cast<const std::unordered_map<std::string, boost::any>&>(plugin.second));
408  }
409  }
410  }
411  } catch ( const boost::bad_any_cast& e ) {
412  return ERROR(INVALID_ANY_CAST, e.what());
413  } catch ( const irods::exception& e ) {
414  return irods::error(e);
415  }
416  return SUCCESS();
417 
418 } // uninstantiate_shared_memory
419 
420 int
421 serverMain( char *logDir ) {
422  int loopCnt = 0;
423  int acceptErrCnt = 0;
424 
425  // set re cache salt here
426  irods::error ret = createAndSetRECacheSalt();
427  if ( !ret.ok() ) {
428  rodsLog( LOG_ERROR, "serverMain: createAndSetRECacheSalt error.\n%s", ret.result().c_str() );
429  exit( 1 );
430  }
431 
433  if(!ret.ok()) {
434  irods::log(PASS(ret));
435  }
436 
438 
439  rsComm_t svrComm;
440  int status = initServerMain( &svrComm );
441  if ( status < 0 ) {
442  rodsLog( LOG_ERROR, "serverMain: initServerMain error. status = %d",
443  status );
444  exit( 1 );
445  }
446 
447  std::string svc_role;
448  ret = get_catalog_service_role(svc_role);
449  if(!ret.ok()) {
450  irods::log(PASS(ret));
451  return ret.code();
452  }
453 
454  uint64_t return_code = 0;
455  // =-=-=-=-=-=-=-
456  // Launch the Control Plane
457  try {
458  irods::server_control_plane ctrl_plane(
460 
462  if(status < 0) {
463  rodsLog(LOG_ERROR, "[%s] - Error in startProcConnReqThreads()", __FUNCTION__);
464  return status;
465  }
466  if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) {
467  try {
468  PurgeLockFileThread = new boost::thread( purgeLockFileWorkerTask );
469  }
470  catch ( const boost::thread_resource_error& ) {
471  rodsLog( LOG_ERROR, "boost encountered a thread_resource_error during thread construction in serverMain." );
472  }
473  }
474 
475  fd_set sockMask;
476  FD_ZERO( &sockMask );
477  SvrSock = svrComm.sock;
478 
480  while ( true ) {
481  std::string the_server_state = server_state();
482  if ( irods::server_state::STOPPED == the_server_state ) {
484 
485  // Wake up the agent factory process so it can clean up and exit
486  kill( agent_spawning_pid, SIGTERM );
487 
488  rodsLog(
489  LOG_NOTICE,
490  "iRODS Server is exiting with state [%s].",
491  the_server_state.c_str() );
492  break;
493 
494  }
495  else if ( irods::server_state::PAUSED == the_server_state ) {
497  rodsSleep(
498  0,
500  continue;
501 
502  }
503  else {
504  if ( irods::server_state::RUNNING != the_server_state ) {
505  rodsLog(
506  LOG_NOTICE,
507  "invalid iRODS server state [%s]",
508  the_server_state.c_str() );
509  }
510 
511  }
512 
513  FD_SET( svrComm.sock, &sockMask );
514 
515  int numSock = 0;
516  struct timeval time_out;
517  time_out.tv_sec = 0;
518  time_out.tv_usec = irods::SERVER_CONTROL_POLLING_TIME_MILLI_SEC * 1000;
519  while ( ( numSock = select(
520  svrComm.sock + 1,
521  &sockMask,
522  ( fd_set * ) NULL,
523  ( fd_set * ) NULL,
524  &time_out ) ) < 0 ) {
525 
526  if ( errno == EINTR ) {
527  rodsLog( LOG_NOTICE, "serverMain: select() interrupted" );
528  FD_SET( svrComm.sock, &sockMask );
529  continue;
530  }
531  else {
532  rodsLog( LOG_NOTICE, "serverMain: select() error, errno = %d",
533  errno );
534  return -1;
535  }
536  }
537 
539 
540  if ( 0 == numSock ) {
541  continue;
542 
543  }
544 
545  const int newSock = rsAcceptConn( &svrComm );
546  if ( newSock < 0 ) {
547  acceptErrCnt ++;
548  if ( acceptErrCnt > MAX_ACCEPT_ERR_CNT ) {
550  "serverMain: Too many socket accept error. Exiting" );
551  break;
552  }
553  else {
555  "serverMain: acceptConn () error, errno = %d", errno );
556  continue;
557  }
558  }
559  else {
560  acceptErrCnt = 0;
561  }
562 
564  if ( status < 0 ) {
566  "serverMain: chkAgentProcCnt failed status = %d", status );
567  // =-=-=-=-=-=-=-
568  // create network object to communicate to the network
569  // plugin interface. repave with newSock as that is the
570  // operational socket at this point
571 
573  irods::error ret = irods::network_factory( &svrComm, net_obj );
574  if ( !ret.ok() ) {
575  irods::log( PASS( ret ) );
576  }
577  else {
578  ret = sendVersion( net_obj, status, 0, NULL, 0 );
579  if ( !ret.ok() ) {
580  irods::log( PASS( ret ) );
581  }
582  }
583  status = mySockClose( newSock );
584  printf( "close status = %d\n", status );
585  continue;
586  }
587 
588  addConnReqToQue( &svrComm, newSock );
589 
590  loopCnt++;
591  if ( loopCnt >= LOGFILE_CHK_CNT ) {
592  // [#3563] server process gets unique log
594  loopCnt = 0;
595  }
596  }
597 
598  if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) {
599  try {
600  PurgeLockFileThread->join();
601  }
602  catch ( const boost::thread_resource_error& ) {
603  rodsLog( LOG_ERROR, "boost encountered a thread_resource_error during join in serverMain." );
604  }
605  }
606 
609 
610  server_state( irods::server_state::EXITED );
611  }
612  catch ( const irods::exception& e_ ) {
613  rodsLog( LOG_ERROR, "Exception caught in server loop\n%s", e_.what() );
614  return_code = e_.code();
615  }
616 
618 
619  close( agent_conn_socket );
620  unlink( agent_factory_socket_file );
621  rmdir( agent_factory_socket_dir );
622 
623  rodsLog( LOG_NOTICE, "iRODS Server is done." );
624 
625  return return_code;
626 
627 }
628 
629 void
630 #if defined(linux_platform) || defined(aix_platform) || defined(solaris_platform) || defined(osx_platform)
631 serverExit( int sig )
632 #else
634 #endif
635 {
636 #if 0
637  // RTS - rodsLog calls in signal handlers are unsafe - #3326
638  rodsLog( LOG_NOTICE, "rodsServer caught signal %d, exiting", sig );
639 #endif
640  recordServerProcess( NULL ); /* unlink the process id file */
641 
642  close( agent_conn_socket );
643  unlink( agent_factory_socket_file );
644  rmdir( agent_factory_socket_dir );
645 
646  // Wake and terminate agent spawning process
647  kill( agent_spawning_pid, SIGTERM );
648 
649  exit( 1 );
650 }
651 
652 void
653 usage( char *prog ) {
654  printf( "Usage: %s [-uvVqs]\n", prog );
655  printf( " -u user command level, remain attached to the tty (foreground)\n" );
656  printf( " -v verbose (LOG_NOTICE)\n" );
657  printf( " -V very verbose (LOG_DEBUG10)\n" );
658  printf( " -q quiet (LOG_ERROR)\n" );
659  printf( " -s log SQL commands\n" );
660 }
661 
662 int
663 procChildren( agentProc_t **agentProcHead ) {
664  agentProc_t *tmpAgentProc, *prevAgentProc, *finishedAgentProc;
665  prevAgentProc = NULL;
666 
667  boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
668 
669  tmpAgentProc = *agentProcHead;
670 
671  while ( tmpAgentProc != NULL ) {
672  // Check if pid is still an active process
673  if ( kill( tmpAgentProc->pid, 0 ) ) {
674  finishedAgentProc = tmpAgentProc;
675 
676  if ( prevAgentProc == NULL ) {
677  *agentProcHead = tmpAgentProc->next;
678  } else {
679  prevAgentProc->next = tmpAgentProc->next;
680  }
681  tmpAgentProc = tmpAgentProc->next;
682  free( finishedAgentProc );
683  } else {
684  prevAgentProc = tmpAgentProc;
685  tmpAgentProc = tmpAgentProc->next;
686  }
687  }
688 
689  con_agent_lock.unlock();
690 
691  return 0;
692 }
693 
694 agentProc_t *
695 getAgentProcByPid( int childPid, agentProc_t **agentProcHead ) {
696  agentProc_t *tmpAgentProc, *prevAgentProc;
697  prevAgentProc = NULL;
698 
699  boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
700 
701  tmpAgentProc = *agentProcHead;
702 
703  while ( tmpAgentProc != NULL ) {
704  if ( childPid == tmpAgentProc->pid ) {
705  if ( prevAgentProc == NULL ) {
706  *agentProcHead = tmpAgentProc->next;
707  }
708  else {
709  prevAgentProc->next = tmpAgentProc->next;
710  }
711  break;
712  }
713  prevAgentProc = tmpAgentProc;
714  tmpAgentProc = tmpAgentProc->next;
715  }
716 
717  con_agent_lock.unlock();
718 
719  return tmpAgentProc;
720 }
721 
722 int
723 spawnAgent( agentProc_t *connReq, agentProc_t **agentProcHead ) {
724  int childPid;
725  int newSock;
727 
728  if ( connReq == NULL ) {
729  return USER__NULL_INPUT_ERR;
730  }
731 
732  newSock = connReq->sock;
733  startupPack = &connReq->startupPack;
734 
735  childPid = execAgent( newSock, startupPack );
736  if (childPid > 0) {
737  queueConnectedAgentProc(childPid, connReq, agentProcHead);
738  }
739 
740  return childPid;
741 }
742 
743 int sendEnvironmentVarIntToSocket ( const char* var, int val, int socket ) {
744  std::stringstream msg;
745  msg << var << "=" << val << ";";
746  ssize_t status = send( socket, msg.str().c_str(), msg.str().length(), 0 );
747  if ( status < 0 ) {
748  rodsLog( LOG_ERROR, "Error in sendEnvironmentVarIntToSocket, errno = [%d]: %s", errno, strerror( errno ) );
749  } else if ( static_cast<size_t>(status) != msg.str().length() ) {
750  rodsLog( LOG_DEBUG, "Failed to send entire message in sendEnvironmentVarIntToSocket - msg [%s] is [%d] bytes long, sent [%d] bytes", msg.str().c_str(), msg.str().length(), status );
751  }
752 
753  return status;
754 }
755 
756 int sendEnvironmentVarStrToSocket ( const char* var, const char* val, int socket ) {
757  std::stringstream msg;
758  msg << var << "=" << val << ";";
759  ssize_t status = send( socket, msg.str().c_str(), msg.str().length(), 0 );
760  if ( status < 0 ) {
761  rodsLog( LOG_ERROR, "Error in sendEnvironmentVarIntToSocket, errno = [%d]: %s", errno, strerror( errno ) );
762  } else if ( static_cast<size_t>(status) != msg.str().length() ) {
763  rodsLog( LOG_DEBUG, "Failed to send entire message in sendEnvironmentVarIntToSocket - msg [%s] is [%d] bytes long, sent [%d] bytes", msg.str().c_str(), msg.str().length(), status );
764  }
765 
766  return status;
767 }
768 
769 ssize_t sendSocketOverSocket( int writeFd, int socket ) {
770  struct msghdr msg;
771  struct iovec iov[1];
772 
773  union {
774  struct cmsghdr cm;
775  char control[CMSG_SPACE(sizeof(int))];
776  } control_un;
777  struct cmsghdr *cmptr;
778 
779  memset( control_un.control, 0, sizeof(control_un.control) );
780  msg.msg_control = control_un.control;
781  msg.msg_controllen = sizeof(control_un.control);
782 
783  cmptr = CMSG_FIRSTHDR(&msg);
784  cmptr->cmsg_len = CMSG_LEN(sizeof(int));
785  cmptr->cmsg_level = SOL_SOCKET;
786  cmptr->cmsg_type = SCM_RIGHTS;
787  *((int *) CMSG_DATA(cmptr)) = socket;
788 
789  msg.msg_name = NULL;
790  msg.msg_namelen = 0;
791 
792  iov[0].iov_base = (void*) "i";
793  iov[0].iov_len = 1;
794  msg.msg_iov = iov;
795  msg.msg_iovlen = 1;
796 
797  return sendmsg( writeFd, &msg, 0);
798 }
799 
800 int
802  // Create unique socket for each call to exec agent
803  char random_suffix[65]{};
804  get64RandomBytes(random_suffix);
805 
806  sockaddr_un tmp_socket_addr{};
807  char tmp_socket_file[sizeof(tmp_socket_addr.sun_path)]{};
808  snprintf(tmp_socket_file, sizeof(tmp_socket_file), "%s/irods_agent_%s", agent_factory_socket_dir, random_suffix);
809 
810  ssize_t status{send(agent_conn_socket, tmp_socket_file, strlen(tmp_socket_file), 0)};
811  if ( status < 0 ) {
812  rodsLog( LOG_ERROR, "Error sending socket to agent factory process, errno = [%d]: %s", errno, strerror( errno ) );
813  } else if ( static_cast<size_t>(status) < strlen( tmp_socket_file ) ) {
814  rodsLog( LOG_DEBUG, "Failed to send entire message - msg [%s] is [%d] bytes long, sent [%d] bytes", tmp_socket_file, strlen( tmp_socket_file ), status );
815  }
816 
817  tmp_socket_addr.sun_family = AF_UNIX;
818  strncpy(tmp_socket_addr.sun_path, tmp_socket_file, sizeof(tmp_socket_addr.sun_path));
819 
820  int tmp_socket{socket(AF_UNIX, SOCK_STREAM, 0)};
821  if ( tmp_socket < 0 ) {
822  rodsLog( LOG_ERROR, "Unable to create socket in execAgent, errno = [%d]: %s", errno, strerror( errno ) );
823  }
824 
825  const auto cleanup_sockets{[&]() {
826  if (close(tmp_socket) < 0) {
827  rodsLog(LOG_ERROR, "close(tmp_socket) failed with errno = [%d]: %s", errno, strerror(errno));
828  }
829  if (unlink(tmp_socket_file) < 0) {
830  rodsLog(LOG_ERROR, "unlink(tmp_socket_file) failed with errno = [%d]: %s", errno, strerror(errno));
831  }
832  }};
833 
834  // Wait until receiving acknowledgement that socket has been created
835  char in_buf[1024]{};
836  status = recv( agent_conn_socket, &in_buf, sizeof(in_buf), 0 );
837  if (status < 0) {
838  rodsLog(LOG_ERROR, "Error in recv acknowledgement from agent factory process, errno = [%d]: %s", errno, strerror(errno));
840  } else if (0 != strcmp(in_buf, "OK")) {
841  rodsLog(LOG_ERROR, "Bad acknowledgement from agent factory process, message = [%s]", in_buf);
843  }
844  else {
845  status = connect(tmp_socket, (const struct sockaddr*) &tmp_socket_addr, sizeof(local_addr));
846  if (status < 0) {
847  rodsLog(LOG_ERROR, "Unable to connect to socket in agent factory process, errno = [%d]: %s", errno, strerror(errno));
849  }
850  }
851 
852  if (status < 0) {
853  // Agent factory expects a message about connection to the agent - send failure
854  const std::string failure_message{"spawn_failure"};
855  send(agent_conn_socket, failure_message.c_str(), failure_message.length() + 1, 0);
856  cleanup_sockets();
857  return status;
858  }
859  else {
860  // Notify agent factory of success and send data to agent process
861  const std::string connection_successful{"connection_successful"};
862  send(agent_conn_socket, connection_successful.c_str(), connection_successful.length() + 1, 0);
863  }
864 
865  status = sendEnvironmentVarStrToSocket( SP_RE_CACHE_SALT,irods::get_server_property<const std::string>( irods::CFG_RE_CACHE_SALT_KW).c_str(), tmp_socket );
866  if (status < 0) {
867  rodsLog( LOG_ERROR, "Failed to send SP_RE_CACHE_SALT to agent" );
868  }
870  if (status < 0) {
871  rodsLog( LOG_ERROR, "Failed to send SP_CONNECT_CNT to agent" );
872  }
874  if (status < 0) {
875  rodsLog( LOG_ERROR, "Failed to send SP_PROXY_RODS_ZONE to agent" );
876  }
877  status = sendEnvironmentVarIntToSocket( SP_NEW_SOCK, newSock, tmp_socket );
878  if (status < 0) {
879  rodsLog( LOG_ERROR, "Failed to send SP_NEW_SOCK to agent" );
880  }
882  if (status < 0) {
883  rodsLog( LOG_ERROR, "Failed to send SP_PROTOCOL to agent" );
884  }
886  if (status < 0) {
887  rodsLog( LOG_ERROR, "Failed to send SP_RECONN_FLAG to agent" );
888  }
890  if (status < 0) {
891  rodsLog( LOG_ERROR, "Failed to send SP_PROXY_USER to agent" );
892  }
894  if (status < 0) {
895  rodsLog( LOG_ERROR, "Failed to send SP_CLIENT_USER to agent" );
896  }
898  if (status < 0) {
899  rodsLog( LOG_ERROR, "Failed to send SP_CLIENT_RODS_ZONE to agent" );
900  }
902  if (status < 0) {
903  rodsLog( LOG_ERROR, "Failed to send SP_REL_VERSION to agent" );
904  }
906  if (status < 0) {
907  rodsLog( LOG_ERROR, "Failed to send SP_API_VERSION to agent" );
908  }
909 
910  // =-=-=-=-=-=-=-
911  // if the client-server negotiation request is in the
912  // option variable, set that env var and strip it out
913  std::string opt_str( startupPack->option );
914  size_t pos = opt_str.find( REQ_SVR_NEG );
915  if ( std::string::npos != pos ) {
916  std::string trunc_str = opt_str.substr( 0, pos );
917  status = sendEnvironmentVarStrToSocket( SP_OPTION, trunc_str.c_str(), tmp_socket );
918  if (status < 0) {
919  rodsLog( LOG_ERROR, "Failed to send SP_OPTION to agent" );
920  }
922  if (status < 0) {
923  rodsLog( LOG_ERROR, "Failed to send irods::RODS_CS_NEG to agent" );
924  }
925 
926  }
927  else {
929  if (status < 0) {
930  rodsLog( LOG_ERROR, "Failed to send SP_OPTION to agent" );
931  }
932  }
933 
935  if (status < 0) {
936  rodsLog( LOG_ERROR, "Failed to send SERVER_BOOT_TIME to agent" );
937  }
938 
939  status = send( tmp_socket, "end_of_vars", 12, 0 );
940  if ( status <= 0 ) {
941  rodsLog( LOG_ERROR, "Failed to send \"end_of_vars;\" to agent" );
942  }
943 
944  status = recv( tmp_socket, &in_buf, sizeof(in_buf), 0 );
945  if ( status < 0 ) {
946  rodsLog( LOG_ERROR, "Error in recv acknowledgement from agent factory process, errno = [%d]: %s", errno, strerror( errno ) );
947  cleanup_sockets();
948  return SYS_SOCK_READ_ERR;
949  } else if ( strcmp(in_buf, "OK") != 0 ) {
950  rodsLog( LOG_ERROR, "Bad acknowledgement from agent factory process, message = [%s]", in_buf );
951  cleanup_sockets();
952  return SYS_SOCK_READ_ERR;
953  }
954  sendSocketOverSocket( tmp_socket, newSock );
955  status = recv( tmp_socket, &in_buf, sizeof(in_buf), 0 );
956  if ( status < 0 ) {
957  rodsLog( LOG_ERROR, "Error in recv child_pid from agent factory process, errno = [%d]: %s", errno, strerror( errno ) );
958  cleanup_sockets();
959  return SYS_SOCK_READ_ERR;
960  }
961 
962  cleanup_sockets();
963  return std::atoi(in_buf);
964 }
965 
966 int
967 queueConnectedAgentProc( int childPid, agentProc_t *connReq,
968  agentProc_t **agentProcHead ) {
969  if ( connReq == NULL ) {
970  return USER__NULL_INPUT_ERR;
971  }
972 
973  connReq->pid = childPid;
974 
975  boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
976 
977  queAgentProc( connReq, agentProcHead, TOP_POS );
978 
979  con_agent_lock.unlock();
980 
981  return 0;
982 }
983 
984 int
986  agentProc_t *tmpAgentProc;
987  int count = 0;
988 
989  boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
990 
991  tmpAgentProc = ConnectedAgentHead;
992  while ( tmpAgentProc != NULL ) {
993  count++;
994  tmpAgentProc = tmpAgentProc->next;
995  }
996  con_agent_lock.unlock();
997 
998  return count;
999 }
1000 
1002  std::vector<int>& _pids ) {
1003  agentProc_t *tmp_proc = 0;
1004  int count = 0;
1005 
1006  boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
1007 
1008  tmp_proc = ConnectedAgentHead;
1009  while ( tmp_proc != NULL ) {
1010  count++;
1011  _pids.push_back( tmp_proc->pid );
1012  tmp_proc = tmp_proc->next;
1013  }
1014  con_agent_lock.unlock();
1015 
1016  return count;
1017 
1018 } // getAgentProcPIDs
1019 
1020 int
1022  int maximum_connections;
1023  try {
1024  maximum_connections = irods::get_server_property<const int>("maximum_connections");
1025  } catch ( const irods::exception& e ) {
1026  if ( e.code() == KEY_NOT_FOUND ) {
1027  maximum_connections = NO_MAX_CONNECTION_LIMIT;
1028  } else {
1030  return e.code();
1031  }
1032  }
1033  if ( maximum_connections != NO_MAX_CONNECTION_LIMIT ) {
1034  int count = getAgentProcCnt();
1035  if ( count >= maximum_connections ) {
1037  count = getAgentProcCnt();
1038  if ( count >= maximum_connections ) {
1040  }
1041  }
1042  }
1043  return 0;
1044 }
1045 
1046 int
1048  agentProc_t *tmpAgentProc, *prevAgentProc, *unmatchedAgentProc;
1049  prevAgentProc = NULL;
1050 
1051  boost::unique_lock< boost::mutex > con_agent_lock( ConnectedAgentMutex );
1052  tmpAgentProc = ConnectedAgentHead;
1053 
1054  while ( tmpAgentProc != NULL ) {
1055  char procPath[MAX_NAME_LEN];
1056 
1057  snprintf( procPath, MAX_NAME_LEN, "%s/%-d", ProcLogDir,
1058  tmpAgentProc->pid );
1059  path p( procPath );
1060  if ( !exists( p ) ) {
1061  /* the agent proc is gone */
1062  unmatchedAgentProc = tmpAgentProc;
1063  rodsLog( LOG_DEBUG,
1064  "Agent process %d in Connected queue but not in ProcLogDir",
1065  tmpAgentProc->pid );
1066  if ( prevAgentProc == NULL ) {
1067  ConnectedAgentHead = tmpAgentProc->next;
1068  }
1069  else {
1070  prevAgentProc->next = tmpAgentProc->next;
1071  }
1072  tmpAgentProc = tmpAgentProc->next;
1073  free( unmatchedAgentProc );
1074  }
1075  else {
1076  prevAgentProc = tmpAgentProc;
1077  tmpAgentProc = tmpAgentProc->next;
1078  }
1079  }
1080  con_agent_lock.unlock();
1081 
1082  return 0;
1083 }
1084 
1085 int
1086 initServer( rsComm_t *svrComm ) {
1087  int status;
1089 
1090  status = initServerInfo( 0, svrComm );
1091  if ( status < 0 ) {
1093  "initServer: initServerInfo error, status = %d",
1094  status );
1095  return status;
1096  }
1097 
1098  // JMC - legacy resources - printLocalResc ();
1100 
1101  printZoneInfo();
1102 
1104 
1105  if ( status < 0 || NULL == rodsServerHost ) { // JMC cppcheck - nullptr
1106  return status;
1107  }
1108 
1109  std::string svc_role;
1110  irods::error ret = get_catalog_service_role(svc_role);
1111  if(!ret.ok()) {
1112  irods::log(PASS(ret));
1113  return ret.code();
1114  }
1115 
1116 
1117  if ( rodsServerHost->localFlag == LOCAL_HOST ) {
1118  if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) {
1119  disconnectRcat();
1120  }
1121  }
1122  else {
1123  if ( rodsServerHost->conn != NULL ) {
1126  }
1127  }
1128 
1129  if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) {
1130  purgeLockFileDir( 0 );
1131  }
1132 
1133  return status;
1134 }
1135 
1136 /* record the server process number and other information into
1137  a well-known file. If svrComm is Null and this has created a file
1138  before, just unlink the file. */
1139 int
1141  int myPid;
1142  FILE *fd;
1143  DIR *dirp;
1144  static char filePath[100] = "";
1145  char cwd[1000];
1146  char stateFile[] = "irodsServer";
1147  char *tmp;
1148  char *cp;
1149 
1150  if ( svrComm == NULL ) {
1151  if ( filePath[0] != '\0' ) {
1152  unlink( filePath );
1153  }
1154  return 0;
1155  }
1156  rodsEnv *myEnv = &( svrComm->myEnv );
1157 
1158  /* Use /usr/tmp if it exists, /tmp otherwise */
1159  dirp = opendir( "/usr/tmp" );
1160  if ( dirp != NULL ) {
1161  tmp = "/usr/tmp";
1162  ( void )closedir( dirp );
1163  }
1164  else {
1165  tmp = "/tmp";
1166  }
1167 
1168  sprintf( filePath, "%s/%s.%d", tmp, stateFile, myEnv->rodsPort );
1169 
1170  unlink( filePath );
1171 
1172  myPid = getpid();
1173  cp = getcwd( cwd, 1000 );
1174  if ( cp != NULL ) {
1175  fd = fopen( filePath, "w" );
1176  if ( fd != NULL ) {
1177  fprintf( fd, "%d %s\n", myPid, cwd );
1178  fclose( fd );
1179  int err_code = chmod( filePath, 0664 );
1180  if ( err_code != 0 ) {
1181  rodsLog( LOG_ERROR, "chmod failed in recordServerProcess on [%s] with error code %d", filePath, err_code );
1182  }
1183  }
1184  }
1185  return 0;
1186 }
1187 
1188 int
1190  memset( svrComm, 0, sizeof( *svrComm ) );
1191  int status = getRodsEnv( &svrComm->myEnv );
1192  if ( status < 0 ) {
1193  rodsLog( LOG_ERROR, "initServerMain: getRodsEnv error. status = %d",
1194  status );
1195  return status;
1196  }
1198 
1199  setRsCommFromRodsEnv( svrComm );
1200 
1201  status = initServer( svrComm );
1202 
1203  if ( status < 0 ) {
1204  rodsLog( LOG_ERROR, "initServerMain: initServer error. status = %d",
1205  status );
1206  exit( 1 );
1207  }
1208 
1209 
1210  int zone_port;
1211  try {
1212  zone_port = irods::get_server_property<const int>(irods::CFG_ZONE_PORT);
1213  } catch ( irods::exception& e ) {
1215  return e.code();
1216  }
1217  svrComm->sock = sockOpenForInConn(
1218  svrComm,
1219  &zone_port,
1220  NULL,
1221  SOCK_STREAM );
1222  if ( svrComm->sock < 0 ) {
1223  rodsLog( LOG_ERROR,
1224  "initServerMain: sockOpenForInConn error. status = %d",
1225  svrComm->sock );
1226  return svrComm->sock;
1227  }
1228 
1229  if ( listen( svrComm->sock, MAX_LISTEN_QUE ) < 0 ) {
1230  rodsLog( LOG_ERROR,
1231  "initServerMain: listen failed, errno: %d",
1232  errno );
1233  return SYS_SOCK_LISTEN_ERR;
1234  }
1235 
1237  "rodsServer Release version %s - API Version %s is up",
1238  RODS_REL_VERSION, RODS_API_VERSION );
1239 
1240  /* Record port, pid, and cwd into a well-known file */
1241  recordServerProcess( svrComm );
1242  /* start the irodsReServer */
1243  rodsServerHost_t *reServerHost = NULL;
1244  getReHost( &reServerHost );
1245  if ( reServerHost != NULL && reServerHost->localFlag == LOCAL_HOST ) {
1246  int re_pid = RODS_FORK();
1247  if ( re_pid == 0 ) { // child
1248 
1249  close( svrComm->sock );
1250  std::vector<char *> av;
1251  av.push_back( "irodsReServer" );
1252  av.push_back( NULL );
1253  rodsLog( LOG_NOTICE, "Starting irodsReServer" );
1254  execv( av[0], &av[0] );
1255  exit( 1 );
1256  }
1257  else {
1258  irods::set_server_property<int>( irods::RE_PID_KW, re_pid );
1259  }
1260  }
1261 
1262  rodsServerHost_t *xmsgServerHost = NULL;
1263  getXmsgHost( &xmsgServerHost );
1264  if ( xmsgServerHost != NULL && xmsgServerHost->localFlag == LOCAL_HOST ) {
1265  int xmsg_pid = RODS_FORK();
1266  if ( 0 == xmsg_pid ) { // child
1267  char *av[NAME_LEN];
1268 
1269  close( svrComm->sock );
1270  memset( av, 0, sizeof( av ) );
1271  rodsLog( LOG_NOTICE, "Starting irodsXmsgServer" );
1272  av[0] = "irodsXmsgServer";
1273  execv( av[0], av );
1274  exit( 1 );
1275  }
1276  else {
1277  irods::set_server_property<int>( irods::XMSG_PID_KW, xmsg_pid );
1278  }
1279 
1280  }
1281 
1282  return 0;
1283 }
1284 
1285 /* add incoming connection request to the bottom of the link list */
1286 
1287 int
1288 addConnReqToQue( rsComm_t *rsComm, int sock ) {
1289  agentProc_t *myConnReq;
1290 
1291  boost::unique_lock< boost::mutex > read_req_lock( ReadReqCondMutex );
1292  myConnReq = ( agentProc_t* )calloc( 1, sizeof( agentProc_t ) );
1293 
1294  myConnReq->sock = sock;
1295  myConnReq->remoteAddr = rsComm->remoteAddr;
1296  queAgentProc( myConnReq, &ConnReqHead, BOTTOM_POS );
1297 
1298  ReadReqCond.notify_all(); // NOTE:: check all vs one
1299  read_req_lock.unlock();
1300 
1301  return 0;
1302 }
1303 
1304 int
1306  return 0;
1307 }
1308 
1309 agentProc_t *
1311  agentProc_t *myConnReq = NULL;
1312 
1314  while ( irods::server_state::STOPPED != server_state() &&
1315  irods::server_state::EXITED != server_state() &&
1316  myConnReq == NULL ) {
1317  boost::unique_lock<boost::mutex> read_req_lock( ReadReqCondMutex );
1318  if ( ConnReqHead != NULL ) {
1319  myConnReq = ConnReqHead;
1321  read_req_lock.unlock();
1322  break;
1323  }
1324 
1325  ReadReqCond.wait( read_req_lock );
1326  if ( ConnReqHead == NULL ) {
1327  read_req_lock.unlock();
1328  continue;
1329  }
1330  else {
1331  myConnReq = ConnReqHead;
1333  read_req_lock.unlock();
1334  break;
1335  }
1336  }
1337 
1338  return myConnReq;
1339 }
1340 
1341 int
1344  for ( int i = 0; i < NUM_READ_WORKER_THR; i++ ) {
1345  try {
1346  ReadWorkerThread[i] = new boost::thread( readWorkerTask );
1347  }
1348  catch ( const boost::thread_resource_error& ) {
1349  rodsLog( LOG_ERROR, "boost encountered a thread_resource_error during thread construction in startProcConnReqThreads." );
1350  return SYS_THREAD_RESOURCE_ERR;
1351  }
1352  }
1353  try {
1354  SpawnManagerThread = new boost::thread( spawnManagerTask );
1355  }
1356  catch ( const boost::thread_resource_error& ) {
1357  rodsLog( LOG_ERROR, "boost encountered a thread_resource_error during thread construction in startProcConnReqThreads." );
1358  return SYS_THREAD_RESOURCE_ERR;
1359  }
1360 
1361  return 0;
1362 }
1363 
1364 void
1366 
1367  SpawnReqCond.notify_all();
1368  try {
1369  SpawnManagerThread->join();
1370  }
1371  catch ( const boost::thread_resource_error& ) {
1372  rodsLog( LOG_ERROR, "boost encountered a thread_resource_error during join in stopProcConnReqThreads." );
1373  }
1374 
1375  for ( int i = 0; i < NUM_READ_WORKER_THR; i++ ) {
1376  ReadReqCond.notify_all();
1377  try {
1378  ReadWorkerThread[i]->join();
1379  }
1380  catch ( const boost::thread_resource_error& ) {
1381  rodsLog( LOG_ERROR, "boost encountered a thread_resource_error during join in stopProcConnReqThreads." );
1382  }
1383  }
1384 }
1385 void
1387 
1388  // =-=-=-=-=-=-=-
1389  // artificially create a conn object in order to
1390  // create a network object. this is gratuitous
1391  // but necessary to maintain the consistent interface.
1392  rcComm_t tmp_comm;
1393  bzero( &tmp_comm, sizeof( rcComm_t ) );
1394 
1395  irods::network_object_ptr net_obj;
1396  irods::error ret = irods::network_factory( &tmp_comm, net_obj );
1397  if ( !ret.ok() || !net_obj.get() ) {
1398  irods::log( PASS( ret ) );
1399  return;
1400  }
1401 
1403  while ( irods::server_state::STOPPED != server_state() &&
1404  irods::server_state::EXITED != server_state() ) {
1405  agentProc_t *myConnReq = getConnReqFromQue();
1406  if ( myConnReq == NULL ) {
1407  /* someone else took care of it */
1408  continue;
1409  }
1410  int newSock = myConnReq->sock;
1411 
1412  // =-=-=-=-=-=-=-
1413  // repave the socket handle with the new socket
1414  // for this connection
1415  net_obj->socket_handle( newSock );
1416  startupPack_t *startupPack = nullptr;
1417  struct timeval tv;
1418  tv.tv_sec = READ_STARTUP_PACK_TOUT_SEC;
1419  tv.tv_usec = 0;
1420  irods::error ret = readStartupPack( net_obj, &startupPack, &tv );
1421 
1422  if ( !ret.ok() ) {
1423  rodsLog( LOG_ERROR, "readWorkerTask - readStartupPack failed. %d", ret.code() );
1424  sendVersion( net_obj, ret.code(), 0, NULL, 0 );
1425  boost::unique_lock<boost::mutex> bad_req_lock( BadReqMutex );
1426  queAgentProc( myConnReq, &BadReqHead, TOP_POS );
1427  bad_req_lock.unlock();
1428  mySockClose( newSock );
1429  }
1430  else if ( strcmp(startupPack->option, RODS_HEARTBEAT_T) == 0 ) {
1431  const char* heartbeat = RODS_HEARTBEAT_T;
1432  const int heartbeat_length = strlen(heartbeat);
1433  int bytes_to_send = heartbeat_length;
1434  while ( bytes_to_send ) {
1435  const int bytes_sent = send(newSock, &(heartbeat[heartbeat_length - bytes_to_send]), bytes_to_send, 0);
1436  const int errsav = errno;
1437  if ( bytes_sent > 0 ) {
1438  bytes_to_send -= bytes_sent;
1439  } else if ( errsav != EINTR ) {
1440  rodsLog(LOG_ERROR, "Socket error encountered during heartbeat; socket returned %s", strerror(errsav));
1441  break;
1442  }
1443  }
1444  mySockClose(newSock);
1445  free( myConnReq );
1446  free( startupPack );
1447  }
1449  sendVersion( net_obj, SYS_EXCEED_CONNECT_CNT, 0, NULL, 0 );
1450  mySockClose( newSock );
1451  free( myConnReq );
1452  free( startupPack );
1453  }
1454  else {
1455  if ( startupPack->clientUser[0] == '\0' ) {
1458  if ( status < 0 ) {
1459  sendVersion( net_obj, status, 0, NULL, 0 );
1460  mySockClose( newSock );
1461  free( myConnReq );
1462  continue;
1463  }
1464  }
1465 
1466  myConnReq->startupPack = *startupPack;
1467  free( startupPack );
1468 
1469  boost::unique_lock< boost::mutex > spwn_req_lock( SpawnReqCondMutex );
1470 
1471  queAgentProc( myConnReq, &SpawnReqHead, BOTTOM_POS );
1472 
1473  SpawnReqCond.notify_all(); // NOTE:: look into notify_one vs notify_all
1474 
1475  } // else
1476 
1477  } // while 1
1478 
1479 } // readWorkerTask
1480 
1481 void
1483  agentProc_t *mySpawnReq = NULL;
1484  int status;
1485  uint curTime;
1486  uint agentQueChkTime = 0;
1487 
1489  while ( irods::server_state::STOPPED != server_state() &&
1490  irods::server_state::EXITED != server_state() ) {
1491 
1492  boost::unique_lock<boost::mutex> spwn_req_lock( SpawnReqCondMutex );
1493  SpawnReqCond.wait( spwn_req_lock );
1494 
1495  while ( SpawnReqHead != NULL ) {
1496  mySpawnReq = SpawnReqHead;
1497  SpawnReqHead = mySpawnReq->next;
1498 
1499  spwn_req_lock.unlock();
1500  status = spawnAgent( mySpawnReq, &ConnectedAgentHead );
1501  close( mySpawnReq->sock );
1502 
1503  if ( status < 0 ) {
1505  "spawnAgent error for puser=%s and cuser=%s from %s, stat=%d",
1506  mySpawnReq->startupPack.proxyUser,
1507  mySpawnReq->startupPack.clientUser,
1508  inet_ntoa( mySpawnReq->remoteAddr.sin_addr ), status );
1509  free( mySpawnReq );
1510  }
1511  else {
1512  rodsLog( LOG_DEBUG,
1513  "Agent process %d started for puser=%s and cuser=%s from %s",
1514  mySpawnReq->pid, mySpawnReq->startupPack.proxyUser,
1515  mySpawnReq->startupPack.clientUser,
1516  inet_ntoa( mySpawnReq->remoteAddr.sin_addr ) );
1517  }
1518 
1519  spwn_req_lock.lock();
1520 
1521  }
1522 
1523  spwn_req_lock.unlock();
1524 
1525  curTime = time( 0 );
1526  if ( curTime > agentQueChkTime + AGENT_QUE_CHK_INT ) {
1527  agentQueChkTime = curTime;
1528  procBadReq();
1529  }
1530  }
1531 }
1532 
1533 int
1535  if ( connReq == NULL ) {
1536  return USER__NULL_INPUT_ERR;
1537  }
1538 
1539  int newSock = connReq->sock;
1540 
1541  // =-=-=-=-=-=-=-
1542  // artificially create a conn object in order to
1543  // create a network object. this is gratuitous
1544  // but necessary to maintain the consistent interface.
1545  rcComm_t tmp_comm;
1546  bzero( &tmp_comm, sizeof( rcComm_t ) );
1547 
1548  irods::network_object_ptr net_obj;
1549  irods::error ret = irods::network_factory( &tmp_comm, net_obj );
1550  if ( !ret.ok() ) {
1551  irods::log( PASS( ret ) );
1552  return -1;
1553  }
1554 
1555  net_obj->socket_handle( newSock );
1556 
1558  ret = readStartupPack( net_obj, &startupPack, NULL );
1559 
1560  if ( !ret.ok() ) {
1561  rodsLog( LOG_NOTICE, "readStartupPack error from %s, status = %d",
1562  inet_ntoa( connReq->remoteAddr.sin_addr ), ret.code() );
1563  sendVersion( net_obj, ret.code(), 0, NULL, 0 );
1564  mySockClose( newSock );
1565  return ret.code();
1566  }
1567 
1569  sendVersion( net_obj, SYS_EXCEED_CONNECT_CNT, 0, NULL, 0 );
1570  mySockClose( newSock );
1571  return SYS_EXCEED_CONNECT_CNT;
1572  }
1573 
1574  connReq->startupPack = *startupPack;
1575  free( startupPack );
1576 
1577  int status = spawnAgent( connReq, &ConnectedAgentHead );
1578 
1579  close( newSock );
1580 
1581  if ( status < 0 ) {
1583  "spawnAgent error for puser=%s and cuser=%s from %s, status = %d",
1584  connReq->startupPack.proxyUser, connReq->startupPack.clientUser,
1585  inet_ntoa( connReq->remoteAddr.sin_addr ), status );
1586  }
1587  else {
1588  rodsLog( LOG_DEBUG,
1589  "Agent process %d started for puser=%s and cuser=%s from %s",
1590  connReq->pid, connReq->startupPack.proxyUser,
1591  connReq->startupPack.clientUser,
1592  inet_ntoa( connReq->remoteAddr.sin_addr ) );
1593  }
1594  return status;
1595 }
1596 
1597 /* procBadReq - process bad request */
1598 int
1600  agentProc_t *tmpConnReq, *nextConnReq;
1601  /* just free them for now */
1602 
1603  boost::unique_lock< boost::mutex > bad_req_lock( BadReqMutex );
1604 
1605  tmpConnReq = BadReqHead;
1606  while ( tmpConnReq != NULL ) {
1607  nextConnReq = tmpConnReq->next;
1608  free( tmpConnReq );
1609  tmpConnReq = nextConnReq;
1610  }
1611  BadReqHead = NULL;
1612  bad_req_lock.unlock();
1613 
1614  return 0;
1615 }
1616 
1617 // =-=-=-=-=-=-=-
1618 // JMC - backport 4612
1619 void
1621  size_t wait_time_ms = 0;
1622  const size_t purge_time_ms = LOCK_FILE_PURGE_TIME * 1000; // s to ms
1623 
1625  while ( irods::server_state::STOPPED != server_state() &&
1626  irods::server_state::EXITED != server_state() ) {
1627  rodsSleep( 0, irods::SERVER_CONTROL_POLLING_TIME_MILLI_SEC * 1000 ); // second, microseconds
1629 
1630  if ( wait_time_ms >= purge_time_ms ) {
1631  wait_time_ms = 0;
1632  int status = purgeLockFileDir( 1 );
1633  if ( status < 0 ) {
1634  rodsLogError(
1635  LOG_ERROR,
1636  status,
1637  "purgeLockFileWorkerTask: purgeLockFileDir failed" );
1638  }
1639 
1640  } // if
1641 
1642  } // while
1643 
1644 } // purgeLockFileWorkerTask
1645 
1646 std::vector<std::string>
1647 setExecArg( const char *commandArgv ) {
1648 
1649  std::vector<std::string> arguments;
1650  if ( commandArgv != NULL ) {
1651  int len = 0;
1652  bool openQuote = false;
1653  const char* cur = commandArgv;
1654  for ( int i = 0; commandArgv[i] != '\0'; i++ ) {
1655  if ( commandArgv[i] == ' ' && !openQuote ) {
1656  if ( len > 0 ) { /* end of a argv */
1657  std::string( cur, len );
1658  arguments.push_back( std::string( cur, len ) );
1659  /* reset inx and pointer */
1660  cur = &commandArgv[i + 1];
1661  len = 0;
1662  }
1663  else { /* skip over blanks */
1664  cur = &commandArgv[i + 1];
1665  }
1666  }
1667  else if ( commandArgv[i] == '\'' || commandArgv[i] == '\"' ) {
1668  openQuote ^= true;
1669  if ( openQuote ) {
1670  /* skip the quote */
1671  cur = &commandArgv[i + 1];
1672  }
1673  }
1674  else {
1675  len ++;
1676  }
1677  }
1678  if ( len > 0 ) { /* handle the last argv */
1679  arguments.push_back( std::string( cur, len ) );
1680  }
1681  }
1682 
1683  return arguments;
1684 }
1685 // =-=-=-=-=-=-=-
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
ReadReqCondMutex
boost::mutex ReadReqCondMutex
Definition: rodsServer.cpp:72
rcComm_t
Definition: rcConnect.h:95
NULL
#define NULL
Definition: rodsDef.h:70
irods::get_server_property
T & get_server_property(const std::string &_prop)
Definition: irods_server_properties.hpp:118
rsComm_t
Definition: rcConnect.h:145
sendVersion
irods::error sendVersion(irods::network_object_ptr, int, int, char *, int)
Definition: sockComm.cpp:1168
rodsServerHost::localFlag
int localFlag
Definition: rodsConnect.h:68
irods::server_state::instance
static server_state & instance()
Definition: irods_server_state.cpp:18
PurgeLockFileThread
boost::thread * PurgeLockFileThread
Definition: rodsServer.cpp:70
SpawnReqCond
boost::condition_variable SpawnReqCond
Definition: rodsServer.cpp:75
irods::SERVER_CONTROL_POLLING_TIME_MILLI_SEC
static const size_t SERVER_CONTROL_POLLING_TIME_MILLI_SEC
Definition: irods_server_control_plane.hpp:35
rodsEnv::rodsPort
int rodsPort
Definition: getRodsEnv.h:11
irods.pypyodbc.connect
connect
Definition: pypyodbc.py:2689
serverMain
int serverMain(char *logDir)
Definition: rodsServer.cpp:421
getRodsEnv
int getRodsEnv(rodsEnv *myRodsEnv)
Definition: getRodsEnv.cpp:112
irods::buffer_crypt::array_t
std::vector< unsigned char > array_t
Definition: irods_buffer_encryption.hpp:30
irods_server_properties.hpp
chkLogfileName
int chkLogfileName(const char *logDir, const char *logFileName)
Definition: rsLog.cpp:88
RODS_HEARTBEAT_T
#define RODS_HEARTBEAT_T
Definition: rodsDef.h:224
RODS_FORK
#define RODS_FORK()
Definition: rodsDef.h:339
rodsServerHost::conn
rcComm_t * conn
Definition: rodsConnect.h:64
NO_MAX_CONNECTION_LIMIT
#define NO_MAX_CONNECTION_LIMIT
Definition: rodsConnect.h:13
irods::server_state::RUNNING
static const std::string RUNNING
Definition: irods_server_state.hpp:17
optarg
char * optarg
AGENT_PT
#define AGENT_PT
Definition: rodsDef.h:79
RE_CACHE_SALT_NUM_RANDOM_BYTES
#define RE_CACHE_SALT_NUM_RANDOM_BYTES
Definition: rodsServer.hpp:42
startupPack::clientRodsZone
char clientRodsZone[64]
Definition: rodsDef.h:241
uninstantiate_shared_memory_for_plugin
static bool uninstantiate_shared_memory_for_plugin(const std::unordered_map< std::string, boost::any > &_plugin_object)
Definition: rodsServer.cpp:365
SP_CLIENT_RODS_ZONE
#define SP_CLIENT_RODS_ZONE
Definition: rodsDef.h:260
PASS
#define PASS(prev_error_)
Definition: irods_error.hpp:118
resc_mgr
irods::resource_manager resc_mgr
Definition: irods_resource_manager.cpp:31
connected_to_agent
bool connected_to_agent
Definition: rodsServer.cpp:47
instantiate_shared_memory_for_plugin
static bool instantiate_shared_memory_for_plugin(const std::unordered_map< std::string, boost::any > &_plugin_object)
Definition: rodsServer.cpp:354
irods::resource_manager::print_local_resources
void print_local_resources()
Definition: irods_resource_manager.cpp:800
ConnectedAgentMutex
boost::mutex ConnectedAgentMutex
Definition: rodsServer.cpp:65
irods::RE_PID_KW
const std::string RE_PID_KW("rule_engine_process_id")
usage
void usage(char *prog)
Definition: rodsServer.cpp:653
rodsLogSqlReq
void rodsLogSqlReq(int onOrOff)
Definition: rodsLog.cpp:352
irods::server_control_plane
Definition: irods_server_control_plane.hpp:116
spawnAgent
int spawnAgent(agentProc_t *connReq, agentProc_t **agentProcHead)
Definition: rodsServer.cpp:723
locks.hpp
sockOpenForInConn
int sockOpenForInConn(rsComm_t *rsComm, int *portNum, char **addr, int proto)
Definition: sockComm.cpp:289
initAndClearProcLog
int initAndClearProcLog()
Definition: procLog.cpp:13
stopProcConnReqThreads
void stopProcConnReqThreads()
Definition: rodsServer.cpp:1365
irods_exception.hpp
rodsSleep
int rodsSleep(int sec, int microSec)
Definition: sockComm.cpp:1270
startupPack::relVersion
char relVersion[64]
Definition: rodsDef.h:242
LogFd
int LogFd
Definition: irods_server_globals.cpp:16
removeSharedMemory
int removeSharedMemory(const std::string &)
Definition: sharedmemory.cpp:57
agent_conn_socket
int agent_conn_socket
Definition: rodsServer.cpp:46
SpawnReqCondMutex
boost::mutex SpawnReqCondMutex
Definition: rodsServer.cpp:73
irods::experimental::administration::client::v1::exists
auto exists(rcComm_t &conn, const user &user) -> bool
Definition: user_administration.cpp:359
rcMisc.h
irods::CFG_PLUGIN_CONFIGURATION_KW
const std::string CFG_PLUGIN_CONFIGURATION_KW("plugin_configuration")
pid_age.p
p
Definition: pid_age.py:13
ConnectedAgentHead
agentProc_t * ConnectedAgentHead
Definition: rodsServer.cpp:57
SP_RE_CACHE_SALT
#define SP_RE_CACHE_SALT
Definition: rodsDef.h:266
irods::XMSG_PID_KW
const std::string XMSG_PID_KW("x_message_process_id")
SP_PROXY_USER
#define SP_PROXY_USER
Definition: rodsDef.h:257
SP_NEW_SOCK
#define SP_NEW_SOCK
Definition: rodsDef.h:252
LOCAL_HOST
#define LOCAL_HOST
Definition: rodsConnect.h:44
detachSharedMemory
void detachSharedMemory(const std::string &)
Definition: sharedmemory.cpp:52
SP_CONNECT_CNT
#define SP_CONNECT_CNT
Definition: rodsDef.h:254
irods::PLUGIN_TYPE_RULE_ENGINE
const std::string PLUGIN_TYPE_RULE_ENGINE("rule_engines")
prepareServerSharedMemory
unsigned char * prepareServerSharedMemory(const std::string &)
Definition: sharedmemory.cpp:14
rodsServer.hpp
resetMutex
void resetMutex(const char *)
Definition: locks.cpp:82
instantiate_shared_memory
static irods::error instantiate_shared_memory()
Definition: rodsServer.cpp:376
SpawnReqHead
agentProc_t * SpawnReqHead
Definition: rodsServer.cpp:59
socket_dir_template
const char socket_dir_template[]
Definition: rodsServer.cpp:50
execAgent
int execAgent(int newSock, startupPack_t *startupPack)
Definition: rodsServer.cpp:801
get64RandomBytes
int get64RandomBytes(char *buf)
Definition: rcMisc.cpp:1371
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
AGENT_QUE_CHK_INT
#define AGENT_QUE_CHK_INT
Definition: rodsServer.hpp:44
irods::server_state::PAUSED
static const std::string PAUSED
Definition: irods_server_state.hpp:18
irods::exception::code
int64_t code() const
Definition: irods_exception.hpp:39
sendEnvironmentVarStrToSocket
int sendEnvironmentVarStrToSocket(const char *var, const char *val, int socket)
Definition: rodsServer.cpp:756
uninstantiate_shared_memory
static irods::error uninstantiate_shared_memory()
Definition: rodsServer.cpp:398
ProcessType
int ProcessType
Definition: rcGlobal.cpp:16
irods_re_plugin.hpp
procSingleConnReq
int procSingleConnReq(agentProc_t *connReq)
Definition: rodsServer.cpp:1534
SYS_INTERNAL_ERR
@ SYS_INTERNAL_ERR
Definition: rodsErrorTable.h:211
loopCnt
int loopCnt
Definition: irodsXmsgServer.cpp:18
rsComm_t::myEnv
rodsEnv myEnv
Definition: rcConnect.h:154
disconnectRcat
int disconnectRcat()
Definition: rsIcatOpr.cpp:68
serverize
int serverize(char *logDir)
Definition: rodsServer.cpp:308
SP_OPTION
#define SP_OPTION
Definition: rodsDef.h:263
SYS_SOCK_CONNECT_ERR
@ SYS_SOCK_CONNECT_ERR
Definition: rodsErrorTable.h:219
LOCK_FILE_PURGE_TIME
#define LOCK_FILE_PURGE_TIME
Definition: rodsConnect.h:25
mySockClose
int mySockClose(int sock)
Definition: sockComm.cpp:1573
SpawnManagerThread
boost::thread * SpawnManagerThread
Definition: rodsServer.cpp:68
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
irods_network_factory.hpp
getAgentProcCnt
int getAgentProcCnt()
Definition: rodsServer.cpp:985
startupPack::clientUser
char clientUser[64]
Definition: rodsDef.h:240
rsGlobalExtern.hpp
queueConnectedAgentProc
int queueConnectedAgentProc(int childPid, agentProc_t *connReq, agentProc_t **agentProcHead)
Definition: rodsServer.cpp:967
LOGFILE_CHK_CNT
#define LOGFILE_CHK_CNT
Definition: rsLog.hpp:25
SYS_MAX_CONNECT_COUNT_EXCEEDED
@ SYS_MAX_CONNECT_COUNT_EXCEEDED
Definition: rodsErrorTable.h:183
irods::error::code
long long code() const
Definition: irods_error.cpp:194
startupPack::proxyRodsZone
char proxyRodsZone[64]
Definition: rodsDef.h:239
irods::network_factory
irods::error network_factory(rcComm_t *, irods::network_object_ptr &)
Definition: irods_network_factory.cpp:8
SYS_SOCK_READ_ERR
@ SYS_SOCK_READ_ERR
Definition: rodsErrorTable.h:181
irods::server_state::EXITED
static const std::string EXITED
Definition: irods_server_state.hpp:20
MAX_LISTEN_QUE
#define MAX_LISTEN_QUE
Definition: sockComm.h:15
LOG_DEBUG
#define LOG_DEBUG
Definition: rodsLog.h:23
getAgentProcPIDs
int getAgentProcPIDs(std::vector< int > &_pids)
Definition: rodsServer.cpp:1001
agentProc::next
struct agentProc * next
Definition: rodsConnect.h:34
main
int main(int argc, char **argv)
Definition: rodsServer.cpp:161
getReHost
int getReHost(rodsServerHost_t **rodsServerHost)
Definition: rodsConnect.cpp:972
irods::server_state::STOPPED
static const std::string STOPPED
Definition: irods_server_state.hpp:19
agentProc::pid
int pid
Definition: rodsConnect.h:30
READ_STARTUP_PACK_TOUT_SEC
#define READ_STARTUP_PACK_TOUT_SEC
Definition: sockComm.h:24
initConnThreadEnv
int initConnThreadEnv()
Definition: rodsServer.cpp:1305
sharedmemory.hpp
RODS_SERVER_LOGFILE
#define RODS_SERVER_LOGFILE
Definition: rsLog.hpp:12
initServerInfo
int initServerInfo(int processType, rsComm_t *rsComm)
Definition: initServer.cpp:57
SP_LOG_SQL
#define SP_LOG_SQL
Definition: rodsDef.h:264
procBadReq
int procBadReq()
Definition: rodsServer.cpp:1599
InformationRequiredToSafelyRenameProcess::argv0
char * argv0
Definition: initServer.hpp:17
irods::CFG_SERVICE_ROLE_PROVIDER
const std::string CFG_SERVICE_ROLE_PROVIDER("provider")
purgeLockFileDir
int purgeLockFileDir(int chkLockFlag)
Definition: initServer.cpp:1109
queAgentProc
int queAgentProc(agentProc_t *agentProc, agentProc_t **agentProcHead, irodsPosition_t position)
Definition: initServer.cpp:1079
irods::server_state
Definition: irods_server_state.hpp:11
ServerBootTime
uint ServerBootTime
Definition: rodsServer.cpp:54
SERVER_BOOT_TIME
#define SERVER_BOOT_TIME
Definition: rodsDef.h:267
rsComm_t::remoteAddr
struct sockaddr_in remoteAddr
Definition: rcConnect.h:150
SP_REL_VERSION
#define SP_REL_VERSION
Definition: rodsDef.h:261
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
SYS_EXCEED_CONNECT_CNT
@ SYS_EXCEED_CONNECT_CNT
Definition: rodsErrorTable.h:77
startupPack::reconnFlag
int reconnFlag
Definition: rodsDef.h:236
SYS_SOCK_LISTEN_ERR
@ SYS_SOCK_LISTEN_ERR
Definition: rodsErrorTable.h:69
recordServerProcess
int recordServerProcess(rsComm_t *svrComm)
Definition: rodsServer.cpp:1140
agent_spawning_pid
pid_t agent_spawning_pid
Definition: rodsServer.cpp:49
SYS_FORK_ERROR
@ SYS_FORK_ERROR
Definition: rodsErrorTable.h:116
INVALID_ANY_CAST
@ INVALID_ANY_CAST
Definition: rodsErrorTable.h:771
KEY_NOT_FOUND
@ KEY_NOT_FOUND
Definition: rodsErrorTable.h:749
InformationRequiredToSafelyRenameProcess
Definition: initServer.hpp:15
getXmsgHost
int getXmsgHost(rodsServerHost_t **rodsServerHost)
Definition: rodsConnect.cpp:991
SP_RECONN_FLAG
#define SP_RECONN_FLAG
Definition: rodsDef.h:256
runIrodsAgentFactory
int runIrodsAgentFactory(sockaddr_un agent_addr)
Definition: rodsAgent.cpp:188
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
spawnManagerTask
void spawnManagerTask()
Definition: rodsServer.cpp:1482
startupPack::proxyUser
char proxyUser[64]
Definition: rodsDef.h:238
BadReqMutex
boost::mutex BadReqMutex
Definition: rodsServer.cpp:66
printZoneInfo
int printZoneInfo()
Definition: rodsConnect.cpp:515
agentProc
Definition: rodsConnect.h:29
irods::log
void log(const error &)
Definition: irods_log.cpp:13
SP_PROTOCOL
#define SP_PROTOCOL
Definition: rodsDef.h:255
local_addr
Definition: rodsServer.cpp:45
addConnReqToQue
int addConnReqToQue(rsComm_t *rsComm, int sock)
Definition: rodsServer.cpp:1288
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
agent_factory_socket_dir
char agent_factory_socket_dir[sizeof(socket_dir_template)]
Definition: rodsServer.cpp:51
startupPack::apiVersion
char apiVersion[64]
Definition: rodsDef.h:243
getRcatHost
int getRcatHost(int rcatType, const char *rcatZoneHint, rodsServerHost_t **rodsServerHost)
Definition: rodsConnect.cpp:88
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
irods::error
Definition: irods_error.hpp:23
irods::global_re_plugin_mgr
Definition: irods_re_plugin.hpp:834
initServer
int initServer(rsComm_t *svrComm)
Definition: rodsServer.cpp:1086
startupPack::irodsProt
irodsProt_t irodsProt
Definition: rodsDef.h:235
miscServerFunct.hpp
agentProc::startupPack
startupPack_t startupPack
Definition: rodsConnect.h:32
int
typedef int((*funcPtr)())
chkAllowedUser
int chkAllowedUser(const char *userName, const char *rodsZone)
Definition: initServer.cpp:1008
purgeLockFileWorkerTask
void purgeLockFileWorkerTask()
Definition: rodsServer.cpp:1620
irods::buffer_crypt::generate_key
static irods::error generate_key(array_t &, int)
Definition: irods_buffer_encryption.cpp:98
rodsLogLevel
void rodsLogLevel(int level)
Definition: rodsLog.cpp:339
getLogfileName
void getLogfileName(char **logFile, const char *logDir, const char *logFileName)
Definition: rsLog.cpp:45
agent_factory_socket_file
char agent_factory_socket_file[sizeof(local_addr.sun_path)]
Definition: rodsServer.cpp:52
SP_CLIENT_USER
#define SP_CLIENT_USER
Definition: rodsDef.h:259
SP_LOG_LEVEL
#define SP_LOG_LEVEL
Definition: rodsDef.h:265
setRsCommFromRodsEnv
int setRsCommFromRodsEnv(rsComm_t *rsComm)
Definition: initServer.cpp:1060
ConnReqHead
agentProc_t * ConnReqHead
Definition: rodsServer.cpp:58
ReadWorkerThread
boost::thread * ReadWorkerThread[5]
Definition: rodsServer.cpp:67
rsAcceptConn
int rsAcceptConn(rsComm_t *svrComm)
Definition: sockComm.cpp:407
terminate_irods_processes.control
control
Definition: terminate_irods_processes.py:16
MASTER_RCAT
#define MASTER_RCAT
Definition: rodsDef.h:85
startupPack::option
char option[256]
Definition: rodsDef.h:244
irods::buffer_crypt::hex_encode
static irods::error hex_encode(const array_t &, std::string &)
Definition: irods_buffer_encryption.cpp:119
startupPack::connectCnt
int connectCnt
Definition: rodsDef.h:237
ProcLogDir
char ProcLogDir[(1024+64)]
Definition: irods_server_globals.cpp:18
readWorkerTask
void readWorkerTask()
Definition: rodsServer.cpp:1386
get_catalog_service_role
irods::error get_catalog_service_role(std::string &_role)
Definition: miscServerFunct.cpp:3153
rodsServerHost
Definition: rodsConnect.h:62
getAgentProcByPid
agentProc_t * getAgentProcByPid(int childPid, agentProc_t **agentProcHead)
Definition: rodsServer.cpp:695
procLog.h
irods::network_object_ptr
boost::shared_ptr< network_object > network_object_ptr
Definition: irods_network_object.hpp:78
SP_API_VERSION
#define SP_API_VERSION
Definition: rodsDef.h:262
rcDisconnect
int rcDisconnect(rcComm_t *conn)
Definition: rcConnect.cpp:246
error
int error
Definition: filesystem.cpp:101
MAX_SVR_SVR_CONNECT_CNT
#define MAX_SVR_SVR_CONNECT_CNT
Definition: rodsServer.hpp:34
irods_server_state.hpp
MAX_ACCEPT_ERR_CNT
#define MAX_ACCEPT_ERR_CNT
Definition: rodsServer.hpp:38
irods::RODS_CS_NEG
const char RODS_CS_NEG[]
Definition: irods_client_server_negotiation.hpp:24
InformationRequiredToSafelyRenameProcess::argv0_size
size_t argv0_size
Definition: initServer.hpp:18
rodsLogError
void rodsLogError(int level, int errCode, char *formatStr,...)
Definition: rodsLog.cpp:422
SYS_SETENV_ERR
@ SYS_SETENV_ERR
Definition: rodsErrorTable.h:209
SERVER_PT
#define SERVER_PT
Definition: rodsDef.h:78
sendEnvironmentVarIntToSocket
int sendEnvironmentVarIntToSocket(const char *var, int val, int socket)
Definition: rodsServer.cpp:743
setExecArg
std::vector< std::string > setExecArg(const char *commandArgv)
Definition: rodsServer.cpp:1647
startupPack
Definition: rodsDef.h:234
irods::SERVER_CONTROL_FWD_SLEEP_TIME_MILLI_SEC
static const size_t SERVER_CONTROL_FWD_SLEEP_TIME_MILLI_SEC
Definition: irods_server_control_plane.hpp:38
irods::CFG_SHARED_MEMORY_INSTANCE_KW
const std::string CFG_SHARED_MEMORY_INSTANCE_KW("shared_memory_instance")
irods::exception
Definition: irods_exception.hpp:15
SYS_ALREADY_INITIALIZED
@ SYS_ALREADY_INITIALIZED
Definition: rodsErrorTable.h:208
ReadReqCond
boost::condition_variable ReadReqCond
Definition: rodsServer.cpp:74
irods_server_control_plane.hpp
LOG_DEBUG10
#define LOG_DEBUG10
Definition: rodsLog.h:19
serverExit
void serverExit()
Definition: rodsServer.cpp:633
chkAgentProcCnt
int chkAgentProcCnt()
Definition: rodsServer.cpp:1021
initServer.hpp
irods::CFG_RE_CACHE_SALT_KW
const std::string CFG_RE_CACHE_SALT_KW("reCacheSalt")
REQ_SVR_NEG
#define REQ_SVR_NEG
Definition: rodsDef.h:272
irods_random.hpp
irods::CFG_SERVER_CONTROL_PLANE_PORT
const std::string CFG_SERVER_CONTROL_PLANE_PORT("server_control_plane_port")
agentProc::remoteAddr
struct sockaddr_in remoteAddr
Definition: rodsConnect.h:33
SP_PROXY_RODS_ZONE
#define SP_PROXY_RODS_ZONE
Definition: rodsDef.h:258
readStartupPack
irods::error readStartupPack(irods::network_object_ptr _ptr, startupPack_t **startupPack, struct timeval *tv)
Definition: miscServerFunct.cpp:2716
getConnReqFromQue
agentProc_t * getConnReqFromQue()
Definition: rodsServer.cpp:1310
chkConnectedAgentProcQue
int chkConnectedAgentProcQue()
Definition: rodsServer.cpp:1047
startProcConnReqThreads
int startProcConnReqThreads()
Definition: rodsServer.cpp:1342
procChildren
int procChildren(agentProc_t **agentProcHead)
Definition: rodsServer.cpp:663
initServerMain
int initServerMain(rsComm_t *svrComm)
Definition: rodsServer.cpp:1189
rodsEnv
Definition: getRodsEnv.h:8
NAME_LEN
#define NAME_LEN
Definition: rodsDef.h:55
irods::CFG_ZONE_PORT
const std::string CFG_ZONE_PORT("zone_port")
BadReqHead
agentProc_t * BadReqHead
Definition: rodsServer.cpp:60
sockCommNetworkInterface.hpp
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
buf
static char buf[64+50+1]
Definition: rsAuthRequest.cpp:21
SYS_THREAD_RESOURCE_ERR
@ SYS_THREAD_RESOURCE_ERR
Definition: rodsErrorTable.h:214
rsComm_t::sock
int sock
Definition: rcConnect.h:147
sendSocketOverSocket
ssize_t sendSocketOverSocket(int writeFd, int socket)
Definition: rodsServer.cpp:769
BOTTOM_POS
@ BOTTOM_POS
Definition: rodsDef.h:161
irods::exception::what
virtual const char * what() const
Definition: irods_exception.cpp:46
set_agent_spawner_process_name
static void set_agent_spawner_process_name(const InformationRequiredToSafelyRenameProcess &info)
Definition: rodsServer.cpp:152
irods::error::result
std::string result() const
Definition: irods_error.cpp:201
irods::re_plugin_globals
std::unique_ptr< struct irods::global_re_plugin_mgr > re_plugin_globals
Definition: irods_re_plugin.cpp:16
TOP_POS
@ TOP_POS
Definition: rodsDef.h:162
SvrSock
int SvrSock
Definition: rodsServer.cpp:55
agentProc::sock
int sock
Definition: rodsConnect.h:31
irods_client_server_negotiation.hpp
myPid
pid_t myPid
Definition: rodsLog.cpp:42
NUM_READ_WORKER_THR
#define NUM_READ_WORKER_THR
Definition: rodsServer.hpp:40
USER__NULL_INPUT_ERR
@ USER__NULL_INPUT_ERR
Definition: rodsErrorTable.h:247
irods::getRandomBytes
void getRandomBytes(void *buf, int bytes)
Definition: irods_random.cpp:6