diff --git a/.gitignore b/.gitignore index 6e91d66..55e6af8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,3 @@ i686 x86_64 libvirt-*.tar.gz -/libvirt-0.8.4.tar.gz -/libvirt-0.8.5.tar.gz -/libvirt-0.8.7.tar.gz diff --git a/libvirt-0.9.9-lxc-io.patch b/libvirt-0.9.9-lxc-io.patch deleted file mode 100644 index e91957a..0000000 --- a/libvirt-0.9.9-lxc-io.patch +++ /dev/null @@ -1,345 +0,0 @@ -commit 9130396214975ba2251082f943c9717281039050 -Author: Daniel P. Berrange -Date: Thu Jan 12 17:03:03 2012 +0000 - - Re-write LXC controller end-of-file I/O handling yet again - - Currently the LXC controller attempts to deal with EOF on a - tty by spawning a thread to do an edge triggered epoll_wait(). - This avoids the normal event loop spinning on POLLHUP. There - is a subtle mistake though - even after seeing POLLHUP on a - master PTY, it is still perfectly possible & valid to write - data to the PTY. There is a buffer that can be filled with - data, even when no client is present. - - The second mistake is that the epoll_wait() thread was not - looking for the EPOLLOUT condition, so when a new client - connects to the LXC console, it had to explicitly send a - character before any queued output would appear. - - Finally, there was in fact no need to spawn a new thread to - deal with epoll_wait(). The epoll file descriptor itself - can be poll()'d on normally. - - This patch attempts to deal with all these problems. - - - The blocking epoll_wait() thread is replaced by a poll - on the epoll file descriptor which then does a non-blocking - epoll_wait() to handle events - - Even if POLLHUP is seen, we continue trying to write - any pending output until getting EAGAIN from write. - - Once write returns EAGAIN, we modify the epoll event - mask to also look for EPOLLOUT - - * src/lxc/lxc_controller.c: Avoid stalled I/O upon - connected to an LXC console - -diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c -index bb936ee..49727dd 100644 ---- a/src/lxc/lxc_controller.c -+++ b/src/lxc/lxc_controller.c -@@ -736,9 +736,17 @@ struct lxcConsole { - int hostWatch; - int hostFd; /* PTY FD in the host OS */ - bool hostClosed; -+ int hostEpoll; -+ bool hostBlocking; -+ - int contWatch; - int contFd; /* PTY FD in the container */ - bool contClosed; -+ int contEpoll; -+ bool contBlocking; -+ -+ int epollWatch; -+ int epollFd; /* epoll FD for dealing with EOF */ - - size_t fromHostLen; - char fromHostBuf[1024]; -@@ -834,102 +842,148 @@ static void lxcConsoleUpdateWatch(struct lxcConsole *console) - int hostEvents = 0; - int contEvents = 0; - -- if (!console->hostClosed) { -+ if (!console->hostClosed || (!console->hostBlocking && console->fromContLen)) { - if (console->fromHostLen < sizeof(console->fromHostBuf)) - hostEvents |= VIR_EVENT_HANDLE_READABLE; - if (console->fromContLen) - hostEvents |= VIR_EVENT_HANDLE_WRITABLE; - } -- if (!console->contClosed) { -+ if (!console->contClosed || (!console->contBlocking && console->fromHostLen)) { - if (console->fromContLen < sizeof(console->fromContBuf)) - contEvents |= VIR_EVENT_HANDLE_READABLE; - if (console->fromHostLen) - contEvents |= VIR_EVENT_HANDLE_WRITABLE; - } - -+ VIR_DEBUG("Container watch %d=%d host watch %d=%d", -+ console->contWatch, contEvents, -+ console->hostWatch, hostEvents); - virEventUpdateHandle(console->contWatch, contEvents); - virEventUpdateHandle(console->hostWatch, hostEvents); --} - -+ if (console->hostClosed) { -+ int events = EPOLLIN | EPOLLET; -+ if (console->hostBlocking) -+ events |= EPOLLOUT; - --struct lxcConsoleEOFData { -- struct lxcConsole *console; -- int fd; --}; -- -+ if (events != console->hostEpoll) { -+ struct epoll_event event; -+ int action = EPOLL_CTL_ADD; -+ if (console->hostEpoll) -+ action = EPOLL_CTL_MOD; - --static void lxcConsoleEOFThread(void *opaque) --{ -- struct lxcConsoleEOFData *data = opaque; -- int ret; -- int epollfd = -1; -- struct epoll_event event; -+ VIR_DEBUG("newHostEvents=%x oldHostEvents=%x", events, console->hostEpoll); - -- if ((epollfd = epoll_create(2)) < 0) { -- virReportSystemError(errno, "%s", -- _("Unable to create epoll fd")); -- goto cleanup; -+ event.events = events; -+ event.data.fd = console->hostFd; -+ if (epoll_ctl(console->epollFd, action, console->hostFd, &event) < 0) { -+ VIR_DEBUG(":fail"); -+ virReportSystemError(errno, "%s", -+ _("Unable to add epoll fd")); -+ quit = true; -+ goto cleanup; -+ } -+ console->hostEpoll = events; -+ VIR_DEBUG("newHostEvents=%x oldHostEvents=%x", events, console->hostEpoll); -+ } -+ } else if (console->hostEpoll) { -+ VIR_DEBUG("Stop epoll oldContEvents=%x", console->hostEpoll); -+ if (epoll_ctl(console->epollFd, EPOLL_CTL_DEL, console->hostFd, NULL) < 0) { -+ virReportSystemError(errno, "%s", -+ _("Unable to remove epoll fd")); -+ VIR_DEBUG(":fail"); -+ quit = true; -+ goto cleanup; -+ } -+ console->hostEpoll = 0; - } - -- event.events = EPOLLIN | EPOLLET; -- event.data.fd = data->fd; -- if (epoll_ctl(epollfd, EPOLL_CTL_ADD, data->fd, &event) < 0) { -- virReportSystemError(errno, "%s", -- _("Unable to add epoll fd")); -- goto cleanup; -+ if (console->contClosed) { -+ int events = EPOLLIN | EPOLLET; -+ if (console->contBlocking) -+ events |= EPOLLOUT; -+ -+ if (events != console->contEpoll) { -+ struct epoll_event event; -+ int action = EPOLL_CTL_ADD; -+ if (console->contEpoll) -+ action = EPOLL_CTL_MOD; -+ -+ VIR_DEBUG("newContEvents=%x oldContEvents=%x", events, console->contEpoll); -+ -+ event.events = events; -+ event.data.fd = console->contFd; -+ if (epoll_ctl(console->epollFd, action, console->contFd, &event) < 0) { -+ virReportSystemError(errno, "%s", -+ _("Unable to add epoll fd")); -+ VIR_DEBUG(":fail"); -+ quit = true; -+ goto cleanup; -+ } -+ console->contEpoll = events; -+ VIR_DEBUG("newHostEvents=%x oldHostEvents=%x", events, console->contEpoll); -+ } -+ } else if (console->contEpoll) { -+ VIR_DEBUG("Stop epoll oldContEvents=%x", console->contEpoll); -+ if (epoll_ctl(console->epollFd, EPOLL_CTL_DEL, console->contFd, NULL) < 0) { -+ virReportSystemError(errno, "%s", -+ _("Unable to remove epoll fd")); -+ VIR_DEBUG(":fail"); -+ quit = true; -+ goto cleanup; -+ } -+ console->contEpoll = 0; - } -+cleanup: -+ return; -+} -+ - -- for (;;) { -- ret = epoll_wait(epollfd, &event, 1, -1); -+static void lxcEpollIO(int watch, int fd, int events, void *opaque) -+{ -+ struct lxcConsole *console = opaque; -+ -+ virMutexLock(&lock); -+ VIR_DEBUG("IO event watch=%d fd=%d events=%d fromHost=%zu fromcont=%zu", -+ watch, fd, events, -+ console->fromHostLen, -+ console->fromContLen); -+ -+ while (1) { -+ struct epoll_event event; -+ int ret; -+ ret = epoll_wait(console->epollFd, &event, 1, 0); - if (ret < 0) { - if (ret == EINTR) - continue; - virReportSystemError(errno, "%s", - _("Unable to wait on epoll")); -- virMutexLock(&lock); - quit = true; -- virMutexUnlock(&lock); - goto cleanup; - } - -+ if (ret == 0) -+ break; -+ -+ VIR_DEBUG("fd=%d hostFd=%d contFd=%d hostEpoll=%x contEpoll=%x", -+ event.data.fd, console->hostFd, console->contFd, -+ console->hostEpoll, console->contEpoll); -+ - /* If we get HUP+dead PID, we just re-enable the main loop - * which will see the PID has died and exit */ - if ((event.events & EPOLLIN)) { -- virMutexLock(&lock); -- if (event.data.fd == data->console->hostFd) { -- data->console->hostClosed = false; -+ if (event.data.fd == console->hostFd) { -+ console->hostClosed = false; - } else { -- data->console->contClosed = false; -+ console->contClosed = false; - } -- lxcConsoleUpdateWatch(data->console); -- virMutexUnlock(&lock); -+ lxcConsoleUpdateWatch(console); - break; - } - } - - cleanup: -- VIR_FORCE_CLOSE(epollfd); -- VIR_FREE(data); --} -- --static int lxcCheckEOF(struct lxcConsole *console, int fd) --{ -- struct lxcConsoleEOFData *data; -- virThread thread; -- -- if (VIR_ALLOC(data) < 0) { -- virReportOOMError(); -- return -1; -- } -- -- data->console = console; -- data->fd = fd; -- -- if (virThreadCreate(&thread, false, lxcConsoleEOFThread, data) < 0) { -- VIR_FREE(data); -- return -1; -- } -- return 0; -+ virMutexUnlock(&lock); - } - - static void lxcConsoleIO(int watch, int fd, int events, void *opaque) -@@ -937,6 +991,10 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque) - struct lxcConsole *console = opaque; - - virMutexLock(&lock); -+ VIR_DEBUG("IO event watch=%d fd=%d events=%d fromHost=%zu fromcont=%zu", -+ watch, fd, events, -+ console->fromHostLen, -+ console->fromContLen); - if (events & VIR_EVENT_HANDLE_READABLE) { - char *buf; - size_t *len; -@@ -993,6 +1051,10 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque) - *len -= done; - } else { - VIR_DEBUG("Write fd %d done %d errno %d", fd, (int)done, errno); -+ if (watch == console->hostWatch) -+ console->hostBlocking = true; -+ else -+ console->contBlocking = true; - } - } - -@@ -1003,8 +1065,6 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque) - console->contClosed = true; - } - VIR_DEBUG("Got EOF on %d %d", watch, fd); -- if (lxcCheckEOF(console, fd) < 0) -- goto error; - } - - lxcConsoleUpdateWatch(console); -@@ -1103,9 +1163,32 @@ static int lxcControllerMain(int serverFd, - } - - for (i = 0 ; i < nFds ; i++) { -+ consoles[i].epollFd = -1; -+ consoles[i].epollWatch = -1; -+ consoles[i].hostWatch = -1; -+ consoles[i].contWatch = -1; -+ } -+ -+ for (i = 0 ; i < nFds ; i++) { - consoles[i].hostFd = hostFds[i]; - consoles[i].contFd = contFds[i]; - -+ if ((consoles[i].epollFd = epoll_create1(EPOLL_CLOEXEC)) < 0) { -+ virReportSystemError(errno, "%s", -+ _("Unable to create epoll fd")); -+ goto cleanup; -+ } -+ -+ if ((consoles[i].epollWatch = virEventAddHandle(consoles[i].epollFd, -+ VIR_EVENT_HANDLE_READABLE, -+ lxcEpollIO, -+ &consoles[i], -+ NULL)) < 0) { -+ lxcError(VIR_ERR_INTERNAL_ERROR, "%s", -+ _("Unable to watch epoll FD")); -+ goto cleanup; -+ } -+ - if ((consoles[i].hostWatch = virEventAddHandle(consoles[i].hostFd, - VIR_EVENT_HANDLE_READABLE, - lxcConsoleIO, -@@ -1146,6 +1229,17 @@ cleanup: - cleanup2: - VIR_FORCE_CLOSE(monitor.serverFd); - VIR_FORCE_CLOSE(monitor.clientFd); -+ -+ for (i = 0 ; i < nFds ; i++) { -+ if (consoles[i].epollWatch != -1) -+ virEventRemoveHandle(consoles[i].epollWatch); -+ VIR_FORCE_CLOSE(consoles[i].epollFd); -+ if (consoles[i].contWatch != -1) -+ virEventRemoveHandle(consoles[i].contWatch); -+ if (consoles[i].hostWatch != -1) -+ virEventRemoveHandle(consoles[i].hostWatch); -+ } -+ - VIR_FREE(consoles); - return rc; - } diff --git a/libvirt.spec b/libvirt.spec index f9422ff..d9df534 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -251,12 +251,11 @@ Summary: Library providing a simple virtualization API Name: libvirt -Version: 0.9.9 -Release: 2%{?dist}%{?extra_release} +Version: 0.9.10 +Release: 0rc2%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries -Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz -Patch1: %{name}-%{version}-lxc-io.patch +Source: http://libvirt.org/sources/libvirt-%{version}-rc2.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/ @@ -274,7 +273,7 @@ Requires: module-init-tools # for /sbin/ip & /sbin/tc Requires: iproute %if %{with_avahi} -Requires: avahi +Requires: avahi-libs %endif %endif %if %{with_network} @@ -347,8 +346,10 @@ Requires: device-mapper %if %{with_cgconfig} Requires: libcgroup %endif +%ifarch i386 i586 i686 x86_64 ia64 # For virConnectGetSysinfo Requires: dmidecode +%endif # For service management %if %{with_systemd} Requires(post): systemd-units @@ -371,10 +372,6 @@ BuildRequires: systemd-units %if %{with_xen} BuildRequires: xen-devel %endif -# temporary explicit requireent missing from xen-4.1.0 -%if %{with_libxl} -BuildRequires: libuuid-devel -%endif BuildRequires: libxml2-devel BuildRequires: xhtml1-dtds BuildRequires: libxslt @@ -588,7 +585,6 @@ of recent versions of Linux (and other OSes). %prep %setup -q -%patch1 -p1 %build %if ! %{with_xen} @@ -1202,9 +1198,11 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd %{_mandir}/man1/virsh.1* %{_mandir}/man1/virt-xml-validate.1* %{_mandir}/man1/virt-pki-validate.1* +%{_mandir}/man1/virt-host-validate.1* %{_bindir}/virsh %{_bindir}/virt-xml-validate %{_bindir}/virt-pki-validate +%{_bindir}/virt-host-validate %{_libdir}/lib*.so.* %dir %{_datadir}/libvirt/ diff --git a/sources b/sources index 164e02f..5eb5696 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -37c4bf8cdd4c76150bc0c1d249945d27 libvirt-0.9.9.tar.gz +25b31eea67c15dffc5f39e345af30c51 libvirt-0.9.10-rc2.tar.gz