crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs

runservice.c (3940B)


      1 /*************************************************************************
      2  * This file is part of Crosroads 1.23, a load balancer and fail over
      3  * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL.
      4  * Visit http://crossroads.e-tunity.com for information.
      5  *************************************************************************/
      6 #include "crossroads.h"
      7 
      8 void runservice () {
      9     int pid;
     10     int first_serving = 1;
     11 
     12     msg ("Service %s (on port %d): STARTING",
     13 	 activeservice->name, activeservice->port);
     14     
     15     /* Allocate the shared mem segment. */
     16     alloc_reporter(activeservice, 1);
     17 
     18     /* Load any allow- or deny filter files if appropriate. */
     19     if (ipf_loadfile (activeservice->allowfile, &(activeservice->allowchain),
     20 		      &(activeservice->nallowchain)))
     21 	error ("Error in allow file");
     22     if (ipf_loadfile (activeservice->denyfile, &(activeservice->denychain),
     23 		      &(activeservice->ndenychain)))
     24 	error ("Error in deny file");
     25     
     26     /* Go into the background. */
     27     if ( (pid = fork()) < 0 ) {
     28 	/* Fork failed */
     29 	error ("Service %s: fork failure: %s",
     30 	       activeservice->name, strerror(errno));
     31     } else if (pid) {
     32 	/* Parent branch */
     33 	msg ("Service %s: detached as PID %d",
     34 	     activeservice->name, pid);
     35 	return;
     36     }
     37     
     38     /* Child branch */
     39     set_program_title ("Service %s: listening", activeservice->name);
     40     close (0);
     41     close (1);
     42     close (2);
     43     daemonized++;
     44     if ( (open ("/dev/null", O_RDONLY) < 0) ||
     45 	 (open ("/dev/null", O_WRONLY) < 0) ||
     46 	 (open ("/dev/null", O_WRONLY) < 0) )
     47 	error ("Service %s: "
     48 	       "failed to reopen stdin/out/err on /dev/null",
     49 	       activeservice->name);
     50     if (setsid() < 0)
     51 	error ("Service %s: failed to become seesion leader",
     52 	       activeservice->name);
     53 	    
     54     /* Promote verbosity. */
     55     flag_verbose = activeservice->verbosity;
     56 	
     57     /* We've forked for the first time */
     58     program_stage = stage_waiting;
     59 
     60     /* In 'forever' mode, we create a server-side socket and ask tcpserve()
     61      * to service it. tcpserve() will return to us if there are no back
     62      * ends to service the request. In that case, we close the listening
     63      * socket (so that new clients get denied), take a nap, and redo.
     64      * Of course we only start listening if we have back ends at all...
     65      */
     66     while (1) {
     67 	if (backend_count()) {
     68 	    /* Create the socket, bind to port. */
     69 	    if ( (listen_sock = make_socket (activeservice->port,
     70 					     activeservice->bind)) < 0 ) {
     71 		if (!sloppyportbind)
     72 		    error ("Service %s: failed to listen to port %d: %s",
     73 			   activeservice->name, activeservice->port,
     74 			   strerror(errno));
     75 		warning ("Service %s: "
     76 			 "listening socket creation failed.. will retry",
     77 			 activeservice->name);
     78 
     79 		/* We wait here for some time, to let the system regain
     80 		 * equilibrium. Something's really afoot, so let's not retry
     81 		 * right away. */
     82 		sleep (SLEEP_TIME);
     83 		
     84 		continue;
     85 	    }
     86 	    msg ("Service %s: server-side network socket: %d",
     87 		 activeservice->name, listen_sock);
     88 	    
     89 	    /* Zero out the stats for first usage. */
     90 	    if (first_serving) {
     91 		first_serving = 0;
     92 		memset (servicereport, 0, sizeof(Servicereport));
     93 		/* Store our pid, so that 'crossroads stop' may kill us. */
     94 		lock_reporter();
     95 		servicereport->pid = getpid();
     96 		unlock_reporter();
     97 	    }
     98 	    
     99 	    /* Start serving the port! */
    100 	    tcpserve (listen_sock);
    101 	    
    102 	    /* tcpserve() returned -- must be because this service is out
    103 	     * of back ends */
    104 	    if (shutdown (listen_sock, SHUT_RDWR))
    105 		error ("Service %s: "
    106 		       "failed to shut down server-side socket %d: %s",
    107 		       activeservice->name, listen_sock, strerror(errno));
    108 	    if (close (listen_sock))
    109 		error ("Service %s: failed to close server-side socket %d: %s",
    110 		       activeservice->name, listen_sock, strerror(errno));
    111 	    
    112 	}
    113 	
    114 	msg ("Service %s: taking a nap...", activeservice->name);
    115 	sleep (SLEEP_TIME);
    116     }
    117 }