[libvirt] Generate non-colliding network IP range at RPM install time (bz #811967) Fix directory creation at s

Cole Robinson crobinso at fedoraproject.org
Mon Sep 15 18:52:10 UTC 2014


commit a540751e83d9508f4d5452fbf0f4f26e11ba9dd4
Author: Cole Robinson <crobinso at redhat.com>
Date:   Mon Sep 15 14:52:07 2014 -0400

    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

 ...-to-eliminate-default-network-conflict-du.patch |   88 ++++++++
 ...ect-conflicting-route-even-if-it-is-the-f.patch |   32 +++
 ...eformat-the-flow-to-make-a-bit-more-sense.patch |  131 +++++++++++
 ...move-redundant-pidfile-path-constructions.patch |  233 ++++++++++++++++++++
 ...util-fix-potential-leak-in-error-codepath.patch |   62 +++++
 0006-util-get-rid-of-unnecessary-umask-call.patch  |   37 +++
 ...ke-daemon-spawning-a-bit-more-intelligent.patch |  131 +++++++++++
 ...Don-t-build-wireshark-on-f21-non-upstream.patch |   24 ++
 libvirt.spec                                       |   68 ++++++-
 9 files changed, 804 insertions(+), 2 deletions(-)
---
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 <laine at laine.org>
+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,</name>,</name>\n  <uuid>$UUID</uuid>," \
++    sed -e "s/${orig_sub}/${sub}/g" \
++        -e "s,</name>,</name>\n  <uuid>$UUID</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 <laine at laine.org>
+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 <mkletzan at redhat.com>
+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 <mkletzan at redhat.com>
+(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 <mkletzan at redhat.com>
+Date: Sun, 7 Sep 2014 19:52:34 +0200
+Subject: [PATCH] remove redundant pidfile path constructions
+
+Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
+(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 <mkletzan at redhat.com>
+Date: Sun, 7 Sep 2014 20:07:49 +0200
+Subject: [PATCH] util: fix potential leak in error codepath
+
+Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
+(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 <mkletzan at redhat.com>
+Date: Sun, 7 Sep 2014 20:09:36 +0200
+Subject: [PATCH] util: get rid of unnecessary umask() call
+
+Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
+(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 <mkletzan at redhat.com>
+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 <mkletzan at redhat.com>
+---
+ 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 <crobinso at redhat.com>
+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,</name>,</name>\n  <uuid>$UUID</uuid>," \
+    sed -e "s/${orig_sub}/${sub}/g" \
+        -e "s,</name>,</name>\n  <uuid>$UUID</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 <crobinso at redhat.com> - 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 <berrange at redhat.com> - 1.2.8-1
 - Update to 1.2.8 release
 


More information about the scm-commits mailing list