diff --git a/libvirt/libvirt-0.6.1-1.src.rpm b/libvirt/libvirt-0.6.1-1.src.rpm deleted file mode 100644 index 2767ba9..0000000 Binary files a/libvirt/libvirt-0.6.1-1.src.rpm and /dev/null differ diff --git a/libvirt/libvirt-0.6.2.tar.gz b/libvirt/libvirt-0.6.2.tar.gz deleted file mode 100644 index c81b6fb..0000000 Binary files a/libvirt/libvirt-0.6.2.tar.gz and /dev/null differ diff --git a/libvirt/libvirt-0.6.3.tar.gz b/libvirt/libvirt-0.6.3.tar.gz new file mode 100644 index 0000000..d174a84 Binary files /dev/null and b/libvirt/libvirt-0.6.3.tar.gz differ diff --git a/libvirt/libvirt-bigargv.patch b/libvirt/libvirt-bigargv.patch new file mode 100644 index 0000000..02d7a66 --- /dev/null +++ b/libvirt/libvirt-bigargv.patch @@ -0,0 +1,12 @@ +diff -urN libvirt-0.6.2/src/qemu_conf.c libvirt-0.6.2-bigargv//src/qemu_conf.c +--- libvirt-0.6.2/src/qemu_conf.c 2009-04-02 05:50:10.000000000 -0400 ++++ libvirt-0.6.2-bigargv//src/qemu_conf.c 2009-05-13 15:03:46.000000000 -0400 +@@ -431,7 +431,7 @@ + return -1; + + char *help = NULL; +- enum { MAX_HELP_OUTPUT_SIZE = 8192 }; ++ enum { MAX_HELP_OUTPUT_SIZE = 16384 }; + int len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help); + if (len < 0) + goto cleanup2; diff --git a/libvirt/libvirt-destroyfix.patch b/libvirt/libvirt-destroyfix.patch new file mode 100644 index 0000000..739f5bf --- /dev/null +++ b/libvirt/libvirt-destroyfix.patch @@ -0,0 +1,921 @@ +diff -r d5dc15adcbea qemud/event.c +--- a/qemud/event.c Fri May 08 11:58:19 2009 +0100 ++++ b/qemud/event.c Fri May 08 16:09:05 2009 +0100 +@@ -30,7 +30,8 @@ + #include + #include + +-#include "qemud.h" ++#include "threads.h" ++#include "logging.h" + #include "event.h" + #include "memory.h" + #include "util.h" +@@ -83,10 +84,10 @@ struct virEventLoop { + static struct virEventLoop eventLoop; + + /* Unique ID for the next FD watch to be registered */ +-static int nextWatch = 0; ++static int nextWatch = 1; + + /* Unique ID for the next timer to be registered */ +-static int nextTimer = 0; ++static int nextTimer = 1; + + static void virEventLock(void) + { +@@ -142,15 +143,22 @@ int virEventAddHandleImpl(int fd, int ev + + void virEventUpdateHandleImpl(int watch, int events) { + int i; ++ EVENT_DEBUG("Update handle w=%d e=%d", watch, events); ++ ++ if (watch <= 0) { ++ VIR_WARN("Ignoring invalid update watch %d", watch); ++ return; ++ } ++ + virEventLock(); + for (i = 0 ; i < eventLoop.handlesCount ; i++) { + if (eventLoop.handles[i].watch == watch) { + eventLoop.handles[i].events = + virEventHandleTypeToPollEvent(events); ++ virEventInterruptLocked(); + break; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + } + +@@ -163,6 +171,12 @@ void virEventUpdateHandleImpl(int watch, + int virEventRemoveHandleImpl(int watch) { + int i; + EVENT_DEBUG("Remove handle %d", watch); ++ ++ if (watch <= 0) { ++ VIR_WARN("Ignoring invalid remove watch %d", watch); ++ return -1; ++ } ++ + virEventLock(); + for (i = 0 ; i < eventLoop.handlesCount ; i++) { + if (eventLoop.handles[i].deleted) +@@ -171,11 +185,11 @@ int virEventRemoveHandleImpl(int watch) + if (eventLoop.handles[i].watch == watch) { + EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd); + eventLoop.handles[i].deleted = 1; ++ virEventInterruptLocked(); + virEventUnlock(); + return 0; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + return -1; + } +@@ -231,6 +245,12 @@ void virEventUpdateTimeoutImpl(int timer + struct timeval tv; + int i; + EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency); ++ ++ if (timer <= 0) { ++ VIR_WARN("Ignoring invalid update timer %d", timer); ++ return; ++ } ++ + if (gettimeofday(&tv, NULL) < 0) { + return; + } +@@ -243,10 +263,10 @@ void virEventUpdateTimeoutImpl(int timer + frequency >= 0 ? frequency + + (((unsigned long long)tv.tv_sec)*1000) + + (((unsigned long long)tv.tv_usec)/1000) : 0; ++ virEventInterruptLocked(); + break; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + } + +@@ -259,6 +279,12 @@ void virEventUpdateTimeoutImpl(int timer + int virEventRemoveTimeoutImpl(int timer) { + int i; + EVENT_DEBUG("Remove timer %d", timer); ++ ++ if (timer <= 0) { ++ VIR_WARN("Ignoring invalid remove timer %d", timer); ++ return -1; ++ } ++ + virEventLock(); + for (i = 0 ; i < eventLoop.timeoutsCount ; i++) { + if (eventLoop.timeouts[i].deleted) +@@ -266,11 +292,11 @@ int virEventRemoveTimeoutImpl(int timer) + + if (eventLoop.timeouts[i].timer == timer) { + eventLoop.timeouts[i].deleted = 1; ++ virEventInterruptLocked(); + virEventUnlock(); + return 0; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + return -1; + } +@@ -287,7 +313,7 @@ static int virEventCalculateTimeout(int + EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount); + /* Figure out if we need a timeout */ + for (i = 0 ; i < eventLoop.timeoutsCount ; i++) { +- if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0) ++ if (eventLoop.timeouts[i].frequency < 0) + continue; + + EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt); +@@ -324,32 +350,26 @@ static int virEventCalculateTimeout(int + * file handles. The caller must free the returned data struct + * returns: the pollfd array, or NULL on error + */ +-static int virEventMakePollFDs(struct pollfd **retfds) { ++static struct pollfd *virEventMakePollFDs(void) { + struct pollfd *fds; +- int i, nfds = 0; ++ int i; ++ ++ /* Setup the poll file handle data structs */ ++ if (VIR_ALLOC_N(fds, eventLoop.handlesCount) < 0) ++ return NULL; + + for (i = 0 ; i < eventLoop.handlesCount ; i++) { +- if (eventLoop.handles[i].deleted) +- continue; +- nfds++; +- } +- *retfds = NULL; +- /* Setup the poll file handle data structs */ +- if (VIR_ALLOC_N(fds, nfds) < 0) +- return -1; +- +- for (i = 0, nfds = 0 ; i < eventLoop.handlesCount ; i++) { +- if (eventLoop.handles[i].deleted) +- continue; +- fds[nfds].fd = eventLoop.handles[i].fd; +- fds[nfds].events = eventLoop.handles[i].events; +- fds[nfds].revents = 0; ++ EVENT_DEBUG("Prepare n=%d w=%d, f=%d e=%d", i, ++ eventLoop.handles[i].watch, ++ eventLoop.handles[i].fd, ++ eventLoop.handles[i].events); ++ fds[i].fd = eventLoop.handles[i].fd; ++ fds[i].events = eventLoop.handles[i].events; ++ fds[i].revents = 0; + //EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events); +- nfds++; + } + +- *retfds = fds; +- return nfds; ++ return fds; + } + + +@@ -409,26 +429,30 @@ static int virEventDispatchTimeouts(void + * Returns 0 upon success, -1 if an error occurred + */ + static int virEventDispatchHandles(int nfds, struct pollfd *fds) { +- int i, n; ++ int i; + +- for (i = 0, n = 0 ; i < eventLoop.handlesCount && n < nfds ; i++) { ++ /* NB, use nfds not eventLoop.handlesCount, because new ++ * fds might be added on end of list, and they're not ++ * in the fds array we've got */ ++ for (i = 0 ; i < nfds ; i++) { + if (eventLoop.handles[i].deleted) { +- EVENT_DEBUG("Skip deleted %d", eventLoop.handles[i].fd); ++ EVENT_DEBUG("Skip deleted n=%d w=%d f=%d", i, ++ eventLoop.handles[i].watch, eventLoop.handles[i].fd); + continue; + } + +- if (fds[n].revents) { ++ if (fds[i].revents) { + virEventHandleCallback cb = eventLoop.handles[i].cb; + void *opaque = eventLoop.handles[i].opaque; +- int hEvents = virPollEventToEventHandleType(fds[n].revents); +- EVENT_DEBUG("Dispatch %d %d %p", fds[n].fd, +- fds[n].revents, eventLoop.handles[i].opaque); ++ int hEvents = virPollEventToEventHandleType(fds[i].revents); ++ EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i, ++ fds[i].fd, eventLoop.handles[i].watch, ++ fds[i].revents, eventLoop.handles[i].opaque); + virEventUnlock(); + (cb)(eventLoop.handles[i].watch, +- fds[n].fd, hEvents, opaque); ++ fds[i].fd, hEvents, opaque); + virEventLock(); + } +- n++; + } + + return 0; +@@ -519,22 +543,21 @@ static int virEventCleanupHandles(void) + * at least one file handle has an event, or a timer expires + */ + int virEventRunOnce(void) { +- struct pollfd *fds; ++ struct pollfd *fds = NULL; + int ret, timeout, nfds; + + virEventLock(); + eventLoop.running = 1; + eventLoop.leader = pthread_self(); +- if ((nfds = virEventMakePollFDs(&fds)) < 0) { +- virEventUnlock(); +- return -1; +- } + +- if (virEventCalculateTimeout(&timeout) < 0) { +- VIR_FREE(fds); +- virEventUnlock(); +- return -1; +- } ++ if (virEventCleanupTimeouts() < 0 || ++ virEventCleanupHandles() < 0) ++ goto error; ++ ++ if (!(fds = virEventMakePollFDs()) || ++ virEventCalculateTimeout(&timeout) < 0) ++ goto error; ++ nfds = eventLoop.handlesCount; + + virEventUnlock(); + +@@ -546,38 +569,31 @@ int virEventRunOnce(void) { + if (errno == EINTR) { + goto retry; + } +- VIR_FREE(fds); +- return -1; ++ goto error_unlocked; + } + + virEventLock(); +- if (virEventDispatchTimeouts() < 0) { +- VIR_FREE(fds); +- virEventUnlock(); +- return -1; +- } ++ if (virEventDispatchTimeouts() < 0) ++ goto error; + + if (ret > 0 && +- virEventDispatchHandles(nfds, fds) < 0) { +- VIR_FREE(fds); +- virEventUnlock(); +- return -1; +- } +- VIR_FREE(fds); ++ virEventDispatchHandles(nfds, fds) < 0) ++ goto error; + +- if (virEventCleanupTimeouts() < 0) { +- virEventUnlock(); +- return -1; +- } +- +- if (virEventCleanupHandles() < 0) { +- virEventUnlock(); +- return -1; +- } ++ if (virEventCleanupTimeouts() < 0 || ++ virEventCleanupHandles() < 0) ++ goto error; + + eventLoop.running = 0; + virEventUnlock(); ++ VIR_FREE(fds); + return 0; ++ ++error: ++ virEventUnlock(); ++error_unlocked: ++ VIR_FREE(fds); ++ return -1; + } + + static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED, +@@ -597,10 +613,10 @@ int virEventInit(void) + return -1; + + if (pipe(eventLoop.wakeupfd) < 0 || +- qemudSetNonBlock(eventLoop.wakeupfd[0]) < 0 || +- qemudSetNonBlock(eventLoop.wakeupfd[1]) < 0 || +- qemudSetCloseExec(eventLoop.wakeupfd[0]) < 0 || +- qemudSetCloseExec(eventLoop.wakeupfd[1]) < 0) ++ virSetNonBlock(eventLoop.wakeupfd[0]) < 0 || ++ virSetNonBlock(eventLoop.wakeupfd[1]) < 0 || ++ virSetCloseExec(eventLoop.wakeupfd[0]) < 0 || ++ virSetCloseExec(eventLoop.wakeupfd[1]) < 0) + return -1; + + if (virEventAddHandleImpl(eventLoop.wakeupfd[0], +@@ -616,9 +632,12 @@ static int virEventInterruptLocked(void) + char c = '\0'; + + if (!eventLoop.running || +- pthread_self() == eventLoop.leader) ++ pthread_self() == eventLoop.leader) { ++ VIR_DEBUG("Skip interrupt, %d %d", eventLoop.running, (int)eventLoop.leader); + return 0; ++ } + ++ VIR_DEBUG0("Interrupting"); + if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c)) + return -1; + return 0; +diff -r d5dc15adcbea qemud/qemud.c +--- a/qemud/qemud.c Fri May 08 11:58:19 2009 +0100 ++++ b/qemud/qemud.c Fri May 08 16:09:05 2009 +0100 +@@ -371,32 +371,6 @@ qemudDispatchSignalEvent(int watch ATTRI + virMutexUnlock(&server->lock); + } + +-int qemudSetCloseExec(int fd) { +- int flags; +- if ((flags = fcntl(fd, F_GETFD)) < 0) +- goto error; +- flags |= FD_CLOEXEC; +- if ((fcntl(fd, F_SETFD, flags)) < 0) +- goto error; +- return 0; +- error: +- VIR_ERROR0(_("Failed to set close-on-exec file descriptor flag")); +- return -1; +-} +- +- +-int qemudSetNonBlock(int fd) { +- int flags; +- if ((flags = fcntl(fd, F_GETFL)) < 0) +- goto error; +- flags |= O_NONBLOCK; +- if ((fcntl(fd, F_SETFL, flags)) < 0) +- goto error; +- return 0; +- error: +- VIR_ERROR0(_("Failed to set non-blocking file descriptor flag")); +- return -1; +-} + + static int qemudGoDaemon(void) { + int pid = fork(); +@@ -525,8 +499,8 @@ static int qemudListenUnix(struct qemud_ + goto cleanup; + } + +- if (qemudSetCloseExec(sock->fd) < 0 || +- qemudSetNonBlock(sock->fd) < 0) ++ if (virSetCloseExec(sock->fd) < 0 || ++ virSetNonBlock(sock->fd) < 0) + goto cleanup; + + memset(&addr, 0, sizeof(addr)); +@@ -687,8 +661,8 @@ remoteListenTCP (struct qemud_server *se + else + sock->port = -1; + +- if (qemudSetCloseExec(sock->fd) < 0 || +- qemudSetNonBlock(sock->fd) < 0) ++ if (virSetCloseExec(sock->fd) < 0 || ++ virSetNonBlock(sock->fd) < 0) + goto cleanup; + + if (listen (sock->fd, 30) < 0) { +@@ -1273,8 +1247,8 @@ static int qemudDispatchServer(struct qe + setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_slow_start, + sizeof no_slow_start); + +- if (qemudSetCloseExec(fd) < 0 || +- qemudSetNonBlock(fd) < 0) { ++ if (virSetCloseExec(fd) < 0 || ++ virSetNonBlock(fd) < 0) { + close(fd); + return -1; + } +@@ -2872,10 +2846,10 @@ int main(int argc, char **argv) { + goto error1; + + if (pipe(sigpipe) < 0 || +- qemudSetNonBlock(sigpipe[0]) < 0 || +- qemudSetNonBlock(sigpipe[1]) < 0 || +- qemudSetCloseExec(sigpipe[0]) < 0 || +- qemudSetCloseExec(sigpipe[1]) < 0) { ++ virSetNonBlock(sigpipe[0]) < 0 || ++ virSetNonBlock(sigpipe[1]) < 0 || ++ virSetCloseExec(sigpipe[0]) < 0 || ++ virSetCloseExec(sigpipe[1]) < 0) { + char ebuf[1024]; + VIR_ERROR(_("Failed to create pipe: %s"), + virStrerror(errno, ebuf, sizeof ebuf)); +diff -r d5dc15adcbea qemud/qemud.h +--- a/qemud/qemud.h Fri May 08 11:58:19 2009 +0100 ++++ b/qemud/qemud.h Fri May 08 16:09:05 2009 +0100 +@@ -198,9 +198,6 @@ void qemudLog(int priority, const char * + ATTRIBUTE_FORMAT(printf,2,3); + + +-int qemudSetCloseExec(int fd); +-int qemudSetNonBlock(int fd); +- + int + remoteDispatchClientRequest (struct qemud_server *server, + struct qemud_client *client, +diff -r d5dc15adcbea tests/Makefile.am +--- a/tests/Makefile.am Fri May 08 11:58:19 2009 +0100 ++++ b/tests/Makefile.am Fri May 08 16:09:05 2009 +0100 +@@ -125,6 +125,11 @@ if WITH_SECDRIVER_SELINUX + TESTS += seclabeltest + endif + ++if WITH_LIBVIRTD ++noinst_PROGRAMS += eventtest ++TESTS += eventtest ++endif ++ + TESTS += nodedevxml2xmltest + + path_add = $$abs_top_builddir/src$(PATH_SEPARATOR)$$abs_top_builddir/qemud +@@ -226,4 +231,10 @@ qparamtest_SOURCES = \ + qparamtest.c testutils.h testutils.c + qparamtest_LDADD = $(LDADDS) + ++if WITH_LIBVIRTD ++eventtest_SOURCES = \ ++ eventtest.c testutils.h testutils.c ../qemud/event.c ++eventtest_LDADD = -lrt $(LDADDS) ++endif ++ + CLEANFILES = *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda +diff -r d5dc15adcbea tests/eventtest.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/tests/eventtest.c Fri May 08 16:09:05 2009 +0100 +@@ -0,0 +1,444 @@ ++/* ++ * eventtest.c: Test the libvirtd event loop impl ++ * ++ * Copyright (C) 2009 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Daniel P. Berrange ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "testutils.h" ++#include "internal.h" ++#include "threads.h" ++#include "logging.h" ++#include "../qemud/event.h" ++ ++#define NUM_FDS 5 ++#define NUM_TIME 5 ++ ++static struct handleInfo { ++ int pipeFD[2]; ++ int fired; ++ int watch; ++ int error; ++ int delete; ++} handles[NUM_FDS]; ++ ++static struct timerInfo { ++ int timeout; ++ int timer; ++ int fired; ++ int error; ++ int delete; ++} timers[NUM_TIME]; ++ ++enum { ++ EV_ERROR_NONE, ++ EV_ERROR_WATCH, ++ EV_ERROR_FD, ++ EV_ERROR_EVENT, ++ EV_ERROR_DATA, ++}; ++ ++static void ++testPipeReader(int watch, int fd, int events, void *data) ++{ ++ struct handleInfo *info = data; ++ char one; ++ ++ info->fired = 1; ++ ++ if (watch != info->watch) { ++ info->error = EV_ERROR_WATCH; ++ return; ++ } ++ ++ if (fd != info->pipeFD[0]) { ++ info->error = EV_ERROR_FD; ++ return; ++ } ++ ++ if (!(events & VIR_EVENT_HANDLE_READABLE)) { ++ info->error = EV_ERROR_EVENT; ++ return; ++ } ++ if (read(fd, &one, 1) != 1) { ++ info->error = EV_ERROR_DATA; ++ return; ++ } ++ info->error = EV_ERROR_NONE; ++ ++ if (info->delete != -1) ++ virEventRemoveHandleImpl(info->delete); ++} ++ ++ ++static void ++testTimer(int timer, void *data) ++{ ++ struct timerInfo *info = data; ++ ++ info->fired = 1; ++ ++ if (timer != info->timer) { ++ info->error = EV_ERROR_WATCH; ++ return; ++ } ++ ++ info->error = EV_ERROR_NONE; ++ ++ if (info->delete != -1) ++ virEventRemoveTimeoutImpl(info->delete); ++} ++ ++static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t eventThreadRunCond = PTHREAD_COND_INITIALIZER; ++static int eventThreadRunOnce = 0; ++static pthread_cond_t eventThreadJobCond = PTHREAD_COND_INITIALIZER; ++static int eventThreadJobDone = 0; ++ ++ ++static void *eventThreadLoop(void *data ATTRIBUTE_UNUSED) { ++ while (1) { ++ pthread_mutex_lock(&eventThreadMutex); ++ while (!eventThreadRunOnce) { ++ pthread_cond_wait(&eventThreadRunCond, &eventThreadMutex); ++ } ++ eventThreadRunOnce = 0; ++ pthread_mutex_unlock(&eventThreadMutex); ++ ++ virEventRunOnce(); ++ ++ pthread_mutex_lock(&eventThreadMutex); ++ eventThreadJobDone = 1; ++ pthread_cond_signal(&eventThreadJobCond); ++ pthread_mutex_unlock(&eventThreadMutex); ++ } ++} ++ ++ ++static int ++verifyFired(int handle, int timer) ++{ ++ int handleFired = 0; ++ int timerFired = 0; ++ int i; ++ for (i = 0 ; i < NUM_FDS ; i++) { ++ if (handles[i].fired) { ++ if (i != handle) { ++ fprintf(stderr, "FAIL Handle %d fired, but expected %d\n", i, handle); ++ return EXIT_FAILURE; ++ } else { ++ if (handles[i].error != EV_ERROR_NONE) { ++ fprintf(stderr, "FAIL Handle %d fired, but had error %d\n", i, ++ handles[i].error); ++ return EXIT_FAILURE; ++ } ++ handleFired = 1; ++ } ++ } else { ++ if (i == handle) { ++ fprintf(stderr, "FAIL Handle %d should have fired, but didn't\n", handle); ++ return EXIT_FAILURE; ++ } ++ } ++ } ++ if (handleFired != 1 && handle != -1) { ++ fprintf(stderr, "FAIL Something wierd happened, expecting handle %d\n", handle); ++ return EXIT_FAILURE; ++ } ++ ++ ++ for (i = 0 ; i < NUM_TIME ; i++) { ++ if (timers[i].fired) { ++ if (i != timer) { ++ fprintf(stderr, "FAIL Timer %d fired, but expected %d\n", i, timer); ++ return EXIT_FAILURE; ++ } else { ++ if (timers[i].error != EV_ERROR_NONE) { ++ fprintf(stderr, "FAIL Timer %d fired, but had error %d\n", i, ++ timers[i].error); ++ return EXIT_FAILURE; ++ } ++ timerFired = 1; ++ } ++ } else { ++ if (i == timer) { ++ fprintf(stderr, "FAIL Timer %d should have fired, but didn't\n", timer); ++ return EXIT_FAILURE; ++ } ++ } ++ } ++ if (timerFired != 1 && timer != -1) { ++ fprintf(stderr, "FAIL Something wierd happened, expecting timer %d\n", timer); ++ return EXIT_FAILURE; ++ } ++ return EXIT_SUCCESS; ++} ++ ++static void ++startJob(const char *msg, int *test) ++{ ++ fprintf(stderr, "%2d: %s ", (*test)++, msg); ++ eventThreadRunOnce = 1; ++ eventThreadJobDone = 0; ++ pthread_cond_signal(&eventThreadRunCond); ++ pthread_mutex_unlock(&eventThreadMutex); ++ sched_yield(); ++ pthread_mutex_lock(&eventThreadMutex); ++} ++ ++static int ++finishJob(int handle, int timer) ++{ ++ struct timespec waitTime; ++ int rc; ++ clock_gettime(CLOCK_REALTIME, &waitTime); ++ waitTime.tv_sec += 5; ++ rc = 0; ++ while (!eventThreadJobDone && rc == 0) ++ rc = pthread_cond_timedwait(&eventThreadJobCond, &eventThreadMutex, &waitTime); ++ if (rc != 0) { ++ fprintf(stderr, "FAIL Timed out waiting for pipe event\n"); ++ return EXIT_FAILURE; ++ } ++ ++ if (verifyFired(handle, timer) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ fprintf(stderr, "OK\n"); ++ return EXIT_SUCCESS; ++} ++ ++static void ++resetAll(void) ++{ ++ int i; ++ for (i = 0 ; i < NUM_FDS ; i++) { ++ handles[i].fired = 0; ++ handles[i].error = EV_ERROR_NONE; ++ } ++ for (i = 0 ; i < NUM_TIME ; i++) { ++ timers[i].fired = 0; ++ timers[i].error = EV_ERROR_NONE; ++ } ++} ++ ++static int ++mymain(int argc, char **argv) ++{ ++ int ret = 0; ++ char *progname; ++ int i; ++ pthread_t eventThread; ++ char one = '1'; ++ int test = 1; ++ ++ progname = argv[0]; ++ ++ if (argc > 1) { ++ fprintf(stderr, "Usage: %s\n", progname); ++ return EXIT_FAILURE; ++ } ++ ++ for (i = 0 ; i < NUM_FDS ; i++) { ++ if (pipe(handles[i].pipeFD) < 0) { ++ fprintf(stderr, "Cannot create pipe: %d", errno); ++ return EXIT_FAILURE; ++ } ++ } ++ ++ if (virThreadInitialize() < 0) ++ return EXIT_FAILURE; ++ char *debugEnv = getenv("LIBVIRT_DEBUG"); ++ if (debugEnv && *debugEnv && *debugEnv != '0') { ++ if (STREQ(debugEnv, "2") || STREQ(debugEnv, "info")) ++ virLogSetDefaultPriority(VIR_LOG_INFO); ++ else if (STREQ(debugEnv, "3") || STREQ(debugEnv, "warning")) ++ virLogSetDefaultPriority(VIR_LOG_WARN); ++ else if (STREQ(debugEnv, "4") || STREQ(debugEnv, "error")) ++ virLogSetDefaultPriority(VIR_LOG_ERROR); ++ else ++ virLogSetDefaultPriority(VIR_LOG_DEBUG); ++ } ++ ++ virEventInit(); ++ ++ for (i = 0 ; i < NUM_FDS ; i++) { ++ handles[i].delete = -1; ++ handles[i].watch = ++ virEventAddHandleImpl(handles[i].pipeFD[0], ++ VIR_EVENT_HANDLE_READABLE, ++ testPipeReader, ++ &handles[i], NULL); ++ } ++ ++ for (i = 0 ; i < NUM_TIME ; i++) { ++ timers[i].delete = -1; ++ timers[i].timeout = -1; ++ timers[i].timer = ++ virEventAddTimeoutImpl(timers[i].timeout, ++ testTimer, ++ &timers[i], NULL); ++ } ++ ++ pthread_create(&eventThread, NULL, eventThreadLoop, NULL); ++ ++ pthread_mutex_lock(&eventThreadMutex); ++ ++ /* First time, is easy - just try triggering one of our ++ * registered handles */ ++ startJob("Simple write", &test); ++ ret = write(handles[1].pipeFD[1], &one, 1); ++ if (finishJob(1, -1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ resetAll(); ++ ++ /* Now lets delete one before starting poll(), and ++ * try triggering another handle */ ++ virEventRemoveHandleImpl(handles[0].watch); ++ startJob("Deleted before poll", &test); ++ ret = write(handles[1].pipeFD[1], &one, 1); ++ if (finishJob(1, -1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ resetAll(); ++ ++ /* Next lets delete *during* poll, which should interrupt ++ * the loop with no event showing */ ++ ++ /* NB: this case is subject to a bit of a race condition. ++ * We yield & sleep, and pray that the other thread gets ++ * scheduled before we run EventRemoveHandleImpl */ ++ startJob("Interrupted during poll", &test); ++ pthread_mutex_unlock(&eventThreadMutex); ++ sched_yield(); ++ usleep(100 * 1000); ++ pthread_mutex_lock(&eventThreadMutex); ++ virEventRemoveHandleImpl(handles[1].watch); ++ if (finishJob(-1, -1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ resetAll(); ++ ++ /* Getting more fun, lets delete a later handle during dispatch */ ++ ++ /* NB: this case is subject to a bit of a race condition. ++ * Only 1 time in 3 does the 2nd write get triggered by ++ * before poll() exits for the first write(). We don't ++ * see a hard failure in other cases, so nothing to worry ++ * about */ ++ startJob("Deleted during dispatch", &test); ++ handles[2].delete = handles[3].watch; ++ ret = write(handles[2].pipeFD[1], &one, 1); ++ ret = write(handles[3].pipeFD[1], &one, 1); ++ if (finishJob(2, -1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ resetAll(); ++ ++ /* Extreme fun, lets delete ourselves during dispatch */ ++ startJob("Deleted during dispatch", &test); ++ handles[2].delete = handles[2].watch; ++ ret = write(handles[2].pipeFD[1], &one, 1); ++ if (finishJob(2, -1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ resetAll(); ++ ++ ++ ++ /* Run a timer on its own */ ++ virEventUpdateTimeoutImpl(timers[1].timer, 100); ++ startJob("Firing a timer", &test); ++ if (finishJob(-1, 1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ virEventUpdateTimeoutImpl(timers[1].timer, -1); ++ ++ resetAll(); ++ ++ /* Now lets delete one before starting poll(), and ++ * try triggering another timer */ ++ virEventUpdateTimeoutImpl(timers[1].timer, 100); ++ virEventRemoveTimeoutImpl(timers[0].timer); ++ startJob("Deleted before poll", &test); ++ if (finishJob(-1, 1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ virEventUpdateTimeoutImpl(timers[1].timer, -1); ++ ++ resetAll(); ++ ++ /* Next lets delete *during* poll, which should interrupt ++ * the loop with no event showing */ ++ ++ /* NB: this case is subject to a bit of a race condition. ++ * We yield & sleep, and pray that the other thread gets ++ * scheduled before we run EventRemoveTimeoutImpl */ ++ startJob("Interrupted during poll", &test); ++ pthread_mutex_unlock(&eventThreadMutex); ++ sched_yield(); ++ usleep(100 * 1000); ++ pthread_mutex_lock(&eventThreadMutex); ++ virEventRemoveTimeoutImpl(timers[1].timer); ++ if (finishJob(-1, -1) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ resetAll(); ++ ++ /* Getting more fun, lets delete a later timer during dispatch */ ++ ++ /* NB: this case is subject to a bit of a race condition. ++ * Only 1 time in 3 does the 2nd write get triggered by ++ * before poll() exits for the first write(). We don't ++ * see a hard failure in other cases, so nothing to worry ++ * about */ ++ virEventUpdateTimeoutImpl(timers[2].timer, 100); ++ virEventUpdateTimeoutImpl(timers[3].timer, 100); ++ startJob("Deleted during dispatch", &test); ++ timers[2].delete = timers[3].timer; ++ if (finishJob(-1, 2) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ virEventUpdateTimeoutImpl(timers[2].timer, -1); ++ ++ resetAll(); ++ ++ /* Extreme fun, lets delete ourselves during dispatch */ ++ virEventUpdateTimeoutImpl(timers[2].timer, 100); ++ startJob("Deleted during dispatch", &test); ++ timers[2].delete = timers[2].timer; ++ if (finishJob(-1, 2) != EXIT_SUCCESS) ++ return EXIT_FAILURE; ++ ++ for (i = 0 ; i < NUM_FDS ; i++) ++ virEventRemoveHandleImpl(handles[i].watch); ++ for (i = 0 ; i < NUM_TIME ; i++) ++ virEventRemoveTimeoutImpl(timers[i].timer); ++ ++ ++ //pthread_kill(eventThread, SIGTERM); ++ ++ return EXIT_SUCCESS; ++} ++ ++ ++VIRT_TEST_MAIN(mymain) +diff -r d5dc15adcbea tests/testutils.h +--- a/tests/testutils.h Fri May 08 11:58:19 2009 +0100 ++++ b/tests/testutils.h Fri May 08 16:09:05 2009 +0100 +@@ -11,6 +11,8 @@ + #ifndef __VIT_TEST_UTILS_H__ + #define __VIT_TEST_UTILS_H__ + ++#include ++ + double virtTestCountAverage(double *items, + int nitems); + diff --git a/libvirt/libvirt-qemukvmfixes.patch b/libvirt/libvirt-qemukvmfixes.patch new file mode 100644 index 0000000..1cc76aa --- /dev/null +++ b/libvirt/libvirt-qemukvmfixes.patch @@ -0,0 +1,33 @@ +diff -urN libvirt-0.6.3/src/qemu_conf.c libvirt-0.6.3-kvm-qemu/src/qemu_conf.c +--- libvirt-0.6.3/src/qemu_conf.c 2009-05-19 22:22:22.000000000 -0400 ++++ libvirt-0.6.3-kvm-qemu/src/qemu_conf.c 2009-05-19 22:22:07.000000000 -0400 +@@ -418,6 +418,7 @@ + int newstdout = -1; + int ret = -1, status; + unsigned int major, minor, micro; ++ unsigned int kvmmajor, kvmminor, kvmmicro; + unsigned int version, kvm_version; + unsigned int flags = 0; + +@@ -440,6 +441,10 @@ + &major, &minor, µ, &kvm_version) != 4) + kvm_version = 0; + ++ if (!kvm_version && sscanf(help, "QEMU PC emulator version %u.%u.%u (qemu-kvm-%u.%u.%u)",&major, &minor, µ,&kvmmajor,&kvmminor,&kvmmicro) != 6) ++ kvm_version=0; ++ else ++ kvm_version=(kvmmajor*1000*1000)+(kvmminor*1000)+kvmmicro; + if (!kvm_version && sscanf(help, "QEMU PC emulator version %u.%u.%u", + &major, &minor, µ) != 3) + goto cleanup2; +@@ -648,8 +653,8 @@ + } + + snprintf(tapfdstr, sizeof(tapfdstr), +- "tap,fd=%d,script=,vlan=%d,ifname=%s", +- tapfd, vlan, net->ifname); ++ "tap,fd=%d,vlan=%d", ++ tapfd, vlan); + + if (!(retval = strdup(tapfdstr))) + goto no_memory; diff --git a/libvirt/libvirt-socat.patch b/libvirt/libvirt-socat.patch new file mode 100644 index 0000000..8b72730 --- /dev/null +++ b/libvirt/libvirt-socat.patch @@ -0,0 +1,30 @@ +Index: libvirt-0.4.5/src/remote_internal.c +=================================================================== +--- libvirt-0.4.5.orig/src/remote_internal.c ++++ libvirt-0.4.5/src/remote_internal.c +@@ -623,9 +623,22 @@ doRemoteOpen (virConnectPtr conn, + cmd_argv[j++] = strdup ("none"); + } + cmd_argv[j++] = strdup (priv->hostname); +- cmd_argv[j++] = strdup (netcat ? netcat : "nc"); +- cmd_argv[j++] = strdup ("-U"); +- cmd_argv[j++] = strdup (sockname ? sockname : LIBVIRTD_PRIV_UNIX_SOCKET); ++ if (netcat) { ++ cmd_argv[j++] = strdup (netcat); ++ cmd_argv[j++] = strdup ("-U"); ++ cmd_argv[j++] = strdup (sockname ? sockname : LIBVIRTD_PRIV_UNIX_SOCKET); ++ } else { ++ cmd_argv[j++] = strdup ("socat"); ++ cmd_argv[j++] = strdup ("-"); ++ ++ char *socat_addr = 0; ++ if ((asprintf (&socat_addr, "GOPEN:%s", ++ sockname ? sockname : LIBVIRTD_PRIV_UNIX_SOCKET)) < 0) { ++ error (conn, VIR_ERR_SYSTEM_ERROR, strerror (ENOMEM)); ++ goto failed; ++ } ++ cmd_argv[j++] = socat_addr; ++ } + cmd_argv[j++] = 0; + assert (j == nr_args); + for (j = 0; j < (nr_args-1); j++) diff --git a/libvirt/libvirt.spec b/libvirt/libvirt.spec index b641112..f56e5f9 100644 --- a/libvirt/libvirt.spec +++ b/libvirt/libvirt.spec @@ -46,7 +46,7 @@ Summary: Library providing a simple API virtualization Name: libvirt -Version: 0.6.2 +Version: 0.6.3 Release: 1%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries diff --git a/libvirt/libvirt.spec.sles b/libvirt/libvirt.spec.sles new file mode 100644 index 0000000..cb88210 --- /dev/null +++ b/libvirt/libvirt.spec.sles @@ -0,0 +1,720 @@ +# -*- rpm-spec -*- + +%define with_xen 0%{!?_without_xen:1} +%define with_xen_proxy 0%{!?_without_xen_proxy:1} +%define with_qemu 0%{!?_without_qemu:1} +%define with_openvz 0%{!?_without_openvz:1} +%define with_lxc 0%{!?_without_lxc:1} +%define with_sasl 0%{!?_without_sasl:1} +%define with_avahi 0%{!?_without_avahi:1} +%define with_polkit 0%{!?_without_polkit:0} +%define with_python 0%{!?_without_python:1} +%define with_libvirtd 0%{!?_without_libvirtd:1} +%define with_uml 0%{!?_without_uml:1} +%define with_network 0%{!?_without_network:1} + +# Xen is available only on i386 x86_64 ia64 +%ifnarch i386 i586 i686 x86_64 ia64 +%define with_xen 0 +%endif + +%if ! %{with_xen} +%define with_xen_proxy 0 +%endif + +%if 0%{?fedora} +%ifarch ppc64 +%define with_qemu 0 +%endif +%endif + +%if 0%{?fedora} >= 8 +%define with_polkit 0%{!?_without_polkit:1} +%define with_xen_proxy 0 +%endif + +# +# If building on RHEL switch on the specific support +# for the specific Xen version +# +%if 0%{?fedora} +%define with_rhel5 0 +%else +%define with_rhel5 1 +%endif + + +Summary: Library providing a simple API virtualization +Name: libvirt +Version: 0.6.3 +Release: 1%{?dist}%{?extra_release} +License: LGPLv2+ +Group: Development/Libraries +Source: libvirt-%{version}.tar.gz +Patch0: libvirt-bigargv.patch +Patch1: libvirt-destroyfix.patch +Patch2: libvirt-socat.patch +Patch3: libvirt-qemukvmfixes.patch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +URL: http://libvirt.org/ +%if %{with_python} +BuildRequires: python python-devel +%endif +Requires: libxml2 +Requires: readline +Requires: ncurses +Requires: bridge-utils +Requires: iptables +# needed for device enumeration +Requires: hal +# So remote clients can access libvirt over SSH tunnel +# (client invokes 'nc' against the UNIX socket on the server) +#Requires: nc +%if %{with_sasl} +Requires: cyrus-sasl +# Not technically required, but makes 'out-of-box' config +# work correctly & doesn't have onerous dependencies +Requires: cyrus-sasl-md5 +%endif +%if %{with_polkit} +Requires: PolicyKit >= 0.6 +%endif +# For mount/umount in FS driver +BuildRequires: util-linux +# For showmount in FS driver (netfs discovery) +BuildRequires: nfs-utils +Requires: nfs-utils +%if %{with_qemu} +# From QEMU RPMs +Requires: /usr/bin/qemu-img +%else +%if %{with_xen} +# From Xen RPMs +Requires: /usr/sbin/qcow-create +%endif +%endif +# For LVM drivers +Requires: lvm2 +# For ISCSI driver +#Requires: iscsi-initiator-utils +# For disk driver +Requires: parted +%if %{with_xen} +BuildRequires: xen-devel +%endif +BuildRequires: libxml2-devel +#BuildRequires: xhtml1-dtds +BuildRequires: readline-devel +BuildRequires: ncurses-devel +BuildRequires: gettext +#BuildRequires: gnutls-devel +BuildRequires: libgnutls-devel +BuildRequires: hal-devel +%if %{with_avahi} +BuildRequires: avahi-devel +%endif +#BuildRequires: libselinux-devel +BuildRequires: bridge-utils +%if %{with_sasl} +BuildRequires: cyrus-sasl-devel +%endif +%if %{with_polkit} +BuildRequires: PolicyKit-devel >= 0.6 +%endif +# For mount/umount in FS driver +BuildRequires: util-linux +%if %{with_qemu} +# From QEMU RPMs +BuildRequires: /usr/bin/qemu-img +%else +%if %{with_xen} +# From Xen RPMs +BuildRequires: /usr/sbin/qcow-create +%endif +%endif +# For LVM drivers +BuildRequires: lvm2 +# For ISCSI driver +#BuildRequires: iscsi-initiator-utils +# For disk driver +BuildRequires: parted-devel +# For QEMU/LXC numa info +#BuildRequires: numactl-devel +BuildRequires: libnuma-devel +Obsoletes: libvir + +# Fedora build root suckage +BuildRequires: gawk + +%description +Libvirt is a C toolkit to interact with the virtualization capabilities +of recent versions of Linux (and other OSes). + +%package devel +Summary: Libraries, includes, etc. to compile with the libvirt library +Group: Development/Libraries +Requires: libvirt = %{version} +Requires: pkgconfig +%if %{with_xen} +Requires: xen-devel +%endif +Obsoletes: libvir-devel + +%description devel +Includes and documentations for the C library providing an API to use +the virtualization capabilities of recent versions of Linux (and other OSes). + +%if %{with_python} +%package python +Summary: Python bindings for the libvirt library +Group: Development/Libraries +Requires: libvirt = %{version} +Obsoletes: libvir-python + +%description python +The libvirt-python package contains a module that permits applications +written in the Python programming language to use the interface +supplied by the libvirt library to use the virtualization capabilities +of recent versions of Linux (and other OSes). +%endif + +%prep +%setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 + +%build +%if ! %{with_xen} +%define _without_xen --without-xen +%endif + +%if ! %{with_qemu} +%define _without_qemu --without-qemu +%endif + +%if ! %{with_openvz} +%define _without_openvz --without-openvz +%endif + +%if ! %{with_lxc} +%define _without_lxc --without-lxc +%endif + +%if ! %{with_sasl} +%define _without_sasl --without-sasl +%endif + +%if ! %{with_avahi} +%define _without_avahi --without-avahi +%endif + +%if ! %{with_polkit} +%define _without_polkit --without-polkit +%endif + +%if ! %{with_python} +%define _without_python --without-python +%endif + +%if ! %{with_libvirtd} +%define _without_libvirtd --without-libvirtd +%endif + +%if ! %{with_uml} +%define _without_uml --without-uml +%endif + +%if %{with_rhel5} +%define _with_rhel5_api --with-rhel5-api +%endif + +%if ! %{with_network} +%define _without_network --without-network +%endif + +%configure %{?_without_xen} \ + %{?_without_qemu} \ + %{?_without_openvz} \ + %{?_without_lxc} \ + %{?_without_sasl} \ + %{?_without_avahi} \ + %{?_without_polkit} \ + %{?_without_python} \ + %{?_without_libvirtd} \ + %{?_without_uml} \ + %{?_without_network} \ + %{?_with_rhel5_api} \ + --with-init-script=redhat \ + --with-qemud-pid-file=%{_localstatedir}/run/libvirt_qemud.pid \ + --with-remote-file=%{_localstatedir}/run/libvirtd.pid +make %{?_smp_mflags} + +%install +rm -fr %{buildroot} + +%makeinstall +(cd docs/examples ; make clean ; rm -rf .deps Makefile Makefile.in) +(cd docs/examples/python ; rm -rf .deps Makefile Makefile.in) +(cd examples/hellolibvirt ; make clean ; rm -rf .deps .libs Makefile Makefile.in) +(cd examples/domain-events/events-c ; make clean ;rm -rf .deps .libs Makefile Makefile.in) +rm -f $RPM_BUILD_ROOT%{_libdir}/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.a + +%if %{with_qemu} +# We don't want to install /etc/libvirt/qemu/networks in the main %files list +# because if the admin wants to delete the default network completely, we don't +# want to end up re-incarnating it on every RPM upgrade. +install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/ +cp $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml \ + $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/default.xml +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml +# Strip auto-generated UUID - we need it generated per-install +sed -i -e "//d" $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/default.xml +%else +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_qemu.aug +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug +%endif +%find_lang %{name} + +%if ! %{with_python} +rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-python-%{version} +%endif + +%if ! %{with_qemu} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu.conf +%endif + +%clean +rm -fr %{buildroot} + +%post +/sbin/ldconfig + +%if %{with_libvirtd} +%if %{with_qemu} +# We want to install the default network for initial RPM installs +# or on the first upgrade from a non-network aware libvirt only. +# We check this by looking to see if the daemon is already installed +/sbin/chkconfig --list libvirtd 1>/dev/null 2>&1 +if [ $? != 0 -a ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ] +then + UUID=`/usr/bin/uuidgen` + sed -e "s,,\n $UUID," \ + < %{_datadir}/libvirt/networks/default.xml \ + > %{_sysconfdir}/libvirt/qemu/networks/default.xml + ln -s ../default.xml %{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml +fi +%endif + +/sbin/chkconfig --add libvirtd +%endif + +%preun +%if %{with_libvirtd} +if [ $1 = 0 ]; then + /sbin/service libvirtd stop 1>/dev/null 2>&1 + /sbin/chkconfig --del libvirtd +fi +%endif + +%postun +/sbin/ldconfig + +%files -f %{name}.lang +%defattr(-, root, root) + +%doc AUTHORS ChangeLog NEWS README COPYING.LIB TODO +%doc %{_mandir}/man1/virsh.1* +/usr +%{_bindir}/virsh +%{_libdir}/lib*.so.* +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/ + +%if %{with_qemu} +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/ +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/ +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/autostart +%endif + +%if %{with_libvirtd} +#%{_sysconfdir}/rc.d/init.d/libvirtd +#%config(noreplace) %{_sysconfdir}/sysconfig/libvirtd +%config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf +%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd +%endif + +%if %{with_qemu} +%config(noreplace) %{_sysconfdir}/libvirt/qemu.conf +%endif + +%if %{with_sasl} +%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf +%endif + +%if %{with_qemu} +%dir %{_datadir}/libvirt/ +%dir %{_datadir}/libvirt/networks/ +%{_datadir}/libvirt/networks/default.xml +%endif + +%dir %{_datadir}/libvirt/ +%dir %{_datadir}/libvirt/schemas/ + +%{_datadir}/libvirt/schemas/domain.rng +%{_datadir}/libvirt/schemas/network.rng +%{_datadir}/libvirt/schemas/storagepool.rng +%{_datadir}/libvirt/schemas/storagevol.rng +%{_datadir}/libvirt/schemas/nodedev.rng +%{_datadir}/libvirt/schemas/capability.rng + +%dir %{_localstatedir}/run/libvirt/ + +%dir %{_localstatedir}/lib/libvirt/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/images/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/boot/ + +%if %{with_qemu} +%dir %{_localstatedir}/run/libvirt/qemu/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/qemu/ +%endif +%if %{with_lxc} +%dir %{_localstatedir}/run/libvirt/lxc/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/lxc/ +%endif +%if %{with_uml} +%dir %{_localstatedir}/run/libvirt/uml/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/ +%endif +%if %{with_network} +%dir %{_localstatedir}/run/libvirt/network/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/iptables/filter/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/iptables/nat/ +%endif + +%if %{with_qemu} +%{_datadir}/augeas/lenses/libvirtd_qemu.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug +%endif + +%if %{with_libvirtd} +%{_datadir}/augeas/lenses/libvirtd.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd.aug +%endif + +%if %{with_polkit} +%{_datadir}/PolicyKit/policy/org.libvirt.unix.policy +%endif + +%if %{with_qemu} +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/ +%endif + +%if %{with_xen_proxy} +%attr(4755, root, root) %{_libexecdir}/libvirt_proxy +%endif + +%if %{with_lxc} +%attr(0755, root, root) %{_libexecdir}/libvirt_lxc +%endif + +%if %{with_libvirtd} +%attr(0755, root, root) %{_sbindir}/libvirtd +%endif + +%doc docs/*.xml + +%files devel +%defattr(-, root, root) + +%{_libdir}/lib*.so +%dir %{_includedir}/libvirt +%{_includedir}/libvirt/*.h +%{_libdir}/pkgconfig/libvirt.pc +%doc %{_datadir}/gtk-doc/html/libvirt/*.devhelp +%doc %{_datadir}/gtk-doc/html/libvirt/*.html +%doc %{_datadir}/gtk-doc/html/libvirt/*.png +%doc %{_datadir}/gtk-doc/html/libvirt/*.css + +%doc docs/*.html docs/html docs/*.gif +%doc docs/examples +%doc docs/libvirt-api.xml +%doc examples + +%if %{with_python} +%files python +%defattr(-, root, root) + +%doc AUTHORS NEWS README COPYING.LIB +%{_libdir}/python*/site-packages/libvirt.py* +%{_libdir}/python*/site-packages/libvirtmod* +%doc python/tests/*.py +%doc python/TODO +%doc python/libvirtclass.txt +%doc docs/examples/python +%endif + +%changelog +* Tue Nov 25 2008 Daniel Veillard - 0.5.0-1 +- release of 0.5.0 + +* Tue Sep 23 2008 Daniel Veillard - 0.4.6-1 +- release of 0.4.6 + +* Mon Sep 8 2008 Daniel Veillard - 0.4.5-1 +- release of 0.4.5 + +* Wed Jun 25 2008 Daniel Veillard - 0.4.4-1 +- release of 0.4.4 +- mostly a few bug fixes from 0.4.3 + +* Thu Jun 12 2008 Daniel Veillard - 0.4.3-1 +- release of 0.4.3 +- lots of bug fixes and small improvements + +* Tue Apr 8 2008 Daniel Veillard - 0.4.2-1 +- release of 0.4.2 +- lots of bug fixes and small improvements + +* Mon Mar 3 2008 Daniel Veillard - 0.4.1-1 +- Release of 0.4.1 +- Storage APIs +- xenner support +- lots of assorted improvements, bugfixes and cleanups +- documentation and localization improvements + +* Tue Dec 18 2007 Daniel Veillard - 0.4.0-1 +- Release of 0.4.0 +- SASL based authentication +- PolicyKit authentication +- improved NUMA and statistics support +- lots of assorted improvements, bugfixes and cleanups +- documentation and localization improvements + +* Sun Sep 30 2007 Daniel Veillard - 0.3.3-1 +- Release of 0.3.3 +- Avahi support +- NUMA support +- lots of assorted improvements, bugfixes and cleanups +- documentation and localization improvements + +* Tue Aug 21 2007 Daniel Veillard - 0.3.2-1 +- Release of 0.3.2 +- API for domains migration +- APIs for collecting statistics on disks and interfaces +- lots of assorted bugfixes and cleanups +- documentation and localization improvements + +* Tue Jul 24 2007 Daniel Veillard - 0.3.1-1 +- Release of 0.3.1 +- localtime clock support +- PS/2 and USB input devices +- lots of assorted bugfixes and cleanups +- documentation and localization improvements + +* Mon Jul 9 2007 Daniel Veillard - 0.3.0-1 +- Release of 0.3.0 +- Secure remote access support +- unification of daemons +- lots of assorted bugfixes and cleanups +- documentation and localization improvements + +* Fri Jun 8 2007 Daniel Veillard - 0.2.3-1 +- Release of 0.2.3 +- lot of assorted bugfixes and cleanups +- support for Xen-3.1 +- new scheduler API + +* Tue Apr 17 2007 Daniel Veillard - 0.2.2-1 +- Release of 0.2.2 +- lot of assorted bugfixes and cleanups +- preparing for Xen-3.0.5 + +* Thu Mar 22 2007 Jeremy Katz - 0.2.1-2.fc7 +- don't require xen; we don't need the daemon and can control non-xen now +- fix scriptlet error (need to own more directories) +- update description text + +* Fri Mar 16 2007 Daniel Veillard - 0.2.1-1 +- Release of 0.2.1 +- lot of bug and portability fixes +- Add support for network autostart and init scripts +- New API to detect the virtualization capabilities of a host +- Documentation updates + +* Fri Feb 23 2007 Daniel P. Berrange - 0.2.0-4.fc7 +- Fix loading of guest & network configs + +* Fri Feb 16 2007 Daniel P. Berrange - 0.2.0-3.fc7 +- Disable kqemu support since its not in Fedora qemu binary +- Fix for -vnc arg syntax change in 0.9.0 QEMU + +* Thu Feb 15 2007 Daniel P. Berrange - 0.2.0-2.fc7 +- Fixed path to qemu daemon for autostart +- Fixed generation of block in XML +- Pre-create config directory at startup + +* Wed Feb 14 2007 Daniel Veillard 0.2.0-1.fc7 +- support for KVM and QEmu +- support for network configuration +- assorted fixes + +* Mon Jan 22 2007 Daniel Veillard 0.1.11-1.fc7 +- finish inactive Xen domains support +- memory leak fix +- RelaxNG schemas for XML configs + +* Wed Dec 20 2006 Daniel Veillard 0.1.10-1.fc7 +- support for inactive Xen domains +- improved support for Xen display and vnc +- a few bug fixes +- localization updates + +* Thu Dec 7 2006 Jeremy Katz - 0.1.9-2 +- rebuild against python 2.5 + +* Wed Nov 29 2006 Daniel Veillard 0.1.9-1 +- better error reporting +- python bindings fixes and extensions +- add support for shareable drives +- add support for non-bridge style networking +- hot plug device support +- added support for inactive domains +- API to dump core of domains +- various bug fixes, cleanups and improvements +- updated the localization + +* Tue Nov 7 2006 Daniel Veillard 0.1.8-3 +- it's pkgconfig not pgkconfig ! + +* Mon Nov 6 2006 Daniel Veillard 0.1.8-2 +- fixing spec file, added %dist, -devel requires pkgconfig and xen-devel +- Resolves: rhbz#202320 + +* Mon Oct 16 2006 Daniel Veillard 0.1.8-1 +- fix missing page size detection code for ia64 +- fix mlock size when getting domain info list from hypervisor +- vcpu number initialization +- don't label crashed domains as shut off +- fix virsh man page +- blktapdd support for alternate drivers like blktap +- memory leak fixes (xend interface and XML parsing) +- compile fix +- mlock/munlock size fixes + +* Fri Sep 22 2006 Daniel Veillard 0.1.7-1 +- Fix bug when running against xen-3.0.3 hypercalls +- Fix memory bug when getting vcpus info from xend + +* Fri Sep 22 2006 Daniel Veillard 0.1.6-1 +- Support for localization +- Support for new Xen-3.0.3 cdrom and disk configuration +- Support for setting VNC port +- Fix bug when running against xen-3.0.2 hypercalls +- Fix reconnection problem when talking directly to http xend + +* Tue Sep 5 2006 Jeremy Katz - 0.1.5-3 +- patch from danpb to support new-format cd devices for HVM guests + +* Tue Sep 5 2006 Daniel Veillard 0.1.5-2 +- reactivating ia64 support + +* Tue Sep 5 2006 Daniel Veillard 0.1.5-1 +- new release +- bug fixes +- support for new hypervisor calls +- early code for config files and defined domains + +* Mon Sep 4 2006 Daniel Berrange - 0.1.4-5 +- add patch to address dom0_ops API breakage in Xen 3.0.3 tree + +* Mon Aug 28 2006 Jeremy Katz - 0.1.4-4 +- add patch to support paravirt framebuffer in Xen + +* Mon Aug 21 2006 Daniel Veillard 0.1.4-3 +- another patch to fix network handling in non-HVM guests + +* Thu Aug 17 2006 Daniel Veillard 0.1.4-2 +- patch to fix virParseUUID() + +* Wed Aug 16 2006 Daniel Veillard 0.1.4-1 +- vCPUs and affinity support +- more complete XML, console and boot options +- specific features support +- enforced read-only connections +- various improvements, bug fixes + +* Wed Aug 2 2006 Jeremy Katz - 0.1.3-6 +- add patch from pvetere to allow getting uuid from libvirt + +* Wed Aug 2 2006 Jeremy Katz - 0.1.3-5 +- build on ia64 now + +* Thu Jul 27 2006 Jeremy Katz - 0.1.3-4 +- don't BR xen, we just need xen-devel + +* Thu Jul 27 2006 Daniel Veillard 0.1.3-3 +- need rebuild since libxenstore is now versionned + +* Mon Jul 24 2006 Mark McLoughlin - 0.1.3-2 +- Add BuildRequires: xen-devel + +* Wed Jul 12 2006 Jesse Keating - 0.1.3-1.1 +- rebuild + +* Tue Jul 11 2006 Daniel Veillard 0.1.3-1 +- support for HVM Xen guests +- various bugfixes + +* Mon Jul 3 2006 Daniel Veillard 0.1.2-1 +- added a proxy mechanism for read only access using httpu +- fixed header includes paths + +* Wed Jun 21 2006 Daniel Veillard 0.1.1-1 +- extend and cleanup the driver infrastructure and code +- python examples +- extend uuid support +- bug fixes, buffer handling cleanups +- support for new Xen hypervisor API +- test driver for unit testing +- virsh --conect argument + +* Mon Apr 10 2006 Daniel Veillard 0.1.0-1 +- various fixes +- new APIs: for Node information and Reboot +- virsh improvements and extensions +- documentation updates and man page +- enhancement and fixes of the XML description format + +* Tue Feb 28 2006 Daniel Veillard 0.0.6-1 +- added error handling APIs +- small bug fixes +- improve python bindings +- augment documentation and regression tests + +* Thu Feb 23 2006 Daniel Veillard 0.0.5-1 +- new domain creation API +- new UUID based APIs +- more tests, documentation, devhelp +- bug fixes + +* Fri Feb 10 2006 Daniel Veillard 0.0.4-1 +- fixes some problems in 0.0.3 due to the change of names + +* Wed Feb 8 2006 Daniel Veillard 0.0.3-1 +- changed library name to libvirt from libvir, complete and test the python + bindings + +* Sun Jan 29 2006 Daniel Veillard 0.0.2-1 +- upstream release of 0.0.2, use xend, save and restore added, python bindings + fixed + +* Wed Nov 2 2005 Daniel Veillard 0.0.1-1 +- created