Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
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;
}