Example #1
0
File: avail.c Project: npe9/sprite
/*-
 *-----------------------------------------------------------------------
 * Avail_Send --
 *	Send the availability of the local host.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	An availability packet is sent to the master.
 *
 *-----------------------------------------------------------------------
 */
Boolean
Avail_Send ()
{
    Avail   	  avail;
    static int	  sending = 0;	    /* XXX: A kludge to prevent endless
				     * recursion. At times, for no reason I've
				     * been able to determine, the avail event
				     * will be triggered during the call to
				     * CUSTOMS_AVAIL (hard to believe since
				     * the timeout for the avail event is
				     * twice as long as the total for the
				     * rpc, but...). Once it starts, it
				     * continues and the calls never seem to
				     * complete. To prevent this, we use a
				     * static flag and don't send anything
				     * if a call is already being sent. */
    if (sending) {
	return(FALSE);
    } else {
	sending = 1;
    }
    
    avail.addr =  	localAddr.sin_addr;
    avail.interval = 	availInterval;
    avail.avail = 	Avail_Local(AVAIL_EVERYTHING, &avail.rating);

    if (verbose) {
	printf ("Localhost %s available\n", avail.avail ? "not" : "is");
	fflush(stdout);
    }

    if (!Elect_InProgress() &&
	(Rpc_Call(udpSocket, &masterAddr, (Rpc_Proc)CUSTOMS_AVAIL,
		  sizeof(avail), (Rpc_Opaque)&avail,
		  0, (Rpc_Opaque)0,
		  CUSTOMSINT_NRETRY, &retryTimeOut) != RPC_SUCCESS)) {
		      Elect_GetMaster();
    }
    sending = 0;
    return (FALSE);
}
Example #2
0
int
start_remote_job (char **argv, char **envp, int stdin_fd,
                  int *is_remote, int *id_ptr, int *used_stdin)
{
  char waybill[MAX_DATA_SIZE], msg[128];
  struct hostent *host;
  struct timeval timeout;
  struct sockaddr_in sin;
  int len;
  int retsock, retport, sock;
  Rpc_Stat status;
  int pid;

  /* Create the return socket.  */
  retsock = Rpc_UdpCreate (True, 0);
  if (retsock < 0)
    {
      error (NILF, "exporting: Couldn't create return socket.");
      return 1;
    }

  /* Get the return socket's port number.  */
  len = sizeof (sin);
  if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0)
    {
      (void) close (retsock);
      perror_with_name ("exporting: ", "getsockname");
      return 1;
    }
  retport = sin.sin_port;

  /* Create the TCP socket for talking to the remote child.  */
  sock = Rpc_TcpCreate (False, 0);

  /* Create a WayBill to give to the server.  */
  len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv,
			     envp, retport, waybill);

  /* Modify the waybill as if the remote child had done 'child_access ()'.  */
  {
    WayBill *wb = (WayBill *) waybill;
    wb->ruid = wb->euid;
    wb->rgid = wb->egid;
  }

  /* Send the request to the server, timing out in 20 seconds.  */
  timeout.tv_usec = 0;
  timeout.tv_sec = 20;
  sin.sin_family = AF_INET;
  sin.sin_port = htons (Customs_Port ());
  sin.sin_addr = permit.addr;
  status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
		     len, (Rpc_Opaque) waybill,
		     sizeof(msg), (Rpc_Opaque) msg,
		     1, &timeout);

  host = gethostbyaddr((char *)&permit.addr, sizeof(permit.addr), AF_INET);

  if (status != RPC_SUCCESS)
    {
      (void) close (retsock);
      (void) close (sock);
      error (NILF, "exporting to %s: %s",
             host ? host->h_name : inet_ntoa (permit.addr),
             Rpc_ErrorMessage (status));
      return 1;
    }
  else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
    {
      (void) close (retsock);
      (void) close (sock);
      error (NILF, "exporting to %s: %s",
             host ? host->h_name : inet_ntoa (permit.addr),
             msg);
      return 1;
    }
  else
    {
      error (NILF, "*** exported to %s (id %u)",
	      host ? host->h_name : inet_ntoa (permit.addr),
	      permit.id);
    }

  fflush (stdout);
  fflush (stderr);

  pid = vfork ();
  if (pid < 0)
    {
      /* The fork failed!  */
      perror_with_name ("vfork", "");
      return 1;
    }
  else if (pid == 0)
    {
      /* Child side.  Run 'export' to handle the connection.  */
      static char sock_buf[20], retsock_buf[20], id_buf[20];
      static char *new_argv[6] =
	{ EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 };

      /* Set up the arguments.  */
      (void) sprintf (sock_buf, "%d", sock);
      (void) sprintf (retsock_buf, "%d", retsock);
      (void) sprintf (id_buf, "%x", permit.id);

      /* Get the right stdin.  */
      if (stdin_fd != 0)
	(void) dup2 (stdin_fd, 0);

      /* Unblock signals in the child.  */
      unblock_sigs ();

      /* Run the command.  */
      exec_command (new_argv, envp);
    }

  /* Parent side.  Return the 'export' process's ID.  */
  (void) close (retsock);
  (void) close (sock);
  *is_remote = 0;
  *id_ptr = pid;
  *used_stdin = 1;
  return 0;
}