static void gp_socket_schedule_write(verto_ctx *vctx, struct gp_buffer *wbuf) { verto_ev *ev; ev = verto_add_io(vctx, VERTO_EV_FLAG_IO_WRITE, gp_socket_write, wbuf->conn->us.sd); if (!ev) { GPDEBUG("Failed to add io/write event!\n"); gp_conn_free(wbuf->conn); gp_buffer_free(wbuf); return; } verto_set_private(ev, wbuf, NULL); }
static void gp_socket_schedule_read(verto_ctx *vctx, struct gp_buffer *rbuf) { verto_ev *ev; ev = verto_add_io(vctx, VERTO_EV_FLAG_IO_READ, gp_socket_read, rbuf->conn->us.sd); if (!ev) { GPDEBUG("Failed to add io/read event!\n"); gp_conn_free(rbuf->conn); gp_buffer_free(rbuf); return; } verto_set_private(ev, rbuf, NULL); }
int main(int argc, const char *argv[]) { int opt; poptContext pc; int opt_daemon = 0; int opt_interactive = 0; int opt_version = 0; char *opt_config_file = NULL; int opt_debug = 0; verto_ctx *vctx; verto_ev *ev; int vflags; struct gssproxy_ctx *gpctx; struct gp_sock_ctx *sock_ctx; int wait_fd; int ret; int i; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \ _("Become a daemon (default)"), NULL }, \ {"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \ _("Run interactive (not a daemon)"), NULL}, \ {"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \ _("Specify a non-default config file"), NULL}, \ {"debug", 'd', POPT_ARG_NONE, &opt_debug, 0, \ _("Enable debugging"), NULL}, \ {"version", '\0', POPT_ARG_NONE, &opt_version, 0, \ _("Print version number and exit"), NULL }, \ POPT_TABLEEND }; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } if (opt_version) { puts(VERSION""DISTRO_VERSION""PRERELEASE_VERSION); return 0; } if (opt_debug) { gp_debug_enable(); } if (opt_daemon && opt_interactive) { fprintf(stderr, "Option -i|--interactive is not allowed together with -D|--daemon\n"); poptPrintUsage(pc, stderr, 0); return 1; } if (opt_interactive) { opt_daemon = 2; } gpctx = calloc(1, sizeof(struct gssproxy_ctx)); gpctx->config = read_config(opt_config_file, opt_daemon); if (!gpctx->config) { exit(EXIT_FAILURE); } init_server(gpctx->config->daemonize, &wait_fd); write_pid(); vctx = init_event_loop(); if (!vctx) { fprintf(stderr, "Failed to initialize event loop. " "Is there at least one libverto backend installed?\n"); return 1; } gpctx->vctx = vctx; /* init main socket */ sock_ctx = init_unix_socket(gpctx, gpctx->config->socket_name); if (!sock_ctx) { return 1; } vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ; ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd); if (!ev) { return 1; } verto_set_private(ev, sock_ctx, NULL); /* init secondary sockets */ for (i = 0; i < gpctx->config->num_svcs; i++) { if (gpctx->config->svcs[i]->socket != NULL) { sock_ctx = init_unix_socket(gpctx, gpctx->config->svcs[i]->socket); if (!sock_ctx) { return 1; } vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ; ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd); if (!ev) { return 1; } verto_set_private(ev, sock_ctx, NULL); } } /* We need to tell nfsd that GSS-Proxy is available before it starts, * as nfsd needs to know GSS-Proxy is in use before the first time it * needs to call accept_sec_context. */ init_proc_nfsd(gpctx->config); /* Now it is safe to tell the init system that we're done starting up, * so it can continue with dependencies and start nfsd */ init_done(wait_fd); ret = drop_privs(gpctx->config); if (ret) { exit(EXIT_FAILURE); } ret = gp_workers_init(gpctx); if (ret) { exit(EXIT_FAILURE); } verto_run(vctx); gp_workers_free(gpctx->workers); fini_server(); poptFreeContext(pc); free_config(&gpctx->config); return 0; }
int gp_workers_init(struct gssproxy_ctx *gpctx) { struct gp_workers *w; struct gp_thread *t; pthread_attr_t attr; verto_ev *ev; int vflags; int ret; int i; w = calloc(1, sizeof(struct gp_workers)); if (!w) { return ENOMEM; } w->gpctx = gpctx; /* init global queue mutex */ ret = pthread_mutex_init(&w->lock, NULL); if (ret) { free(w); return ENOMEM; } if (gpctx->config->num_workers > 0) { w->num_threads = gpctx->config->num_workers; } else { w->num_threads = DEFAULT_WORKER_THREADS_NUM; } /* make thread joinable (portability) */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* init all workers */ for (i = 0; i < w->num_threads; i++) { t = calloc(1, sizeof(struct gp_thread)); if (!t) { ret = -1; goto done; } t->pool = w; ret = pthread_cond_init(&t->cond_wakeup, NULL); if (ret) { free(t); goto done; } ret = pthread_mutex_init(&t->cond_mutex, NULL); if (ret) { free(t); goto done; } ret = pthread_create(&t->tid, &attr, gp_worker_main, t); if (ret) { free(t); goto done; } LIST_ADD(w->free_list, t); } /* add wakeup pipe, so that threads can hand back replies to the * dispatcher */ ret = pipe2(w->sig_pipe, O_NONBLOCK | O_CLOEXEC); if (ret == -1) { goto done; } vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ; ev = verto_add_io(gpctx->vctx, vflags, gp_handle_reply, w->sig_pipe[0]); if (!ev) { ret = -1; goto done; } verto_set_private(ev, w, NULL); gpctx->workers = w; ret = 0; done: if (ret) { gp_workers_free(w); } return ret; }