static int virFDStreamUpdateCallback(virStreamPtr stream, int events)
{
    struct virFDStreamData *fdst = stream->privateData;
    int ret = -1;

    if (!fdst) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("stream is not open"));
        return -1;
    }

    virMutexLock(&fdst->lock);
    if (fdst->watch == 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("stream does not have a callback registered"));
        goto cleanup;
    }

    virEventUpdateHandle(fdst->watch, events);
    fdst->events = events;

    ret = 0;

 cleanup:
    virMutexUnlock(&fdst->lock);
    return ret;
}
Beispiel #2
0
static void
virConsoleEventOnStdout(int watch ATTRIBUTE_UNUSED,
                        int fd,
                        int events,
                        void *opaque)
{
    virConsolePtr con = opaque;

    virObjectLock(con);

    /* we got late event after console was shutdown */
    if (!con->st)
        goto cleanup;

    if (events & VIR_EVENT_HANDLE_WRITABLE &&
        con->streamToTerminal.offset) {
        ssize_t done;
        size_t avail;
        done = write(fd,
                     con->streamToTerminal.data,
                     con->streamToTerminal.offset);
        if (done < 0) {
            if (errno != EAGAIN) {
                virReportSystemError(errno, "%s", _("cannot write to stdout"));
                virConsoleShutdown(con);
            }
            goto cleanup;
        }
        memmove(con->streamToTerminal.data,
                con->streamToTerminal.data + done,
                con->streamToTerminal.offset - done);
        con->streamToTerminal.offset -= done;

        avail = con->streamToTerminal.length - con->streamToTerminal.offset;
        if (avail > 1024) {
            ignore_value(VIR_REALLOC_N(con->streamToTerminal.data,
                                       con->streamToTerminal.offset + 1024));
            con->streamToTerminal.length = con->streamToTerminal.offset + 1024;
        }
    }

    if (!con->streamToTerminal.offset)
        virEventUpdateHandle(con->stdoutWatch, 0);

    if (events & VIR_EVENT_HANDLE_ERROR) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("IO error stdout"));
        virConsoleShutdown(con);
        goto cleanup;
    }

    if (events & VIR_EVENT_HANDLE_HANGUP) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("EOF on stdout"));
        virConsoleShutdown(con);
        goto cleanup;
    }

 cleanup:
    virObjectUnlock(con);
}
Beispiel #3
0
static void lxcConsoleUpdateWatch(struct lxcConsole *console)
{
    int hostEvents = 0;
    int contEvents = 0;

    if (!console->hostClosed) {
        if (console->fromHostLen < sizeof(console->fromHostBuf))
            hostEvents |= VIR_EVENT_HANDLE_READABLE;
        if (console->fromContLen)
            hostEvents |= VIR_EVENT_HANDLE_WRITABLE;
    }
    if (!console->contClosed) {
        if (console->fromContLen < sizeof(console->fromContBuf))
            contEvents |= VIR_EVENT_HANDLE_READABLE;
        if (console->fromHostLen)
            contEvents |= VIR_EVENT_HANDLE_WRITABLE;
    }

    virEventUpdateHandle(console->contWatch, contEvents);
    virEventUpdateHandle(console->hostWatch, hostEvents);
}
static void qemuAgentUpdateWatch(qemuAgentPtr mon)
{
    int events =
        VIR_EVENT_HANDLE_HANGUP |
        VIR_EVENT_HANDLE_ERROR;

    if (mon->lastError.code == VIR_ERR_OK) {
        events |= VIR_EVENT_HANDLE_READABLE;

        if (mon->msg && mon->msg->txOffset < mon->msg->txLength)
            events |= VIR_EVENT_HANDLE_WRITABLE;
    }

    virEventUpdateHandle(mon->watch, events);
}
Beispiel #5
0
static void
virConsoleEventOnStdout(int watch ATTRIBUTE_UNUSED,
                        int fd,
                        int events,
                        void *opaque)
{
    virConsolePtr con = opaque;

    if (events & VIR_EVENT_HANDLE_WRITABLE &&
        con->streamToTerminal.offset) {
        ssize_t done;
        size_t avail;
        done = write(fd,
                     con->streamToTerminal.data,
                     con->streamToTerminal.offset);
        if (done < 0) {
            if (errno != EAGAIN) {
                virConsoleShutdown(con);
            }
            return;
        }
        memmove(con->streamToTerminal.data,
                con->streamToTerminal.data + done,
                con->streamToTerminal.offset - done);
        con->streamToTerminal.offset -= done;

        avail = con->streamToTerminal.length - con->streamToTerminal.offset;
        if (avail > 1024) {
            if (VIR_REALLOC_N(con->streamToTerminal.data,
                              con->streamToTerminal.offset + 1024) < 0)
            {}
            con->streamToTerminal.length = con->streamToTerminal.offset + 1024;
        }
    }

    if (!con->streamToTerminal.offset)
        virEventUpdateHandle(con->stdoutWatch, 0);

    if (events & VIR_EVENT_HANDLE_ERROR ||
        events & VIR_EVENT_HANDLE_HANGUP) {
        virConsoleShutdown(con);
    }
}
Beispiel #6
0
static void
virConsoleEventOnStream(virStreamPtr st,
                        int events, void *opaque)
{
    virConsolePtr con = opaque;

    virObjectLock(con);

    /* we got late event after console was shutdown */
    if (!con->st)
        goto cleanup;

    if (events & VIR_STREAM_EVENT_READABLE) {
        size_t avail = con->streamToTerminal.length -
            con->streamToTerminal.offset;
        int got;

        if (avail < 1024) {
            if (VIR_REALLOC_N(con->streamToTerminal.data,
                              con->streamToTerminal.length + 1024) < 0) {
                virConsoleShutdown(con);
                goto cleanup;
            }
            con->streamToTerminal.length += 1024;
            avail += 1024;
        }

        got = virStreamRecv(st,
                            con->streamToTerminal.data +
                            con->streamToTerminal.offset,
                            avail);
        if (got == -2)
            goto cleanup; /* blocking */
        if (got <= 0) {
            if (got == 0)
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("console stream EOF"));

            virConsoleShutdown(con);
            goto cleanup;
        }
        con->streamToTerminal.offset += got;
        if (con->streamToTerminal.offset)
            virEventUpdateHandle(con->stdoutWatch,
                                 VIR_EVENT_HANDLE_WRITABLE);
    }

    if (events & VIR_STREAM_EVENT_WRITABLE &&
        con->terminalToStream.offset) {
        ssize_t done;
        size_t avail;
        done = virStreamSend(con->st,
                             con->terminalToStream.data,
                             con->terminalToStream.offset);
        if (done == -2)
            goto cleanup; /* blocking */
        if (done < 0) {
            virConsoleShutdown(con);
            goto cleanup;
        }
        memmove(con->terminalToStream.data,
                con->terminalToStream.data + done,
                con->terminalToStream.offset - done);
        con->terminalToStream.offset -= done;

        avail = con->terminalToStream.length - con->terminalToStream.offset;
        if (avail > 1024) {
            ignore_value(VIR_REALLOC_N(con->terminalToStream.data,
                                       con->terminalToStream.offset + 1024));
            con->terminalToStream.length = con->terminalToStream.offset + 1024;
        }
    }
    if (!con->terminalToStream.offset)
        virStreamEventUpdateCallback(con->st,
                                     VIR_STREAM_EVENT_READABLE);

    if (events & VIR_STREAM_EVENT_ERROR ||
        events & VIR_STREAM_EVENT_HANGUP) {
        virConsoleShutdown(con);
    }

 cleanup:
    virObjectUnlock(con);
}
Beispiel #7
0
static void
virConsoleEventOnStream(virStreamPtr st,
                        int events, void *opaque)
{
    virConsolePtr con = opaque;

    if (events & VIR_STREAM_EVENT_READABLE) {
        size_t avail = con->streamToTerminal.length -
            con->streamToTerminal.offset;
        int got;

        if (avail < 1024) {
            if (VIR_REALLOC_N(con->streamToTerminal.data,
                              con->streamToTerminal.length + 1024) < 0) {
                virReportOOMError();
                virConsoleShutdown(con);
                return;
            }
            con->streamToTerminal.length += 1024;
            avail += 1024;
        }

        got = virStreamRecv(st,
                            con->streamToTerminal.data +
                            con->streamToTerminal.offset,
                            avail);
        if (got == -2)
            return; /* blocking */
        if (got <= 0) {
            virConsoleShutdown(con);
            return;
        }
        con->streamToTerminal.offset += got;
        if (con->streamToTerminal.offset)
            virEventUpdateHandle(con->stdoutWatch,
                                 VIR_EVENT_HANDLE_WRITABLE);
    }

    if (events & VIR_STREAM_EVENT_WRITABLE &&
        con->terminalToStream.offset) {
        ssize_t done;
        size_t avail;
        done = virStreamSend(con->st,
                             con->terminalToStream.data,
                             con->terminalToStream.offset);
        if (done == -2)
            return; /* blocking */
        if (done < 0) {
            virConsoleShutdown(con);
            return;
        }
        memmove(con->terminalToStream.data,
                con->terminalToStream.data + done,
                con->terminalToStream.offset - done);
        con->terminalToStream.offset -= done;

        avail = con->terminalToStream.length - con->terminalToStream.offset;
        if (avail > 1024) {
            if (VIR_REALLOC_N(con->terminalToStream.data,
                              con->terminalToStream.offset + 1024) < 0)
            {}
            con->terminalToStream.length = con->terminalToStream.offset + 1024;
        }
    }
    if (!con->terminalToStream.offset)
        virStreamEventUpdateCallback(con->st,
                                     VIR_STREAM_EVENT_READABLE);

    if (events & VIR_STREAM_EVENT_ERROR ||
        events & VIR_STREAM_EVENT_HANGUP) {
        virConsoleShutdown(con);
    }
}