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