diff --git a/0001-storage-split-off-code-for-calling-rbd_list.patch b/0001-storage-split-off-code-for-calling-rbd_list.patch
new file mode 100644
index 0000000..1689aa7
--- /dev/null
+++ b/0001-storage-split-off-code-for-calling-rbd_list.patch
@@ -0,0 +1,149 @@
+From 092320f10b47bd6aca1f29278fcdc6b0efaf636a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 18 Mar 2019 10:58:48 +0000
+Subject: [PATCH 1/5] storage: split off code for calling rbd_list
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The rbd_list method has a quite unpleasant signature returning an
+array of strings in a single buffer instead of an array. It is
+being deprecated in favour of rbd_list2. To maintain clarity of
+code when supporting both APIs in parallel, split the rbd_list
+code out into a separate method.
+
+In splitting this we now honour the rbd_list failures.
+
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 28c8403ed07896d6d7e06d7726ed904027206719)
+---
+ src/storage/storage_backend_rbd.c | 83 +++++++++++++++++++++----------
+ 1 file changed, 58 insertions(+), 25 deletions(-)
+
+diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
+index 2b7af1db23..0865163756 100644
+--- a/src/storage/storage_backend_rbd.c
++++ b/src/storage/storage_backend_rbd.c
+@@ -565,19 +565,68 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr vol,
+     return ret;
+ }
+ 
++
++static char **
++virStorageBackendRBDGetVolNames(virStorageBackendRBDStatePtr ptr)
++{
++    char **names = NULL;
++    size_t nnames = 0;
++    int rc;
++    size_t max_size = 1024;
++    VIR_AUTOFREE(char *) namebuf = NULL;
++    const char *name;
++
++    while (true) {
++        if (VIR_ALLOC_N(namebuf, max_size) < 0)
++            goto error;
++
++        rc = rbd_list(ptr->ioctx, namebuf, &max_size);
++        if (rc >= 0)
++            break;
++        if (rc != -ERANGE) {
++            virReportSystemError(-rc, "%s", _("Unable to list RBD images"));
++            goto error;
++        }
++        VIR_FREE(namebuf);
++    }
++
++    for (name = namebuf; name < namebuf + max_size;) {
++        VIR_AUTOFREE(char *) namedup = NULL;
++
++        if (STREQ(name, ""))
++            break;
++
++        if (VIR_STRDUP(namedup, name) < 0)
++            goto error;
++
++        if (VIR_APPEND_ELEMENT(names, nnames, namedup) < 0)
++            goto error;
++
++        name += strlen(name) + 1;
++    }
++
++    if (VIR_EXPAND_N(names, nnames, 1) < 0)
++        goto error;
++
++    return names;
++
++ error:
++    virStringListFreeCount(names, nnames);
++    return NULL;
++}
++
++
+ static int
+ virStorageBackendRBDRefreshPool(virStoragePoolObjPtr pool)
+ {
+-    size_t max_size = 1024;
+     int ret = -1;
+-    int len = -1;
+     int r = 0;
+-    char *name;
+     virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
+     virStorageBackendRBDStatePtr ptr = NULL;
+     struct rados_cluster_stat_t clusterstat;
+     struct rados_pool_stat_t poolstat;
+-    VIR_AUTOFREE(char *) names = NULL;
++    char **names = NULL;
++    size_t i;
+ 
+     if (!(ptr = virStorageBackendRBDNewState(pool)))
+         goto cleanup;
+@@ -602,33 +651,16 @@ virStorageBackendRBDRefreshPool(virStoragePoolObjPtr pool)
+               def->source.name, clusterstat.kb, clusterstat.kb_avail,
+               poolstat.num_bytes);
+ 
+-    while (true) {
+-        if (VIR_ALLOC_N(names, max_size) < 0)
+-            goto cleanup;
+-
+-        len = rbd_list(ptr->ioctx, names, &max_size);
+-        if (len >= 0)
+-            break;
+-        if (len != -ERANGE) {
+-            VIR_WARN("%s", "A problem occurred while listing RBD images");
+-            goto cleanup;
+-        }
+-        VIR_FREE(names);
+-    }
++    if (!(names = virStorageBackendRBDGetVolNames(ptr)))
++        goto cleanup;
+ 
+-    for (name = names; name < names + max_size;) {
++    for (i = 0; names[i] != NULL; i++) {
+         VIR_AUTOPTR(virStorageVolDef) vol = NULL;
+ 
+-        if (STREQ(name, ""))
+-            break;
+-
+         if (VIR_ALLOC(vol) < 0)
+             goto cleanup;
+ 
+-        if (VIR_STRDUP(vol->name, name) < 0)
+-            goto cleanup;
+-
+-        name += strlen(name) + 1;
++        VIR_STEAL_PTR(vol->name, names[i]);
+ 
+         r = volStorageBackendRBDRefreshVolInfo(vol, pool, ptr);
+ 
+@@ -661,6 +693,7 @@ virStorageBackendRBDRefreshPool(virStoragePoolObjPtr pool)
+     ret = 0;
+ 
+  cleanup:
++    virStringListFree(names);
+     virStorageBackendRBDFreeState(&ptr);
+     return ret;
+ }
+-- 
+2.20.1
+
diff --git a/0002-storage-add-support-for-new-rbd_list2-method.patch b/0002-storage-add-support-for-new-rbd_list2-method.patch
new file mode 100644
index 0000000..b03dbee
--- /dev/null
+++ b/0002-storage-add-support-for-new-rbd_list2-method.patch
@@ -0,0 +1,96 @@
+From e8ec2592202387cca8e45cf15bd55ed5a952f3e3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 18 Mar 2019 11:11:38 +0000
+Subject: [PATCH 2/5] storage: add support for new rbd_list2 method
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The rbd_list method has been deprecated in Ceph >= 14.0.0
+in favour of the new rbd_list2 method which populates an
+array of structs.
+
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 3aa190f2a43a632b542a6ba751a6c3ab4d51f1dd)
+---
+ m4/virt-storage-rbd.m4            |  1 +
+ src/storage/storage_backend_rbd.c | 43 +++++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+)
+
+diff --git a/m4/virt-storage-rbd.m4 b/m4/virt-storage-rbd.m4
+index 17e2115309..f3d9d04908 100644
+--- a/m4/virt-storage-rbd.m4
++++ b/m4/virt-storage-rbd.m4
+@@ -33,6 +33,7 @@ AC_DEFUN([LIBVIRT_STORAGE_CHECK_RBD], [
+       old_LIBS="$LIBS"
+       LIBS="$LIBS $LIBRBD_LIBS"
+       AC_CHECK_FUNCS([rbd_get_features],[],[LIBRBD_FOUND=no])
++      AC_CHECK_FUNCS([rbd_list2])
+       LIBS="$old_LIBS"
+     fi
+ 
+diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
+index 0865163756..bfc3419f9c 100644
+--- a/src/storage/storage_backend_rbd.c
++++ b/src/storage/storage_backend_rbd.c
+@@ -566,6 +566,48 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr vol,
+ }
+ 
+ 
++#ifdef HAVE_RBD_LIST2
++static char **
++virStorageBackendRBDGetVolNames(virStorageBackendRBDStatePtr ptr)
++{
++    char **names = NULL;
++    size_t nnames = 0;
++    int rc;
++    rbd_image_spec_t *images = NULL;
++    size_t nimages = 16;
++    size_t i;
++
++    while (true) {
++        if (VIR_ALLOC_N(images, nimages) < 0)
++            goto error;
++
++        rc = rbd_list2(ptr->ioctx, images, &nimages);
++        if (rc >= 0)
++            break;
++        if (rc != -ERANGE) {
++            virReportSystemError(-rc, "%s", _("Unable to list RBD images"));
++            goto error;
++        }
++    }
++
++    if (VIR_ALLOC_N(names, nimages + 1) < 0)
++        goto error;
++    nnames = nimages;
++
++    for (i = 0; i < nimages; i++)
++        VIR_STEAL_PTR(names[i], images->name);
++
++    return names;
++
++ error:
++    virStringListFreeCount(names, nnames);
++    rbd_image_spec_list_cleanup(images, nimages);
++    VIR_FREE(images);
++    return NULL;
++}
++
++#else /* ! HAVE_RBD_LIST2 */
++
+ static char **
+ virStorageBackendRBDGetVolNames(virStorageBackendRBDStatePtr ptr)
+ {
+@@ -614,6 +656,7 @@ virStorageBackendRBDGetVolNames(virStorageBackendRBDStatePtr ptr)
+     virStringListFreeCount(names, nnames);
+     return NULL;
+ }
++#endif /* ! HAVE_RBD_LIST2 */
+ 
+ 
+ static int
+-- 
+2.20.1
+
diff --git a/0003-network-improve-error-report-when-firewall-chain-cre.patch b/0003-network-improve-error-report-when-firewall-chain-cre.patch
new file mode 100644
index 0000000..2e99a73
--- /dev/null
+++ b/0003-network-improve-error-report-when-firewall-chain-cre.patch
@@ -0,0 +1,137 @@
+From b990740b12117eaaf2797141a53a30b41f07c791 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 18 Mar 2019 17:31:21 +0000
+Subject: [PATCH 3/5] network: improve error report when firewall chain
+ creation fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+During startup we create some top level chains in which all
+virtual network firewall rules will be placed. The upfront
+creation is done to avoid slowing down creation of individual
+virtual networks by checking for chain existance every time.
+
+There are some factors which can cause this upfront creation
+to fail and while a message will get into the libvirtd log
+this won't be seen by users who later try to start a virtual
+network. Instead they'll just get a message saying that the
+libvirt top level chain does not exist. This message is
+accurate, but unhelpful for solving the root cause.
+
+This patch thus saves any error during daemon startup and
+reports it when trying to create a virtual network later.
+
+Reviewed-by: Andrea Bolognani <abologna@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 9f4e35dc73ec9e940aa61bc7c140c2b800218ef3)
+---
+ src/network/bridge_driver.c          |  3 +--
+ src/network/bridge_driver_linux.c    | 31 +++++++++++++++++++++-------
+ src/network/bridge_driver_nop.c      |  3 +--
+ src/network/bridge_driver_platform.h |  2 +-
+ 4 files changed, 27 insertions(+), 12 deletions(-)
+
+diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
+index b3ca5b8a15..1da60f0a21 100644
+--- a/src/network/bridge_driver.c
++++ b/src/network/bridge_driver.c
+@@ -2108,8 +2108,7 @@ static void
+ networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup)
+ {
+     VIR_INFO("Reloading iptables rules");
+-    if (networkPreReloadFirewallRules(startup) < 0)
+-        return;
++    networkPreReloadFirewallRules(startup);
+     virNetworkObjListForEach(driver->networks,
+                              networkReloadFirewallRulesHelper,
+                              NULL);
+diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
+index b10d0a6c4d..c899f4b6d0 100644
+--- a/src/network/bridge_driver_linux.c
++++ b/src/network/bridge_driver_linux.c
+@@ -35,11 +35,25 @@ VIR_LOG_INIT("network.bridge_driver_linux");
+ 
+ #define PROC_NET_ROUTE "/proc/net/route"
+ 
+-int networkPreReloadFirewallRules(bool startup)
++static virErrorPtr errInit;
++
++void networkPreReloadFirewallRules(bool startup)
+ {
+-    int ret = iptablesSetupPrivateChains();
+-    if (ret < 0)
+-        return -1;
++    int rc;
++
++    /* We create global rules upfront as we don't want
++     * the perf hit of conditionally figuring out whether
++     * to create them each time a network is started.
++     *
++     * Any errors here are saved to be reported at time
++     * of starting the network though as that makes them
++     * more likely to be seen by a human
++     */
++    rc = iptablesSetupPrivateChains();
++    if (rc < 0) {
++        errInit = virSaveLastError();
++        virResetLastError();
++    }
+ 
+     /*
+      * If this is initial startup, and we just created the
+@@ -54,10 +68,8 @@ int networkPreReloadFirewallRules(bool startup)
+      * rules will be present. Thus we can safely just tell it
+      * to always delete from the builin chain
+      */
+-    if (startup && ret == 1)
++    if (startup && rc == 1)
+         iptablesSetDeletePrivate(false);
+-
+-    return 0;
+ }
+ 
+ 
+@@ -671,6 +683,11 @@ int networkAddFirewallRules(virNetworkDefPtr def)
+     virFirewallPtr fw = NULL;
+     int ret = -1;
+ 
++    if (errInit) {
++        virSetError(errInit);
++        return -1;
++    }
++
+     if (def->bridgeZone) {
+ 
+         /* if a firewalld zone has been specified, fail/log an error
+diff --git a/src/network/bridge_driver_nop.c b/src/network/bridge_driver_nop.c
+index a0e57012f9..ea9db338cb 100644
+--- a/src/network/bridge_driver_nop.c
++++ b/src/network/bridge_driver_nop.c
+@@ -19,9 +19,8 @@
+ 
+ #include <config.h>
+ 
+-int networkPreReloadFirewallRules(bool startup ATTRIBUTE_UNUSED)
++void networkPreReloadFirewallRules(bool startup ATTRIBUTE_UNUSED)
+ {
+-    return 0;
+ }
+ 
+ 
+diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driver_platform.h
+index baeb22bc3e..95fd64bdc7 100644
+--- a/src/network/bridge_driver_platform.h
++++ b/src/network/bridge_driver_platform.h
+@@ -58,7 +58,7 @@ struct _virNetworkDriverState {
+ typedef struct _virNetworkDriverState virNetworkDriverState;
+ typedef virNetworkDriverState *virNetworkDriverStatePtr;
+ 
+-int networkPreReloadFirewallRules(bool startup);
++void networkPreReloadFirewallRules(bool startup);
+ void networkPostReloadFirewallRules(bool startup);
+ 
+ int networkCheckRouteCollision(virNetworkDefPtr def);
+-- 
+2.20.1
+
diff --git a/0004-network-split-setup-of-ipv4-and-ipv6-top-level-chain.patch b/0004-network-split-setup-of-ipv4-and-ipv6-top-level-chain.patch
new file mode 100644
index 0000000..b7832a6
--- /dev/null
+++ b/0004-network-split-setup-of-ipv4-and-ipv6-top-level-chain.patch
@@ -0,0 +1,153 @@
+From 095c45036615a84c7150ea801d6932bdde1d5b49 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 18 Mar 2019 16:49:32 +0000
+Subject: [PATCH 4/5] network: split setup of ipv4 and ipv6 top level chains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+During startup libvirtd creates top level chains for both ipv4
+and ipv6 protocols. If this fails for any reason then startup
+of virtual networks is blocked.
+
+The default virtual network, however, only requires use of ipv4
+and some servers have ipv6 disabled so it is expected that ipv6
+chain creation will fail. There could equally be servers with
+no ipv4, only ipv6.
+
+This patch thus makes error reporting a little more fine grained
+so that it works more sensibly when either ipv4 or ipv6 is
+disabled on the server. Only the protocols that are actually
+used by the virtual network have errors reported.
+
+Reviewed-by: Andrea Bolognani <abologna@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 686803a1a2e1e0641916b1c9e2c7e3910fe598d4)
+---
+ src/network/bridge_driver_linux.c | 34 +++++++++++++++++++++++++------
+ src/util/viriptables.c            | 14 ++++---------
+ src/util/viriptables.h            |  2 +-
+ 3 files changed, 33 insertions(+), 17 deletions(-)
+
+diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
+index c899f4b6d0..50fc197134 100644
+--- a/src/network/bridge_driver_linux.c
++++ b/src/network/bridge_driver_linux.c
+@@ -35,10 +35,12 @@ VIR_LOG_INIT("network.bridge_driver_linux");
+ 
+ #define PROC_NET_ROUTE "/proc/net/route"
+ 
+-static virErrorPtr errInit;
++static virErrorPtr errInitV4;
++static virErrorPtr errInitV6;
+ 
+ void networkPreReloadFirewallRules(bool startup)
+ {
++    bool created = false;
+     int rc;
+ 
+     /* We create global rules upfront as we don't want
+@@ -49,11 +51,21 @@ void networkPreReloadFirewallRules(bool startup)
+      * of starting the network though as that makes them
+      * more likely to be seen by a human
+      */
+-    rc = iptablesSetupPrivateChains();
++    rc = iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV4);
+     if (rc < 0) {
+-        errInit = virSaveLastError();
++        errInitV4 = virSaveLastError();
+         virResetLastError();
+     }
++    if (rc)
++        created = true;
++
++    rc = iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV6);
++    if (rc < 0) {
++        errInitV6 = virSaveLastError();
++        virResetLastError();
++    }
++    if (rc)
++        created = true;
+ 
+     /*
+      * If this is initial startup, and we just created the
+@@ -68,7 +80,7 @@ void networkPreReloadFirewallRules(bool startup)
+      * rules will be present. Thus we can safely just tell it
+      * to always delete from the builin chain
+      */
+-    if (startup && rc == 1)
++    if (startup && created)
+         iptablesSetDeletePrivate(false);
+ }
+ 
+@@ -683,8 +695,18 @@ int networkAddFirewallRules(virNetworkDefPtr def)
+     virFirewallPtr fw = NULL;
+     int ret = -1;
+ 
+-    if (errInit) {
+-        virSetError(errInit);
++    if (errInitV4 &&
++        (virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
++         virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
++        virSetError(errInitV4);
++        return -1;
++    }
++
++    if (errInitV6 &&
++        (virNetworkDefGetIPByIndex(def, AF_INET6, 0) ||
++         virNetworkDefGetRouteByIndex(def, AF_INET6, 0) ||
++         def->ipv6nogw)) {
++        virSetError(errInitV6);
+         return -1;
+     }
+ 
+diff --git a/src/util/viriptables.c b/src/util/viriptables.c
+index d67b640a3b..0e3c0ad73a 100644
+--- a/src/util/viriptables.c
++++ b/src/util/viriptables.c
+@@ -127,7 +127,7 @@ iptablesPrivateChainCreate(virFirewallPtr fw,
+ 
+ 
+ int
+-iptablesSetupPrivateChains(void)
++iptablesSetupPrivateChains(virFirewallLayer layer)
+ {
+     virFirewallPtr fw = NULL;
+     int ret = -1;
+@@ -143,17 +143,11 @@ iptablesSetupPrivateChains(void)
+     };
+     bool changed = false;
+     iptablesGlobalChainData data[] = {
+-        { VIR_FIREWALL_LAYER_IPV4, "filter",
++        { layer, "filter",
+           filter_chains, ARRAY_CARDINALITY(filter_chains), &changed },
+-        { VIR_FIREWALL_LAYER_IPV4, "nat",
++        { layer, "nat",
+           natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
+-        { VIR_FIREWALL_LAYER_IPV4, "mangle",
+-          natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
+-        { VIR_FIREWALL_LAYER_IPV6, "filter",
+-          filter_chains, ARRAY_CARDINALITY(filter_chains), &changed },
+-        { VIR_FIREWALL_LAYER_IPV6, "nat",
+-          natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
+-        { VIR_FIREWALL_LAYER_IPV6, "mangle",
++        { layer, "mangle",
+           natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
+     };
+     size_t i;
+diff --git a/src/util/viriptables.h b/src/util/viriptables.h
+index 903f390f89..e680407ec8 100644
+--- a/src/util/viriptables.h
++++ b/src/util/viriptables.h
+@@ -24,7 +24,7 @@
+ # include "virsocketaddr.h"
+ # include "virfirewall.h"
+ 
+-int              iptablesSetupPrivateChains      (void);
++int              iptablesSetupPrivateChains      (virFirewallLayer layer);
+ 
+ void             iptablesSetDeletePrivate        (bool pvt);
+ 
+-- 
+2.20.1
+
diff --git a/0005-network-avoid-trying-to-create-global-firewall-rules.patch b/0005-network-avoid-trying-to-create-global-firewall-rules.patch
new file mode 100644
index 0000000..047d75f
--- /dev/null
+++ b/0005-network-avoid-trying-to-create-global-firewall-rules.patch
@@ -0,0 +1,50 @@
+From 3e02ee9b5da7fc7197aaa6d57563349a7670b8a1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Wed, 13 Mar 2019 16:21:15 +0000
+Subject: [PATCH 5/5] network: avoid trying to create global firewall rules if
+ unprivileged
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The unprivileged libvirtd does not have permission to create firewall
+rules, or bridge devices, or do anything to the host network in
+general. Historically we still activate the network driver though and
+let the network start API call fail.
+
+The startup code path which reloads firewall rules on active networks
+would thus effectively be a no-op when unprivileged as it is impossible
+for there to be any active networks
+
+With the change to use a global set of firewall chains, however, we now
+have code that is run unconditionally.
+
+Ideally we would not register the network driver at all when
+unprivileged, but the entanglement with the virt drivers currently makes
+that impractical. As a temporary hack, we just make the firewall reload
+into a no-op.
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 5d010c3df6152cf5fb00f1f67d22151241f4a8a2)
+---
+ src/network/bridge_driver.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
+index 1da60f0a21..0e1d5efd8e 100644
+--- a/src/network/bridge_driver.c
++++ b/src/network/bridge_driver.c
+@@ -2108,6 +2108,10 @@ static void
+ networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup)
+ {
+     VIR_INFO("Reloading iptables rules");
++    /* Ideally we'd not even register the driver when unprivilegd
++     * but until we untangle the virt driver that's not viable */
++    if (!driver->privileged)
++        return;
+     networkPreReloadFirewallRules(startup);
+     virNetworkObjListForEach(driver->networks,
+                              networkReloadFirewallRulesHelper,
+-- 
+2.20.1
+
diff --git a/libvirt.spec b/libvirt.spec
index dd06451..147b2e2 100644
--- a/libvirt.spec
+++ b/libvirt.spec
@@ -15,7 +15,7 @@
 # Default to skipping autoreconf.  Distros can change just this one line
 # (or provide a command-line override) if they backport any patches that
 # touch configure.ac or Makefile.am.
-%{!?enable_autotools:%global enable_autotools 0}
+%{!?enable_autotools:%global enable_autotools 1}
 
 # The hypervisor drivers that run in libvirtd
 %define with_qemu          0%{!?_without_qemu:1}
@@ -216,7 +216,7 @@
 Summary: Library providing a simple virtualization API
 Name: libvirt
 Version: 5.1.0
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: LGPLv2+
 URL: https://libvirt.org/
 
@@ -224,6 +224,12 @@ URL: https://libvirt.org/
     %define mainturl stable_updates/
 %endif
 Source: https://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.xz
+Patch1: 0001-storage-split-off-code-for-calling-rbd_list.patch
+Patch2: 0002-storage-add-support-for-new-rbd_list2-method.patch
+Patch3: 0003-network-improve-error-report-when-firewall-chain-cre.patch
+Patch4: 0004-network-split-setup-of-ipv4-and-ipv6-top-level-chain.patch
+Patch5: 0005-network-avoid-trying-to-create-global-firewall-rules.patch
+
 
 Requires: libvirt-daemon = %{version}-%{release}
 Requires: libvirt-daemon-config-network = %{version}-%{release}
@@ -326,6 +332,8 @@ BuildRequires: libiscsi-devel
 BuildRequires: parted-devel
 # For Multipath support
 BuildRequires: device-mapper-devel
+# For XFS reflink clone support
+BuildRequires: xfsprogs-devel
 %if %{with_storage_rbd}
 BuildRequires: librados2-devel
 BuildRequires: librbd1-devel
@@ -548,6 +556,9 @@ Requires: util-linux
 # From QEMU RPMs
 Requires: /usr/bin/qemu-img
 %endif
+%if !%{with_storage_rbd}
+Obsoletes: libvirt-daemon-driver-storage-rbd < %{version}-%{release}
+%endif
 
 %description daemon-driver-storage-core
 The storage driver plugin for the libvirtd daemon, providing
@@ -1889,6 +1900,13 @@ exit 0
 
 
 %changelog
+* Wed Mar 20 2019 Daniel P. Berrangé <berrange@redhat.com> - 5.1.0-3
+- Fix upgrades for rbd on i686 (rhbz #1688121)
+- Add missing xfsprogs-devel dep
+- Fix use of deprecated RBD features
+- Avoid using firewalld if unprivileged
+- Don't require ipv6 firewall support at startup (rhbz #1688968)
+
 * Wed Mar 06 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 5.1.0-2
 - Remove obsolete scriptlets