diff --git a/0001-network-try-to-eliminate-default-network-conflict-du.patch b/0001-network-try-to-eliminate-default-network-conflict-du.patch new file mode 100644 index 0000000..a9fcc71 --- /dev/null +++ b/0001-network-try-to-eliminate-default-network-conflict-du.patch @@ -0,0 +1,88 @@ +From 935cd0c56643d28a5c60ff6658b16bd4c2fd920c Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Wed, 10 Sep 2014 13:10:45 -0400 +Subject: [PATCH] network: try to eliminate default network conflict during + package install + +Sometimes libvirt is installed on a host that is already using the +network 192.168.122.0/24. If the libvirt-daemon-config-network package +is installed, this creates a conflict, since that package has been +hard-coded to create a virtual network that also uses +192.168.122.0/24. In the past libvirt has attempted to warn of / +remediate this situation by checking for conflicting routes when the +network is started, but it turns out that isn't always useful (for +example in the case that the *other* interface/network creating the +conflict hasn't yet been started at the time libvirtd start its own +networks). + +This patch attempts to catch the problem earlier - at install +time. During the %post install script for +libvirt-daemon-config-network, we use a case statement to look through +the output of "ip route show" for a route that exactly matches +192.168.122.0/24, and if found we search for a similar route that +*doesn't* match (e.g. 192.168.124.0/24) (note that the search starts +with "124" instead of 123 because of reports of people already +modifying their L1 host's network to 192.168.123.0/24 in an attempt to +solve exactly the problem we are also trying to solve). When we find +an available route, we just replace all occurrences of "122" in the +default.xml that is being created with the newly found 192.168 +subnet. This could obviously be made more complicated - examine the +template defaul.xml to automatically determine the existing network +address and mask rather than hard coding it in the specfile, etc, but +this scripting is simpler and gets the job done as long as we continue +to use 192.168.122.0/24 in the template. (If anyone with mad bash +skillz wants to suggest something to do that, by all means please do). + +This is intended to at least "further reduce" occurrence of the +problems detailed in: + + https://bugzilla.redhat.com/show_bug.cgi?id=811967 + +(cherry picked from commit 5f71959667e4902d738a849e7c9391e794fccf22) +--- + libvirt.spec.in | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index 4dc801b..75a91f5 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -1732,8 +1732,37 @@ fi + %if %{with_network} + %post daemon-config-network + if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ; then ++ # see if the network used by default network creates a conflict, ++ # and try to resolve it ++ # NB: 192.168.122.0/24 is used in the default.xml template file; ++ # do not modify any of those values here without also modifying ++ # them in the template. ++ orig_sub=122 ++ sub=${orig_sub} ++ nl=' ++' ++ routes="${nl}$(ip route show | cut -d' ' -f1)" ++ case ${routes} in ++ *"${nl}192.168.${orig_sub}.0/24${nl}"*) ++ # there was a match, so we need to look for an unused subnet ++ for new_sub in $(seq 124 254); do ++ case ${routes} in ++ *"${nl}192.168.${new_sub}.0/24${nl}"*) ++ ;; ++ *) ++ sub=$new_sub ++ break; ++ ;; ++ esac ++ done ++ ;; ++ *) ++ ;; ++ esac ++ + UUID=`/usr/bin/uuidgen` +- sed -e "s,,\n $UUID," \ ++ sed -e "s/${orig_sub}/${sub}/g" \ ++ -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 diff --git a/0002-network-detect-conflicting-route-even-if-it-is-the-f.patch b/0002-network-detect-conflicting-route-even-if-it-is-the-f.patch new file mode 100644 index 0000000..b2164dd --- /dev/null +++ b/0002-network-detect-conflicting-route-even-if-it-is-the-f.patch @@ -0,0 +1,32 @@ +From ed1efa32c71ba195a16bb63da4ee532d8a6c8a99 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Mon, 15 Sep 2014 13:30:08 -0400 +Subject: [PATCH] network: detect conflicting route even if it is the final + entry + +This is a folloup to commit 5f719596, which checks for a route +conflicting with the standard libvirt default network subnet +(192.168.122.0/24). It turns out that $() strips the trailing newline +from the output of "ip route show", so there would be no match if the +route we were looking for was the final line of output. This can be +solved by adding ${nl} to the end of the output (just as we were +already adding it at the beginning of the output). + +(cherry picked from commit 22048ae61dbb7876d17bcf7dbedf9e8d1cf98d4e) +--- + libvirt.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index 75a91f5..0741c73 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -1741,7 +1741,7 @@ if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ; + sub=${orig_sub} + nl=' + ' +- routes="${nl}$(ip route show | cut -d' ' -f1)" ++ routes="${nl}$(ip route show | cut -d' ' -f1)${nl}" + case ${routes} in + *"${nl}192.168.${orig_sub}.0/24${nl}"*) + # there was a match, so we need to look for an unused subnet diff --git a/0003-rpc-reformat-the-flow-to-make-a-bit-more-sense.patch b/0003-rpc-reformat-the-flow-to-make-a-bit-more-sense.patch new file mode 100644 index 0000000..42e4acd --- /dev/null +++ b/0003-rpc-reformat-the-flow-to-make-a-bit-more-sense.patch @@ -0,0 +1,131 @@ +From 00d63796318b065479eda661ab83503cc1cf8446 Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Sun, 7 Sep 2014 17:08:57 +0200 +Subject: [PATCH] rpc: reformat the flow to make a bit more sense + +Just remove useless "else". Best viewed with '-w'. + +Signed-off-by: Martin Kletzander +(cherry picked from commit 3951d4a6d3d5867eadc82814e8dd9a61d19b68cf) +--- + src/rpc/virnetsocket.c | 94 +++++++++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 47 deletions(-) + +diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c +index 9780e17..306c9ea 100644 +--- a/src/rpc/virnetsocket.c ++++ b/src/rpc/virnetsocket.c +@@ -574,66 +574,66 @@ int virNetSocketNewConnectUNIX(const char *path, + + retry: + if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) { ++ int status = 0; ++ pid_t pid = 0; ++ + if (!spawnDaemon) { + virReportSystemError(errno, _("Failed to connect socket to '%s'"), + path); + goto error; +- } else { +- int status = 0; +- pid_t pid = 0; +- +- if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { +- virReportSystemError(errno, "%s", _("Failed to create socket")); +- goto error; +- } ++ } + +- /* +- * We have to fork() here, because umask() is set +- * per-process, chmod() is racy and fchmod() has undefined +- * behaviour on sockets according to POSIX, so it doesn't +- * work outside Linux. +- */ +- if ((pid = virFork()) < 0) +- goto error; ++ if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { ++ virReportSystemError(errno, "%s", _("Failed to create socket")); ++ goto error; ++ } + +- if (pid == 0) { +- umask(0077); +- if (bind(passfd, &remoteAddr.data.sa, remoteAddr.len) < 0) +- _exit(EXIT_FAILURE); ++ /* ++ * We have to fork() here, because umask() is set ++ * per-process, chmod() is racy and fchmod() has undefined ++ * behaviour on sockets according to POSIX, so it doesn't ++ * work outside Linux. ++ */ ++ if ((pid = virFork()) < 0) ++ goto error; + +- _exit(EXIT_SUCCESS); +- } ++ if (pid == 0) { ++ umask(0077); ++ if (bind(passfd, &remoteAddr.data.sa, remoteAddr.len) < 0) ++ _exit(EXIT_FAILURE); + +- if (virProcessWait(pid, &status, false) < 0) +- goto error; ++ _exit(EXIT_SUCCESS); ++ } + +- if (status != EXIT_SUCCESS) { +- /* +- * OK, so the subprocces failed to bind() the socket. This may mean +- * that another daemon was starting at the same time and succeeded +- * with its bind(). So we'll try connecting again, but this time +- * without spawning the daemon. +- */ +- spawnDaemon = false; +- goto retry; +- } ++ if (virProcessWait(pid, &status, false) < 0) ++ goto error; + +- if (listen(passfd, 0) < 0) { +- virReportSystemError(errno, "%s", +- _("Failed to listen on socket that's about " +- "to be passed to the daemon")); +- goto error; +- } ++ if (status != EXIT_SUCCESS) { ++ /* ++ * OK, so the subprocces failed to bind() the socket. This may mean ++ * that another daemon was starting at the same time and succeeded ++ * with its bind(). So we'll try connecting again, but this time ++ * without spawning the daemon. ++ */ ++ spawnDaemon = false; ++ goto retry; ++ } + +- if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) { +- virReportSystemError(errno, _("Failed to connect socket to '%s'"), +- path); +- goto error; +- } ++ if (listen(passfd, 0) < 0) { ++ virReportSystemError(errno, "%s", ++ _("Failed to listen on socket that's about " ++ "to be passed to the daemon")); ++ goto error; ++ } + +- if (virNetSocketForkDaemon(binary, passfd) < 0) +- goto error; ++ if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) { ++ virReportSystemError(errno, _("Failed to connect socket to '%s'"), ++ path); ++ goto error; + } ++ ++ if (virNetSocketForkDaemon(binary, passfd) < 0) ++ goto error; + } + + localAddr.len = sizeof(localAddr.data); diff --git a/0004-remove-redundant-pidfile-path-constructions.patch b/0004-remove-redundant-pidfile-path-constructions.patch new file mode 100644 index 0000000..6fd06f6 --- /dev/null +++ b/0004-remove-redundant-pidfile-path-constructions.patch @@ -0,0 +1,233 @@ +From 5217124c8f276a9d35b60470a332d887af4cc446 Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Sun, 7 Sep 2014 19:52:34 +0200 +Subject: [PATCH] remove redundant pidfile path constructions + +Signed-off-by: Martin Kletzander +(cherry picked from commit 8035f2e6f2db7fc0b74b639deb7eff64957692bc) +--- + daemon/libvirtd.c | 41 ++++----------------------------------- + src/libvirt_private.syms | 1 + + src/locking/lock_daemon.c | 42 ++++------------------------------------ + src/util/virpidfile.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- + src/util/virpidfile.h | 7 ++++++- + 5 files changed, 63 insertions(+), 77 deletions(-) + +diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c +index 0503cd0..61f5486 100644 +--- a/daemon/libvirtd.c ++++ b/daemon/libvirtd.c +@@ -251,41 +251,6 @@ static int daemonForkIntoBackground(const char *argv0) + + + static int +-daemonPidFilePath(bool privileged, +- char **pidfile) +-{ +- if (privileged) { +- if (VIR_STRDUP(*pidfile, LOCALSTATEDIR "/run/libvirtd.pid") < 0) +- goto error; +- } else { +- char *rundir = NULL; +- mode_t old_umask; +- +- if (!(rundir = virGetUserRuntimeDirectory())) +- goto error; +- +- old_umask = umask(077); +- if (virFileMakePath(rundir) < 0) { +- umask(old_umask); +- goto error; +- } +- umask(old_umask); +- +- if (virAsprintf(pidfile, "%s/libvirtd.pid", rundir) < 0) { +- VIR_FREE(rundir); +- goto error; +- } +- +- VIR_FREE(rundir); +- } +- +- return 0; +- +- error: +- return -1; +-} +- +-static int + daemonUnixSocketPaths(struct daemonConfig *config, + bool privileged, + char **sockfile, +@@ -1313,8 +1278,10 @@ int main(int argc, char **argv) { + } + + if (!pid_file && +- daemonPidFilePath(privileged, +- &pid_file) < 0) { ++ virPidFileConstructPath(privileged, ++ LOCALSTATEDIR, ++ "libvirtd", ++ &pid_file) < 0) { + VIR_ERROR(_("Can't determine pid file path.")); + exit(EXIT_FAILURE); + } +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 71fc063..f8d9b95 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1773,6 +1773,7 @@ virPCIIsVirtualFunction; + virPidFileAcquire; + virPidFileAcquirePath; + virPidFileBuildPath; ++virPidFileConstructPath; + virPidFileDelete; + virPidFileDeletePath; + virPidFileRead; +diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c +index 02d77e3..fe7cfb8 100644 +--- a/src/locking/lock_daemon.c ++++ b/src/locking/lock_daemon.c +@@ -366,42 +366,6 @@ virLockDaemonForkIntoBackground(const char *argv0) + + + static int +-virLockDaemonPidFilePath(bool privileged, +- char **pidfile) +-{ +- if (privileged) { +- if (VIR_STRDUP(*pidfile, LOCALSTATEDIR "/run/virtlockd.pid") < 0) +- goto error; +- } else { +- char *rundir = NULL; +- mode_t old_umask; +- +- if (!(rundir = virGetUserRuntimeDirectory())) +- goto error; +- +- old_umask = umask(077); +- if (virFileMakePath(rundir) < 0) { +- umask(old_umask); +- goto error; +- } +- umask(old_umask); +- +- if (virAsprintf(pidfile, "%s/virtlockd.pid", rundir) < 0) { +- VIR_FREE(rundir); +- goto error; +- } +- +- VIR_FREE(rundir); +- } +- +- return 0; +- +- error: +- return -1; +-} +- +- +-static int + virLockDaemonUnixSocketPaths(bool privileged, + char **sockfile) + { +@@ -1283,8 +1247,10 @@ int main(int argc, char **argv) { + } + + if (!pid_file && +- virLockDaemonPidFilePath(privileged, +- &pid_file) < 0) { ++ virPidFileConstructPath(privileged, ++ LOCALSTATEDIR, ++ "virtlockd", ++ &pid_file) < 0) { + VIR_ERROR(_("Can't determine pid file path.")); + exit(EXIT_FAILURE); + } +diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c +index 1d9a1c5..19ec103 100644 +--- a/src/util/virpidfile.c ++++ b/src/util/virpidfile.c +@@ -1,7 +1,7 @@ + /* + * virpidfile.c: manipulation of pidfiles + * +- * Copyright (C) 2010-2012 Red Hat, Inc. ++ * Copyright (C) 2010-2012, 2014 Red Hat, Inc. + * Copyright (C) 2006, 2007 Binary Karma + * Copyright (C) 2006 Shuveb Hussain + * +@@ -521,3 +521,50 @@ int virPidFileRelease(const char *dir, + VIR_FREE(pidfile); + return rc; + } ++ ++ ++int ++virPidFileConstructPath(bool privileged, ++ const char *statedir, ++ const char *progname, ++ char **pidfile) ++{ ++ if (privileged) { ++ /* ++ * This is here just to allow calling this function with ++ * statedir == NULL; of course only when !privileged. ++ */ ++ if (!statedir) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ "%s", _("No statedir specified")); ++ goto cleanup; ++ } ++ if (virAsprintf(pidfile, "%s/run/%s.pid", statedir, progname) < 0) ++ goto cleanup; ++ } else { ++ char *rundir = NULL; ++ mode_t old_umask; ++ ++ if (!(rundir = virGetUserRuntimeDirectory())) ++ goto error; ++ ++ old_umask = umask(077); ++ if (virFileMakePath(rundir) < 0) { ++ umask(old_umask); ++ goto error; ++ } ++ umask(old_umask); ++ ++ if (virAsprintf(pidfile, "%s/%s.pid", rundir, progname) < 0) { ++ VIR_FREE(rundir); ++ goto error; ++ } ++ ++ VIR_FREE(rundir); ++ } ++ ++ return 0; ++ ++ error: ++ return -1; ++} +diff --git a/src/util/virpidfile.h b/src/util/virpidfile.h +index 2720206..ca1dbff 100644 +--- a/src/util/virpidfile.h ++++ b/src/util/virpidfile.h +@@ -1,7 +1,7 @@ + /* + * virpidfile.h: manipulation of pidfiles + * +- * Copyright (C) 2010-2011 Red Hat, Inc. ++ * Copyright (C) 2010-2011, 2014 Red Hat, Inc. + * Copyright (C) 2006, 2007 Binary Karma + * Copyright (C) 2006 Shuveb Hussain + * +@@ -69,4 +69,9 @@ int virPidFileRelease(const char *dir, + const char *name, + int fd); + ++int virPidFileConstructPath(bool privileged, ++ const char *statedir, ++ const char *progname, ++ char **pidfile); ++ + #endif /* __VIR_PIDFILE_H__ */ diff --git a/0005-util-fix-potential-leak-in-error-codepath.patch b/0005-util-fix-potential-leak-in-error-codepath.patch new file mode 100644 index 0000000..243cc85 --- /dev/null +++ b/0005-util-fix-potential-leak-in-error-codepath.patch @@ -0,0 +1,62 @@ +From 0bf4b718fafa22c67f84ffd0b4434a5c7b1bce94 Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Sun, 7 Sep 2014 20:07:49 +0200 +Subject: [PATCH] util: fix potential leak in error codepath + +Signed-off-by: Martin Kletzander +(cherry picked from commit aaaa2d56bd47556b6857ecca33e4b28ab36c8488) +--- + src/util/virpidfile.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c +index 19ec103..dd29701 100644 +--- a/src/util/virpidfile.c ++++ b/src/util/virpidfile.c +@@ -529,6 +529,9 @@ virPidFileConstructPath(bool privileged, + const char *progname, + char **pidfile) + { ++ int ret = -1; ++ char *rundir = NULL; ++ + if (privileged) { + /* + * This is here just to allow calling this function with +@@ -542,29 +545,27 @@ virPidFileConstructPath(bool privileged, + if (virAsprintf(pidfile, "%s/run/%s.pid", statedir, progname) < 0) + goto cleanup; + } else { +- char *rundir = NULL; + mode_t old_umask; + + if (!(rundir = virGetUserRuntimeDirectory())) +- goto error; ++ goto cleanup; + + old_umask = umask(077); + if (virFileMakePath(rundir) < 0) { + umask(old_umask); +- goto error; ++ goto cleanup; + } + umask(old_umask); + + if (virAsprintf(pidfile, "%s/%s.pid", rundir, progname) < 0) { + VIR_FREE(rundir); +- goto error; ++ goto cleanup; + } + +- VIR_FREE(rundir); + } + +- return 0; +- +- error: +- return -1; ++ ret = 0; ++ cleanup: ++ VIR_FREE(rundir); ++ return ret; + } diff --git a/0006-util-get-rid-of-unnecessary-umask-call.patch b/0006-util-get-rid-of-unnecessary-umask-call.patch new file mode 100644 index 0000000..06f1494 --- /dev/null +++ b/0006-util-get-rid-of-unnecessary-umask-call.patch @@ -0,0 +1,37 @@ +From 51ceb3ceaa2f192a0612b9a794d3282a059d2c9d Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Sun, 7 Sep 2014 20:09:36 +0200 +Subject: [PATCH] util: get rid of unnecessary umask() call + +Signed-off-by: Martin Kletzander +(cherry picked from commit d00c6fd25854bfd4822f6ce3d769a8ca132ec31b) +--- + src/util/virpidfile.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c +index dd29701..a3b8846 100644 +--- a/src/util/virpidfile.c ++++ b/src/util/virpidfile.c +@@ -545,17 +545,15 @@ virPidFileConstructPath(bool privileged, + if (virAsprintf(pidfile, "%s/run/%s.pid", statedir, progname) < 0) + goto cleanup; + } else { +- mode_t old_umask; +- + if (!(rundir = virGetUserRuntimeDirectory())) + goto cleanup; + +- old_umask = umask(077); +- if (virFileMakePath(rundir) < 0) { +- umask(old_umask); ++ if (virFileMakePathWithMode(rundir, 0700) < 0) { ++ virReportSystemError(errno, ++ _("Cannot create user runtime directory '%s'"), ++ rundir); + goto cleanup; + } +- umask(old_umask); + + if (virAsprintf(pidfile, "%s/%s.pid", rundir, progname) < 0) { + VIR_FREE(rundir); diff --git a/0007-rpc-make-daemon-spawning-a-bit-more-intelligent.patch b/0007-rpc-make-daemon-spawning-a-bit-more-intelligent.patch new file mode 100644 index 0000000..a8563b5 --- /dev/null +++ b/0007-rpc-make-daemon-spawning-a-bit-more-intelligent.patch @@ -0,0 +1,131 @@ +From 28b27787c5bb545df3c178fef682151c45b66784 Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Mon, 8 Sep 2014 07:46:39 +0200 +Subject: [PATCH] rpc: make daemon spawning a bit more intelligent + +This way it behaves more like the daemon itself does (acquiring a +pidfile, deleting the socket before binding, etc.). + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=927369 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1138604 + +Signed-off-by: Martin Kletzander +--- + src/rpc/virnetsocket.c | 57 ++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 51 insertions(+), 6 deletions(-) + +diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c +index 306c9ea..fa9ba99 100644 +--- a/src/rpc/virnetsocket.c ++++ b/src/rpc/virnetsocket.c +@@ -51,9 +51,11 @@ + #include "virlog.h" + #include "virfile.h" + #include "virthread.h" ++#include "virpidfile.h" + #include "virprobe.h" + #include "virprocess.h" + #include "virstring.h" ++#include "dirname.h" + #include "passfd.h" + + #if WITH_SSH2 +@@ -544,7 +546,10 @@ int virNetSocketNewConnectUNIX(const char *path, + const char *binary, + virNetSocketPtr *retsock) + { ++ char *binname = NULL; ++ char *pidpath = NULL; + int fd, passfd = -1; ++ int pidfd = -1; + virSocketAddr localAddr; + virSocketAddr remoteAddr; + +@@ -583,16 +588,45 @@ int virNetSocketNewConnectUNIX(const char *path, + goto error; + } + ++ if (!(binname = last_component(binary)) || binname[0] == '\0') { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot determine basename for binary '%s'"), ++ binary); ++ goto error; ++ } ++ ++ if (virPidFileConstructPath(false, NULL, binname, &pidpath) < 0) ++ goto error; ++ ++ if ((pidfd = virPidFileAcquirePath(pidpath, false, getpid())) < 0) { ++ /* ++ * This can happen in a very rare case of two clients spawning two ++ * daemons at the same time, and the error in the logs that gets ++ * reset here can be a clue to some future debugging. ++ */ ++ virResetLastError(); ++ spawnDaemon = false; ++ goto retry; ++ } ++ + if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + virReportSystemError(errno, "%s", _("Failed to create socket")); + goto error; + } + + /* +- * We have to fork() here, because umask() is set +- * per-process, chmod() is racy and fchmod() has undefined +- * behaviour on sockets according to POSIX, so it doesn't +- * work outside Linux. ++ * We already even acquired the pidfile, so noone else should be using ++ * @path right now. So we're OK to unlink it and paying attention to ++ * the return value makes no real sense here. Only if it's not an ++ * abstract socket, of course. ++ */ ++ if (path[0] != '@') ++ unlink(path); ++ ++ /* ++ * We have to fork() here, because umask() is set per-process, chmod() ++ * is racy and fchmod() has undefined behaviour on sockets according to ++ * POSIX, so it doesn't work outside Linux. + */ + if ((pid = virFork()) < 0) + goto error; +@@ -612,8 +646,9 @@ int virNetSocketNewConnectUNIX(const char *path, + /* + * OK, so the subprocces failed to bind() the socket. This may mean + * that another daemon was starting at the same time and succeeded +- * with its bind(). So we'll try connecting again, but this time +- * without spawning the daemon. ++ * with its bind() (even though it should not happen because we ++ * using a pidfile for the race). So we'll try connecting again, ++ * but this time without spawning the daemon. + */ + spawnDaemon = false; + goto retry; +@@ -632,6 +667,12 @@ int virNetSocketNewConnectUNIX(const char *path, + goto error; + } + ++ /* ++ * Do we need to eliminate the super-rare race here any more? It would ++ * need incorporating the following VIR_FORCE_CLOSE() into a ++ * virCommandHook inside a virNetSocketForkDaemon(). ++ */ ++ VIR_FORCE_CLOSE(pidfd); + if (virNetSocketForkDaemon(binary, passfd) < 0) + goto error; + } +@@ -648,8 +689,12 @@ int virNetSocketNewConnectUNIX(const char *path, + return 0; + + error: ++ if (pidfd > 0) ++ virPidFileDeletePath(pidpath); ++ VIR_FREE(pidpath); + VIR_FORCE_CLOSE(fd); + VIR_FORCE_CLOSE(passfd); ++ VIR_FORCE_CLOSE(pidfd); + if (spawnDaemon) + unlink(path); + return -1; diff --git a/0008-spec-Don-t-build-wireshark-on-f21-non-upstream.patch b/0008-spec-Don-t-build-wireshark-on-f21-non-upstream.patch new file mode 100644 index 0000000..13fb17d --- /dev/null +++ b/0008-spec-Don-t-build-wireshark-on-f21-non-upstream.patch @@ -0,0 +1,24 @@ +From 2950887a9e7800e0421dadb0b9c348adb087deca Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Mon, 15 Sep 2014 14:49:35 -0400 +Subject: [PATCH] spec: Don't build wireshark on f21 (non upstream) + +wireshark bug: https://bugzilla.redhat.com/show_bug.cgi?id=1129419 +--- + libvirt.spec.in | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index 0741c73..7d8748d 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -267,6 +267,9 @@ + %if 0%{?fedora} >= 21 + %define with_wireshark 0%{!?_without_wireshark:1} + %endif ++# Except this is presently busted on F21/rawhide with wireshark 1.12.0 ++# https://bugzilla.redhat.com/show_bug.cgi?id=1129419 ++%define with_wireshark 0 + + # Disable some drivers when building without libvirt daemon. + # The logic is the same as in configure.ac diff --git a/libvirt.spec b/libvirt.spec index 5d72bdd..2391a2a 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -366,7 +366,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 1.2.8 -Release: 1%{?dist}%{?extra_release} +Release: 2%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -377,6 +377,21 @@ URL: http://libvirt.org/ %endif Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz +# Generate non-colliding network IP range at RPM install time (bz +# #811967) +Patch0001: 0001-network-try-to-eliminate-default-network-conflict-du.patch +Patch0002: 0002-network-detect-conflicting-route-even-if-it-is-the-f.patch +# Fix directory creation at session daemon startup (bz #1139672) +# (Patch 5 is posted but not in git as of 2014-09-15) +Patch0003: 0003-rpc-reformat-the-flow-to-make-a-bit-more-sense.patch +Patch0004: 0004-remove-redundant-pidfile-path-constructions.patch +Patch0005: 0005-util-fix-potential-leak-in-error-codepath.patch +Patch0006: 0006-util-get-rid-of-unnecessary-umask-call.patch +Patch0007: 0007-rpc-make-daemon-spawning-a-bit-more-intelligent.patch +# Disable wireshark building, currently broken on f21/rawhide +# Nonupstream patch +Patch0008: 0008-spec-Don-t-build-wireshark-on-f21-non-upstream.patch + %if %{with_libvirtd} Requires: libvirt-daemon = %{version}-%{release} %if %{with_network} @@ -1201,6 +1216,21 @@ driver %prep %setup -q +# Generate non-colliding network IP range at RPM install time (bz +# #811967) +%patch0001 -p1 +%patch0002 -p1 +# Fix directory creation at session daemon startup (bz #1139672) +# (Patch 5 is posted but not in git as of 2014-09-15) +%patch0003 -p1 +%patch0004 -p1 +%patch0005 -p1 +%patch0006 -p1 +%patch0007 -p1 +# Disable wireshark building, currently broken on f21/rawhide +# Nonupstream patch +%patch0008 -p1 + %build %if ! %{with_xen} %define _without_xen --without-xen @@ -1735,8 +1765,37 @@ fi %if %{with_network} %post daemon-config-network if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ; then + # see if the network used by default network creates a conflict, + # and try to resolve it + # NB: 192.168.122.0/24 is used in the default.xml template file; + # do not modify any of those values here without also modifying + # them in the template. + orig_sub=122 + sub=${orig_sub} + nl=' +' + routes="${nl}$(ip route show | cut -d' ' -f1)${nl}" + case ${routes} in + *"${nl}192.168.${orig_sub}.0/24${nl}"*) + # there was a match, so we need to look for an unused subnet + for new_sub in $(seq 124 254); do + case ${routes} in + *"${nl}192.168.${new_sub}.0/24${nl}"*) + ;; + *) + sub=$new_sub + break; + ;; + esac + done + ;; + *) + ;; + esac + UUID=`/usr/bin/uuidgen` - sed -e "s,,\n $UUID," \ + sed -e "s/${orig_sub}/${sub}/g" \ + -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 @@ -2250,6 +2309,11 @@ exit 0 %doc examples/systemtap %changelog +* Mon Sep 15 2014 Cole Robinson - 1.2.8-2 +- Generate non-colliding network IP range at RPM install time (bz #811967) +- Fix directory creation at session daemon startup (bz #1139672) +- Disable wireshark building, currently broken on f21/rawhide + * Fri Sep 5 2014 Daniel P. Berrange - 1.2.8-1 - Update to 1.2.8 release