Daniel P. Berrangé d670e2
From b990740b12117eaaf2797141a53a30b41f07c791 Mon Sep 17 00:00:00 2001
Daniel P. Berrangé d670e2
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Daniel P. Berrangé d670e2
Date: Mon, 18 Mar 2019 17:31:21 +0000
Daniel P. Berrangé d670e2
Subject: [PATCH 3/5] network: improve error report when firewall chain
Daniel P. Berrangé d670e2
 creation fails
Daniel P. Berrangé d670e2
MIME-Version: 1.0
Daniel P. Berrangé d670e2
Content-Type: text/plain; charset=UTF-8
Daniel P. Berrangé d670e2
Content-Transfer-Encoding: 8bit
Daniel P. Berrangé d670e2
Daniel P. Berrangé d670e2
During startup we create some top level chains in which all
Daniel P. Berrangé d670e2
virtual network firewall rules will be placed. The upfront
Daniel P. Berrangé d670e2
creation is done to avoid slowing down creation of individual
Daniel P. Berrangé d670e2
virtual networks by checking for chain existance every time.
Daniel P. Berrangé d670e2
Daniel P. Berrangé d670e2
There are some factors which can cause this upfront creation
Daniel P. Berrangé d670e2
to fail and while a message will get into the libvirtd log
Daniel P. Berrangé d670e2
this won't be seen by users who later try to start a virtual
Daniel P. Berrangé d670e2
network. Instead they'll just get a message saying that the
Daniel P. Berrangé d670e2
libvirt top level chain does not exist. This message is
Daniel P. Berrangé d670e2
accurate, but unhelpful for solving the root cause.
Daniel P. Berrangé d670e2
Daniel P. Berrangé d670e2
This patch thus saves any error during daemon startup and
Daniel P. Berrangé d670e2
reports it when trying to create a virtual network later.
Daniel P. Berrangé d670e2
Daniel P. Berrangé d670e2
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Daniel P. Berrangé d670e2
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Daniel P. Berrangé d670e2
(cherry picked from commit 9f4e35dc73ec9e940aa61bc7c140c2b800218ef3)
Daniel P. Berrangé d670e2
---
Daniel P. Berrangé d670e2
 src/network/bridge_driver.c          |  3 +--
Daniel P. Berrangé d670e2
 src/network/bridge_driver_linux.c    | 31 +++++++++++++++++++++-------
Daniel P. Berrangé d670e2
 src/network/bridge_driver_nop.c      |  3 +--
Daniel P. Berrangé d670e2
 src/network/bridge_driver_platform.h |  2 +-
Daniel P. Berrangé d670e2
 4 files changed, 27 insertions(+), 12 deletions(-)
Daniel P. Berrangé d670e2
Daniel P. Berrangé d670e2
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
Daniel P. Berrangé d670e2
index b3ca5b8a15..1da60f0a21 100644
Daniel P. Berrangé d670e2
--- a/src/network/bridge_driver.c
Daniel P. Berrangé d670e2
+++ b/src/network/bridge_driver.c
Daniel P. Berrangé d670e2
@@ -2108,8 +2108,7 @@ static void
Daniel P. Berrangé d670e2
 networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup)
Daniel P. Berrangé d670e2
 {
Daniel P. Berrangé d670e2
     VIR_INFO("Reloading iptables rules");
Daniel P. Berrangé d670e2
-    if (networkPreReloadFirewallRules(startup) < 0)
Daniel P. Berrangé d670e2
-        return;
Daniel P. Berrangé d670e2
+    networkPreReloadFirewallRules(startup);
Daniel P. Berrangé d670e2
     virNetworkObjListForEach(driver->networks,
Daniel P. Berrangé d670e2
                              networkReloadFirewallRulesHelper,
Daniel P. Berrangé d670e2
                              NULL);
Daniel P. Berrangé d670e2
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
Daniel P. Berrangé d670e2
index b10d0a6c4d..c899f4b6d0 100644
Daniel P. Berrangé d670e2
--- a/src/network/bridge_driver_linux.c
Daniel P. Berrangé d670e2
+++ b/src/network/bridge_driver_linux.c
Daniel P. Berrangé d670e2
@@ -35,11 +35,25 @@ VIR_LOG_INIT("network.bridge_driver_linux");
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
 #define PROC_NET_ROUTE "/proc/net/route"
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
-int networkPreReloadFirewallRules(bool startup)
Daniel P. Berrangé d670e2
+static virErrorPtr errInit;
Daniel P. Berrangé d670e2
+
Daniel P. Berrangé d670e2
+void networkPreReloadFirewallRules(bool startup)
Daniel P. Berrangé d670e2
 {
Daniel P. Berrangé d670e2
-    int ret = iptablesSetupPrivateChains();
Daniel P. Berrangé d670e2
-    if (ret < 0)
Daniel P. Berrangé d670e2
-        return -1;
Daniel P. Berrangé d670e2
+    int rc;
Daniel P. Berrangé d670e2
+
Daniel P. Berrangé d670e2
+    /* We create global rules upfront as we don't want
Daniel P. Berrangé d670e2
+     * the perf hit of conditionally figuring out whether
Daniel P. Berrangé d670e2
+     * to create them each time a network is started.
Daniel P. Berrangé d670e2
+     *
Daniel P. Berrangé d670e2
+     * Any errors here are saved to be reported at time
Daniel P. Berrangé d670e2
+     * of starting the network though as that makes them
Daniel P. Berrangé d670e2
+     * more likely to be seen by a human
Daniel P. Berrangé d670e2
+     */
Daniel P. Berrangé d670e2
+    rc = iptablesSetupPrivateChains();
Daniel P. Berrangé d670e2
+    if (rc < 0) {
Daniel P. Berrangé d670e2
+        errInit = virSaveLastError();
Daniel P. Berrangé d670e2
+        virResetLastError();
Daniel P. Berrangé d670e2
+    }
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
     /*
Daniel P. Berrangé d670e2
      * If this is initial startup, and we just created the
Daniel P. Berrangé d670e2
@@ -54,10 +68,8 @@ int networkPreReloadFirewallRules(bool startup)
Daniel P. Berrangé d670e2
      * rules will be present. Thus we can safely just tell it
Daniel P. Berrangé d670e2
      * to always delete from the builin chain
Daniel P. Berrangé d670e2
      */
Daniel P. Berrangé d670e2
-    if (startup && ret == 1)
Daniel P. Berrangé d670e2
+    if (startup && rc == 1)
Daniel P. Berrangé d670e2
         iptablesSetDeletePrivate(false);
Daniel P. Berrangé d670e2
-
Daniel P. Berrangé d670e2
-    return 0;
Daniel P. Berrangé d670e2
 }
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
@@ -671,6 +683,11 @@ int networkAddFirewallRules(virNetworkDefPtr def)
Daniel P. Berrangé d670e2
     virFirewallPtr fw = NULL;
Daniel P. Berrangé d670e2
     int ret = -1;
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
+    if (errInit) {
Daniel P. Berrangé d670e2
+        virSetError(errInit);
Daniel P. Berrangé d670e2
+        return -1;
Daniel P. Berrangé d670e2
+    }
Daniel P. Berrangé d670e2
+
Daniel P. Berrangé d670e2
     if (def->bridgeZone) {
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
         /* if a firewalld zone has been specified, fail/log an error
Daniel P. Berrangé d670e2
diff --git a/src/network/bridge_driver_nop.c b/src/network/bridge_driver_nop.c
Daniel P. Berrangé d670e2
index a0e57012f9..ea9db338cb 100644
Daniel P. Berrangé d670e2
--- a/src/network/bridge_driver_nop.c
Daniel P. Berrangé d670e2
+++ b/src/network/bridge_driver_nop.c
Daniel P. Berrangé d670e2
@@ -19,9 +19,8 @@
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
 #include <config.h>
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
-int networkPreReloadFirewallRules(bool startup ATTRIBUTE_UNUSED)
Daniel P. Berrangé d670e2
+void networkPreReloadFirewallRules(bool startup ATTRIBUTE_UNUSED)
Daniel P. Berrangé d670e2
 {
Daniel P. Berrangé d670e2
-    return 0;
Daniel P. Berrangé d670e2
 }
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driver_platform.h
Daniel P. Berrangé d670e2
index baeb22bc3e..95fd64bdc7 100644
Daniel P. Berrangé d670e2
--- a/src/network/bridge_driver_platform.h
Daniel P. Berrangé d670e2
+++ b/src/network/bridge_driver_platform.h
Daniel P. Berrangé d670e2
@@ -58,7 +58,7 @@ struct _virNetworkDriverState {
Daniel P. Berrangé d670e2
 typedef struct _virNetworkDriverState virNetworkDriverState;
Daniel P. Berrangé d670e2
 typedef virNetworkDriverState *virNetworkDriverStatePtr;
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
-int networkPreReloadFirewallRules(bool startup);
Daniel P. Berrangé d670e2
+void networkPreReloadFirewallRules(bool startup);
Daniel P. Berrangé d670e2
 void networkPostReloadFirewallRules(bool startup);
Daniel P. Berrangé d670e2
 
Daniel P. Berrangé d670e2
 int networkCheckRouteCollision(virNetworkDefPtr def);
Daniel P. Berrangé d670e2
-- 
Daniel P. Berrangé d670e2
2.20.1
Daniel P. Berrangé d670e2