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; }
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; /* * This must be done first, because it attempts to bind * to various UDP ports and we don't want anything else * potentially taking over those ports before we get a chance * to reserve them. */ if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS) restart_automounter_nodes(); /* * 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(); /* * Create the nfs service for amd * If nfs_port is already initialized, it means we * already created the service during restart_automounter_nodes(). */ if (nfs_port == 0) { ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2); if (ret != 0) return ret; } xsnprintf(pid_fsname, sizeof(pid_fsname), "%s:(pid%ld,port%u)", am_get_hostname(), (long) am_mypid, nfs_port); /* security: if user sets -D noamq, don't even create listening socket */ if (amuDebug(D_AMQ)) { ret = create_amq_service(&udp_soAMQ, &udp_amqp, &udp_amqncp, &tcp_soAMQ, &tcp_amqp, &tcp_amqncp, gopt.preferred_amq_port); 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 */ /* * 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; } if (amuDebug(D_AMQ)) { /* * Complete registration of amq (first TCP service then UDP) */ int tcp_ok = 0, udp_ok = 0; unregister_amq(); /* unregister leftover Amd, if any, just in case */ tcp_ok = amu_svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION, amq_program_1, IPPROTO_TCP, tcp_amqncp); if (!tcp_ok) plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%lu, AMQ_VERSION, tcp)", get_amd_program_number()); udp_ok = amu_svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION, amq_program_1, IPPROTO_UDP, udp_amqncp); if (!udp_ok) plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%lu, AMQ_VERSION, udp)", get_amd_program_number()); /* return error only if both failed */ if (!tcp_ok && !udp_ok) { amd_state = Done; return 3; } } /* * 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; }