[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 28/31] libxl: provide libxl__openpty_*



On Tue, 2012-04-10 at 20:08 +0100, Ian Jackson wrote:
> General facility for ao operations to open ptys.
> 
> This will be used by the bootloader machinery.
> 
> Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
> ---
>  tools/libxl/libxl_aoutils.c  |  127 
> ++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_internal.h |   36 ++++++++++++
>  2 files changed, 163 insertions(+), 0 deletions(-)
> 
> diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c
> index c1229e4..b33abe4 100644
> --- a/tools/libxl/libxl_aoutils.c
> +++ b/tools/libxl/libxl_aoutils.c
[...]
> +int libxl__openptys(libxl__openpty_state *op,
> +                    const struct termios *termp,
> +                    const struct winsize *winp) {
> +    /*
> +     * This is completely crazy.

;-)

>   openpty calls grantpt which the spec
> +     * says may fork, and may not be called with a SIGCHLD handler.
> +     * Now our application may have a SIGCHLD handler so that's bad.
> +     * We could perhaps block it but we'd need to block it on all
> +     * threads.  This is just Too Hard.
> +     *
> +     * So instead, we run openpty in a child process.  That child
> +     * process then of course has only our own thread and our own
> +     * signal handlers.  We pass the fds back.
> +     *
> +     * Since our only current caller actually wants two ptys, we
> +     * support calling openpty multiple times for a single fork.
> +     */
> +    STATE_AO_GC(op);
> +    int count = op->count;
> +    int r, i, rc, sockets[2], ptyfds[count][2];
> +    libxl__carefd *for_child = 0;
> +    pid_t pid = -1;
> +
> +    for (i=0; i<count; i++) {
> +        ptyfds[i][0] = ptyfds[i][1] = -1;
> +        libxl__openpty_result *res = &op->results[i];
> +        assert(!res->master);
> +        assert(!res->slave);
> +    }
> +    sockets[0] = sockets[1] = -1; /* 0 is for us, 1 for our child */
> +
> +    libxl__carefd_begin();
> +    r = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
> +    if (r) { sockets[0] = sockets[1] = -1; }
> +    for_child = libxl__carefd_opened(CTX, sockets[1]);
> +    if (r) { LOGE(ERROR,"socketpair failed"); rc = ERROR_FAIL; goto out; }
> +
> +    pid = libxl__ev_child_fork(gc, &op->child, openpty_exited);
> +    if (pid == -1) {
> +        rc = ERROR_FAIL;
> +        goto out;
> +    }
> +
> +    if (!pid) {
> +        /* child */
> +        close(sockets[0]);
> +        signal(SIGCHLD, SIG_DFL);
> +
> +        for (i=0; i<count; i++) {
> +            r = openpty(&ptyfds[i][0], &ptyfds[i][1], NULL, termp, winp);
> +            if (r) { LOGE(ERROR,"openpty failed"); _exit(-1); }
> +        }
> +        rc = libxl__sendmsg_fds(gc, sockets[1], "",1,
> +                                2*count, &ptyfds[0][0], "ptys");
> +        if (rc) { LOGE(ERROR,"sendmsg to parent failed"); _exit(-1); }

Buried in this LOGE is a CTX somewhere, right? Is it valid to keep using
it? Perhaps it's OK just for this logging.

I suppose we don't need to call the postfork-noexecing handler because
we are inside libxl?

Ian.



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.