static serv_state run_rpc(void) { #ifdef HAVE_SIGACTION sigset_t smask; sigprocmask(SIG_BLOCK, &masked_sigs, &smask); #else /* not HAVE_SIGACTION */ int smask = sigblock(MASKED_SIGS); #endif /* not HAVE_SIGACTION */ next_softclock = clocktime(); amd_state = Run; /* * Keep on trucking while we are in Run mode. This state * is switched to Quit after all the file systems have * been unmounted. */ while ((int) amd_state <= (int) Finishing) { struct timeval tvv; int nsel; time_t now; #ifdef HAVE_SVC_GETREQSET fd_set readfds; memmove(&readfds, &svc_fdset, sizeof(svc_fdset)); FD_SET(fwd_sock, &readfds); #else /* not HAVE_SVC_GETREQSET */ # ifdef FD_SET fd_set readfds; FD_ZERO(&readfds); readfds.fds_bits[0] = svc_fds; FD_SET(fwd_sock, &readfds); # else /* not FD_SET */ int readfds = svc_fds | (1 << fwd_sock); # endif /* not FD_SET */ #endif /* not HAVE_SVC_GETREQSET */ checkup(); /* * If the full timeout code is not called, * then recompute the time delta manually. */ now = clocktime(); if (next_softclock <= now) { if (amd_state == Finishing) umount_exported(); tvv.tv_sec = softclock(); } else { tvv.tv_sec = next_softclock - now; } tvv.tv_usec = 0; if (amd_state == Finishing && last_used_map < 0) { flush_mntfs(); amd_state = Quit; break; } #ifdef HAVE_FS_AUTOFS autofs_add_fdset(&readfds); #endif /* HAVE_FS_AUTOFS */ if (tvv.tv_sec <= 0) tvv.tv_sec = SELECT_MAXWAIT; if (tvv.tv_sec) { dlog("Select waits for %ds", (int) tvv.tv_sec); } else { dlog("Select waits for Godot"); } nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv); switch (nsel) { case -1: if (errno == EINTR) { dlog("select interrupted"); continue; } plog(XLOG_ERROR, "select: %m"); break; case 0: break; default: /* * Read all pending NFS responses at once to avoid having responses * queue up as a consequence of retransmissions. */ #ifdef FD_SET if (FD_ISSET(fwd_sock, &readfds)) { FD_CLR(fwd_sock, &readfds); #else /* not FD_SET */ if (readfds & (1 << fwd_sock)) { readfds &= ~(1 << fwd_sock); #endif /* not FD_SET */ --nsel; do { fwd_reply(); } while (rpc_pending_now() > 0); } #ifdef HAVE_FS_AUTOFS if (nsel) nsel = autofs_handle_fdset(&readfds, nsel); #endif /* HAVE_FS_AUTOFS */ if (nsel) { /* * Anything left must be a normal * RPC request. */ #ifdef HAVE_SVC_GETREQSET svc_getreqset(&readfds); #else /* not HAVE_SVC_GETREQSET */ # ifdef FD_SET svc_getreq(readfds.fds_bits[0]); # else /* not FD_SET */ svc_getreq(readfds); # endif /* not FD_SET */ #endif /* not HAVE_SVC_GETREQSET */ } break; } } #ifdef HAVE_SIGACTION sigprocmask(SIG_SETMASK, &smask, NULL); #else /* not HAVE_SIGACTION */ (void) sigsetmask(smask); #endif /* not HAVE_SIGACTION */ if (amd_state == Quit) amd_state = Done; return amd_state; } int mount_automounter(int ppid) { /* * Old code replaced by rpc-trash patch. * Erez Zadok <*****@*****.**> int so = socket(AF_INET, SOCK_DGRAM, 0); */ SVCXPRT *udp_amqp = NULL, *tcp_amqp = NULL; int nmount, ret; int soNFS; int udp_soAMQ, tcp_soAMQ; struct netconfig *udp_amqncp, *tcp_amqncp; /* * Create the nfs service for amd */ ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2); if (ret != 0) return ret; /* security: if user sets -D noamq, don't even create listening socket */ amuDebug(D_AMQ) { ret = create_amq_service(&udp_soAMQ, &udp_amqp, &udp_amqncp, &tcp_soAMQ, &tcp_amqp, &tcp_amqncp); if (ret != 0) return ret; } #ifdef HAVE_FS_AUTOFS if (amd_use_autofs) { /* * Create the autofs service for amd. */ ret = create_autofs_service(); /* if autofs service fails it is OK if using a test amd */ if (ret != 0) { plog(XLOG_WARNING, "autofs service registration failed, turning off autofs support"); amd_use_autofs = 0; } } #endif /* HAVE_FS_AUTOFS */ /* * Start RPC forwarding */ if (fwd_init() != 0) return 3; /* * Construct the root automount node */ make_root_node(); /* * Pick up the pieces from a previous run * This is likely to (indirectly) need the rpc_fwd package * so it *must* come after the call to fwd_init(). */ if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS) restart(); /* * Mount the top-level auto-mountpoints */ nmount = mount_exported(); /* * Now safe to tell parent that we are up and running */ if (ppid) kill(ppid, SIGQUIT); if (nmount == 0) { plog(XLOG_FATAL, "No work to do - quitting"); amd_state = Done; return 0; } #ifdef DEBUG amuDebug(D_AMQ) #endif /* DEBUG */ { /* * Complete registration of amq (first TCP service then UDP) */ unregister_amq(); ret = amu_svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION, amq_program_1, IPPROTO_TCP, tcp_amqncp); if (ret != 1) { plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, tcp)", get_amd_program_number()); return 3; } ret = amu_svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION, amq_program_1, IPPROTO_UDP, udp_amqncp); if (ret != 1) { plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, udp)", get_amd_program_number()); return 4; } } /* * Start timeout_mp rolling */ reschedule_timeout_mp(); /* * Start the server */ if (run_rpc() != Done) { plog(XLOG_FATAL, "run_rpc failed"); amd_state = Done; } return 0; }
static serv_state run_rpc(void) { #ifdef HAVE_SIGACTION sigset_t smask; sigprocmask(SIG_BLOCK, &masked_sigs, &smask); #else /* not HAVE_SIGACTION */ int smask = sigblock(MASKED_SIGS); #endif /* not HAVE_SIGACTION */ next_softclock = clocktime(NULL); amd_state = Run; /* * Keep on trucking while we are in Run mode. This state * is switched to Quit after all the file systems have * been unmounted. */ while ((int) amd_state <= (int) Finishing) { struct timeval tvv; int nsel; time_t now; fd_set readfds; #ifdef HAVE_SVC_GETREQSET memmove(&readfds, &svc_fdset, sizeof(svc_fdset)); #else /* not HAVE_SVC_GETREQSET */ FD_ZERO(&readfds); # ifdef HAVE_FD_SET_FDS_BITS readfds.fds_bits[0] = svc_fds; # else /* not HAVE_FD_SET_FDS_BITS */ readfds = svc_fds; # endif /* not HAVE_FD_SET_FDS_BITS */ #endif /* not HAVE_SVC_GETREQSET */ FD_SET(fwd_sock, &readfds); checkup(); /* * If the full timeout code is not called, * then recompute the time delta manually. */ now = clocktime(NULL); if (next_softclock <= now) { if (amd_state == Finishing) umount_exported(); tvv.tv_sec = softclock(); } else { tvv.tv_sec = next_softclock - now; } tvv.tv_usec = 0; if (amd_state == Finishing && get_exported_ap(0) == NULL) { flush_mntfs(); amd_state = Quit; break; } #ifdef HAVE_FS_AUTOFS autofs_add_fdset(&readfds); #endif /* HAVE_FS_AUTOFS */ if (tvv.tv_sec <= 0) tvv.tv_sec = SELECT_MAXWAIT; if (tvv.tv_sec) { dlog("Select waits for %ds", (int) tvv.tv_sec); } else { dlog("Select waits for Godot"); } nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv); switch (nsel) { case -1: if (errno == EINTR) { dlog("select interrupted"); continue; } plog(XLOG_ERROR, "select: %m"); break; case 0: break; default: /* * Read all pending NFS responses at once to avoid having responses * queue up as a consequence of retransmissions. */ if (FD_ISSET(fwd_sock, &readfds)) { FD_CLR(fwd_sock, &readfds); --nsel; do { fwd_reply(); } while (rpc_pending_now() > 0); } #ifdef HAVE_FS_AUTOFS if (nsel) nsel = autofs_handle_fdset(&readfds, nsel); #endif /* HAVE_FS_AUTOFS */ if (nsel) { /* * Anything left must be a normal * RPC request. */ #ifdef HAVE_SVC_GETREQSET svc_getreqset(&readfds); #else /* not HAVE_SVC_GETREQSET */ # ifdef HAVE_FD_SET_FDS_BITS svc_getreq(readfds.fds_bits[0]); # else /* not HAVE_FD_SET_FDS_BITS */ svc_getreq(readfds); # endif /* not HAVE_FD_SET_FDS_BITS */ #endif /* not HAVE_SVC_GETREQSET */ } break; } } #ifdef HAVE_SIGACTION sigprocmask(SIG_SETMASK, &smask, NULL); #else /* not HAVE_SIGACTION */ (void) sigsetmask(smask); #endif /* not HAVE_SIGACTION */ if (amd_state == Quit) amd_state = Done; return amd_state; }