Esempio n. 1
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();

  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;
}
Esempio n. 2
0
static enum clnt_stat
clntraw_call (CLIENT *h, u_long proc, xdrproc_t xargs, caddr_t argsp,
	      xdrproc_t xresults, caddr_t resultsp, struct timeval timeout)
{
  struct clntraw_private_s *clp = clntraw_private;
  XDR *xdrs = &clp->xdr_stream;
  struct rpc_msg msg;
  enum clnt_stat status;
  struct rpc_err error;

  if (clp == NULL)
    return RPC_FAILED;
call_again:
  /*
   * send request
   */
  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS (xdrs, 0);
  /* Just checking the union definition to access rm_xid is correct.  */
  if (offsetof (struct rpc_msg, rm_xid) != 0)
    abort ();
  clp->mashl_callmsg.rm_xid++;
  if ((!XDR_PUTBYTES (xdrs, clp->mashl_callmsg.msg, clp->mcnt)) ||
      (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
      (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
      (!(*xargs) (xdrs, argsp)))
    {
      return (RPC_CANTENCODEARGS);
    }
  (void) XDR_GETPOS (xdrs);	/* called just to cause overhead */

  /*
   * We have to call server input routine here because this is
   * all going on in one process. Yuk.
   */
  svc_getreq (1);

  /*
   * get results
   */
  xdrs->x_op = XDR_DECODE;
  XDR_SETPOS (xdrs, 0);
  msg.acpted_rply.ar_verf = _null_auth;
  msg.acpted_rply.ar_results.where = resultsp;
  msg.acpted_rply.ar_results.proc = xresults;
  if (!xdr_replymsg (xdrs, &msg))
    return RPC_CANTDECODERES;
  _seterr_reply (&msg, &error);
  status = error.re_status;

  if (status == RPC_SUCCESS)
    {
      if (!AUTH_VALIDATE (h->cl_auth, &msg.acpted_rply.ar_verf))
	{
	  status = RPC_AUTHERROR;
	}
    }				/* end successful completion */
  else
    {
      if (AUTH_REFRESH (h->cl_auth))
	goto call_again;
    }				/* end of unsuccessful completion */

  if (status == RPC_SUCCESS)
    {
      if (!AUTH_VALIDATE (h->cl_auth, &msg.acpted_rply.ar_verf))
	{
	  status = RPC_AUTHERROR;
	}
      if (msg.acpted_rply.ar_verf.oa_base != NULL)
	{
	  xdrs->x_op = XDR_FREE;
	  (void) xdr_opaque_auth (xdrs, &(msg.acpted_rply.ar_verf));
	}
    }

  return status;
}
Esempio n. 3
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;
}