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