diff mbox

[ovs-dev,RFC] rhel: Add support for "systemctl reload openvswitch"

Message ID 9a9cdb5ceed08bd482c9322e7e7a0fb5f87b9675.1501504734.git.tredaelli@redhat.com
State Changes Requested
Delegated to: Russell Bryant
Headers show

Commit Message

Timothy Redaelli July 31, 2017, 12:38 p.m. UTC
The reload procedure will trigger a script that saves the flows and tlv
maps then it restarts ovsdb-server, it stops ovs-vswitchd, it sets
other_config:flow-restore-wait=true (to wait till flow restore is
finished), it starts ovs-vswitchd, it restore the backupped flows/tlv
maps and it removes other_config:flow-restore-wait=true (logic mostly ripped
from ovs-ctl).

It uses systemctl with --job-mode=ignore-dependencies to restart ovsdb-server
and stop and start ovs-vswitchd in order to avoid systemd to restart the
other components due to dependencies (as explained in rhel/README.RHEL.rst).

It also uses --bundle, when available, in order to minimize the downtime.

Signed-off-by: Timothy Redaelli <tredaelli@redhat.com>
---
 rhel/automake.mk                                 |  1 +
 rhel/openvswitch-fedora.spec.in                  |  5 ++
 rhel/usr_lib_systemd_system_openvswitch.service  |  2 +-
 rhel/usr_lib_systemd_system_ovsdb-server.service |  1 -
 rhel/usr_share_openvswitch_scripts_ovs-reload    | 73 ++++++++++++++++++++++++
 5 files changed, 80 insertions(+), 2 deletions(-)
 create mode 100755 rhel/usr_share_openvswitch_scripts_ovs-reload
diff mbox

Patch

diff --git a/rhel/automake.mk b/rhel/automake.mk
index 1265fa747..93dbeac0c 100644
--- a/rhel/automake.mk
+++ b/rhel/automake.mk
@@ -23,6 +23,7 @@  EXTRA_DIST += \
 	rhel/openvswitch.spec.in \
 	rhel/openvswitch-fedora.spec \
 	rhel/openvswitch-fedora.spec.in \
+	rhel/usr_share_openvswitch_scripts_ovs-reload \
 	rhel/usr_share_openvswitch_scripts_sysconfig.template \
 	rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template \
 	rhel/usr_lib_systemd_system_openvswitch.service \
diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in
index 367207bc2..dadc8fd32 100644
--- a/rhel/openvswitch-fedora.spec.in
+++ b/rhel/openvswitch-fedora.spec.in
@@ -289,6 +289,10 @@  install -d -m 0755 $RPM_BUILD_ROOT%{_prefix}/lib/ocf/resource.d/ovn
 ln -s %{_datadir}/openvswitch/scripts/ovndb-servers.ocf \
       $RPM_BUILD_ROOT%{_prefix}/lib/ocf/resource.d/ovn/ovndb-servers
 
+install -p -D -m 0755 \
+        rhel/usr_share_openvswitch_scripts_ovs-reload \
+        $RPM_BUILD_ROOT%{_datadir}/openvswitch/scripts/ovs-reload
+
 # remove unpackaged files
 rm -f $RPM_BUILD_ROOT%{_bindir}/ovs-parse-backtrace \
         $RPM_BUILD_ROOT%{_sbindir}/ovs-vlan-bug-workaround \
@@ -493,6 +497,7 @@  fi
 %{_datadir}/openvswitch/scripts/ovs-save
 %{_datadir}/openvswitch/scripts/ovs-vtep
 %{_datadir}/openvswitch/scripts/ovs-ctl
+%{_datadir}/openvswitch/scripts/ovs-reload
 %config %{_datadir}/openvswitch/vswitch.ovsschema
 %config %{_datadir}/openvswitch/vtep.ovsschema
 %{_bindir}/ovs-appctl
diff --git a/rhel/usr_lib_systemd_system_openvswitch.service b/rhel/usr_lib_systemd_system_openvswitch.service
index faca44b54..2cf29f0e9 100644
--- a/rhel/usr_lib_systemd_system_openvswitch.service
+++ b/rhel/usr_lib_systemd_system_openvswitch.service
@@ -9,7 +9,7 @@  Requires=ovs-vswitchd.service
 [Service]
 Type=oneshot
 ExecStart=/bin/true
-ExecReload=/bin/true
+ExecReload=/usr/share/openvswitch/scripts/ovs-reload
 ExecStop=/bin/true
 RemainAfterExit=yes
 
diff --git a/rhel/usr_lib_systemd_system_ovsdb-server.service b/rhel/usr_lib_systemd_system_ovsdb-server.service
index 68deace7c..b9814bae1 100644
--- a/rhel/usr_lib_systemd_system_ovsdb-server.service
+++ b/rhel/usr_lib_systemd_system_ovsdb-server.service
@@ -2,7 +2,6 @@ 
 Description=Open vSwitch Database Unit
 After=syslog.target network-pre.target
 Before=network.target network.service
-ReloadPropagatedFrom=openvswitch.service
 PartOf=openvswitch.service
 
 [Service]
diff --git a/rhel/usr_share_openvswitch_scripts_ovs-reload b/rhel/usr_share_openvswitch_scripts_ovs-reload
new file mode 100755
index 000000000..793257390
--- /dev/null
+++ b/rhel/usr_share_openvswitch_scripts_ovs-reload
@@ -0,0 +1,73 @@ 
+#! /bin/sh
+
+# Copyright (c) 2017 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Highest OpenFlow version enabled by default
+DEFAULT_OFP_VERSION=OpenFlow14
+
+get_highest_ofp_version() {
+    ovs-vsctl get bridge "$1" protocols | \
+        awk -v default_ofp_version="$DEFAULT_OFP_VERSION" \
+            -F '"' '{ print (NF>1)? $(NF-1) : default_ofp_version }'
+}
+
+save_flows () {
+    for bridge; do
+        # Get the highest enabled OpenFlow version
+        ofp_version=$(get_highest_ofp_version "$bridge")
+
+        printf "ovs-ofctl -O $ofp_version add-tlv-map %s '" "$bridge"
+        ovs-ofctl -O $ofp_version dump-tlv-map $bridge | \
+            awk '/^ 0x/ {if (cnt != 0) printf ","; \
+                 cnt++;printf "{class="$1",type="$2",len="$3"}->"$4}'
+        echo "'"
+
+        printf "%s" "ovs-ofctl -O $ofp_version add-flows $bridge \
+            \"$workdir/$bridge.flows.dump\""
+
+        # If possible, use OpenFlow 1.4 atomic bundle transaction to add flows
+        [ ${ofp_version#OpenFlow} -ge 14 ] && echo " --bundle"
+
+        ovs-ofctl -O $ofp_version dump-flows --no-names --no-stats "$bridge" | \
+            sed -e '/NXST_FLOW/d' \
+                -e '/OFPST_FLOW/d' \
+                -e 's/\(idle\|hard\)_age=[^,]*,//g' \
+                > "$workdir/$bridge.flows.dump"
+    done
+}
+
+workdir=$(mktemp -d)
+trap 'rm -rf "$workdir"' EXIT
+
+# Save flows
+bridges=$(ovs-vsctl -- --real list-br)
+flows=$(save_flows $bridges)
+
+# Restart the database first, since a large database may take a
+# while to load, and we want to minimize forwarding disruption.
+systemctl --job-mode=ignore-dependencies restart ovsdb-server
+
+# Stop ovs-vswitchd.
+systemctl --job-mode=ignore-dependencies stop ovs-vswitchd
+
+# Start vswitchd by asking it to wait till flow restore is finished.
+ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait=true
+systemctl --job-mode=ignore-dependencies start ovs-vswitchd
+
+# Restore saved flows and inform vswitchd that we are done.
+eval "$flows"
+ovs-vsctl --if-exists remove open_vswitch . other_config flow-restore-wait=true
+
+exit 0