Beispiel #1
0
void
np_srv_remove_conn(Npsrv *srv, Npconn *conn)
{
	Npconn *c, **pc;

	pthread_mutex_lock(&srv->lock);
	pc = &srv->conns;
	c = *pc;
	while (c != NULL) {
		if (c == conn) {
			*pc = c->next;
			c->next = NULL;
			break;
		}

		pc = &c->next;
		c = *pc;
	}

	if (srv->connclose)
		(*srv->connclose)(conn);

	if (srv->shuttingdown && !srv->conns)
		np_srv_destroy(srv);

	pthread_mutex_unlock(&srv->lock);
}
Beispiel #2
0
Npsrv*
np_srv_create(int nwthread, int flags)
{
	Npsrv *srv = NULL;

	np_uerror (0);
	if (!(srv = malloc(sizeof(*srv)))) {
		np_uerror (ENOMEM);
		goto error;
	}
	memset (srv, 0, sizeof (*srv));
	pthread_mutex_init(&srv->lock, NULL);
	pthread_cond_init(&srv->conncountcond, NULL);

	srv->msize = 8216;
	srv->flags = flags;

	srv->netroot = np_net_make_root();
	if (srv->netroot == 0)
		goto error;

	if (np_usercache_create (srv) < 0)
		goto error;
	srv->nwthread = nwthread;
	if (!(srv->tpool = np_tpool_create (srv, "default")))
		goto error;
	np_tpool_incref (srv->tpool);
	np_assert_srv = srv;
	return srv;
error:
	if (srv)
		np_srv_destroy (srv);
	return NULL;
}
Beispiel #3
0
int
main (int argc, char *argv[])
{
    Npsrv *srv;
    Npconn *conn;
    Nptrans *trans;
    int flags = SRV_FLAGS_DEBUG_9PTRACE | SRV_FLAGS_DEBUG_USER;

    diod_log_init (argv[0]);
    diod_conf_init ();

    if (!(srv = np_srv_create (16, flags)))
        errn_exit (np_rerror (), "out of memory");
    srv->logmsg = diod_log_msg;

    srv->attach = myattach;
    srv->clunk = myclunk;

    /* create one connection */
    if (!(trans = ttrans_create ()))
        err_exit ("ttrans_create");
    if (!(conn = np_conn_create (srv, trans, "loopback")))
        msg_exit  ("np_conn_create failure");

    _send_tversion (trans);
    _send_tauth (trans);
    _send_tattach (trans, 0, 0);
    _send_tattach (trans, 0, 1);
    _send_tattach (trans, 1, 2);
    _send_tattach (trans, 1, 3);
    _send_tattach (trans, 0, 4);
    _send_tclunk (trans, 4);
    _send_tclunk (trans, 3);
    _send_tclunk (trans, 2);
    _send_tclunk (trans, 1);
    _send_tclunk (trans, 0);
    ttrans_rpc (trans, NULL, NULL); /* signifies EOF to reader */

    /* wait for exactly one connect/disconnect */
    np_srv_wait_conncount (srv, 1);
    sleep(1); /* racy here - conn reader needs time to process EOF */
    np_srv_destroy (srv);

    diod_conf_fini ();
    diod_log_fini ();
    exit (0);
}
Beispiel #4
0
Npsrv*
np_srv_create(int nwthread, int flags)
{
	Npsrv *srv = NULL;

	np_uerror (0);
	if (!(srv = malloc(sizeof(*srv)))) {
		np_uerror (ENOMEM);
		goto error;
	}
	memset (srv, 0, sizeof (*srv));
	pthread_mutex_init(&srv->lock, NULL);
	pthread_cond_init(&srv->conncountcond, NULL);

	srv->msize = 8216;
	srv->flags = flags;

	if (np_ctl_initialize (srv) < 0)
		goto error;
	if (!np_ctl_addfile (srv->ctlroot, "version", _ctl_get_version, NULL))
		goto error;
	if (!np_ctl_addfile (srv->ctlroot, "connections",
			     _ctl_get_connections, srv))
		goto error;
	if (!np_ctl_addfile (srv->ctlroot, "tpools", _ctl_get_tpools, srv))
		goto error;
	if (!np_ctl_addfile (srv->ctlroot, "requests", _ctl_get_requests, srv))
		goto error;
	if (!np_ctl_addfile_proc (srv->ctlroot, "meminfo"))
		goto error;
	if (!np_ctl_addfile_proc (srv->ctlroot, "net.rpc.nfs"))
		goto error;
	if (np_usercache_create (srv) < 0)
		goto error;
	srv->nwthread = nwthread;
	if (!(srv->tpool = np_tpool_create (srv, "default")))
		goto error;
	np_tpool_incref_nolock (srv->tpool);
	return srv;
error:
	if (srv)
		np_srv_destroy (srv);
	return NULL;
}
Beispiel #5
0
static void
_service_run (srvmode_t mode, int rfdno, int wfdno)
{
    List l = diod_conf_get_listen ();
    int nwthreads = diod_conf_get_nwthreads ();
    int flags = diod_conf_get_debuglevel ();
    uid_t euid = geteuid ();
    int n;

    ss.mode = mode;
    ss.rfdno = rfdno;
    ss.wfdno = wfdno;
    ss.shutdown = 0;
    ss.reload = 0;
    _service_sigsetup ();

    ss.fds = NULL;
    ss.nfds = 0;
    switch (mode) {
        case SRV_FILEDES:
            break;
        case SRV_NORMAL:
        case SRV_SOCKTEST:
            if (!diod_sock_listen (l, &ss.fds, &ss.nfds))
                msg_exit ("failed to set up listener");
#if WITH_RDMATRANS
            ss.rdma = diod_rdma_create ();
            diod_rdma_listen (ss.rdma);
#endif
            break;
    }

    /* manipulate squash/runas users if not root */
    if (euid != 0) {
        if (diod_conf_get_allsquash ()) {
            struct passwd *pw = getpwuid (euid);
            char *su = diod_conf_get_squashuser ();
            if (!pw)
                msg_exit ("getpwuid on effective uid failed");
            if (strcmp (pw->pw_name, su) != 0) {
                if (strcmp (su, DFLT_SQUASHUSER) != 0)
                    msg ("changing squashuser '%s' to '%s' "
                         "since you are not root", su, pw->pw_name);
                diod_conf_set_squashuser (pw->pw_name); /* fixes issue 41 */
            }
        } else { /* N.B. runasuser cannot be set in the config file */
            uid_t ruid = diod_conf_get_runasuid ();
            if (diod_conf_opt_runasuid () && ruid != euid)
                msg ("changing runasuid %d to %d "
                     "since you are not root", ruid, euid);
            diod_conf_set_runasuid (euid);
        }
    }
        
    if (!diod_conf_get_foreground () && mode != SRV_FILEDES)
        _daemonize (); /* implicit fork - no pthreads before this */
    if (!diod_conf_get_foreground () && mode != SRV_FILEDES)
        diod_log_set_dest (diod_conf_get_logdest ());

    /* drop root */
    if (euid == 0) {
        if (diod_conf_get_allsquash ())
            _become_user (diod_conf_get_squashuser (), -1, 1);
        else if (diod_conf_opt_runasuid ())
            _become_user (NULL, diod_conf_get_runasuid (), 1);
    }

    /* clear umask */
    umask (0);

    flags |= SRV_FLAGS_LOOSEFID;        /* work around buggy clients */
    flags |= SRV_FLAGS_AUTHCONN;
    //flags |= SRV_FLAGS_FLUSHSIG;      /* XXX temporarily off */
    if (geteuid () == 0) {
        flags |= SRV_FLAGS_SETFSID;
        flags |= SRV_FLAGS_DAC_BYPASS;
        if (_test_setgroups ())
            flags |= SRV_FLAGS_SETGROUPS;
        else
            msg ("test_setgroups: groups are per-process (disabling)");
    }

    /* Process dumpable flag may have been cleared by uid manipulation above.
     * Set it here, then maintain it in user.c::np_setfsid () as uids are
     * further manipulated.
     */
    if (prctl (PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
        err_exit ("prctl PR_SET_DUMPABLE failed");

    if (!diod_conf_get_userdb ())
        flags |= SRV_FLAGS_NOUSERDB;
    if (!(ss.srv = np_srv_create (nwthreads, flags))) /* starts threads */
        errn_exit (np_rerror (), "np_srv_create");
    if (diod_init (ss.srv) < 0)
        errn_exit (np_rerror (), "diod_init");

    if ((n = pthread_create (&ss.t, NULL, _service_loop, NULL)))
        errn_exit (n, "pthread_create _service_loop");
#if WITH_RDMATRANS
    if ((n = pthread_create (&ss.rdma_t, NULL, _service_loop_rdma, NULL)))
        errn_exit (n, "pthread_create _service_loop_rdma");
#endif
    switch (mode) {
        case SRV_FILEDES:
        case SRV_SOCKTEST:
            np_srv_wait_conncount (ss.srv, 1);
            pthread_kill (ss.t, SIGUSR1);
            break;
        case SRV_NORMAL:
            break;
    }
    if ((n = pthread_join (ss.t, NULL)))
        errn_exit (n, "pthread_join _service_loop");
#if WITH_RDMATRANS
    if ((n = pthread_join (ss.rdma_t, NULL)))
        errn_exit (n, "pthread_join _service_loop_rdma");
#endif

    diod_fini (ss.srv);
    np_srv_destroy (ss.srv);
}