/*- *----------------------------------------------------------------------- * 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); }
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; }