Antoni Segura Puimedon has uploaded a new change for review.
Change subject: [WIP] Unified persistence.
......................................................................
[WIP] Unified persistence.
This patch introduces the new persistence model for vdsm networking.
It is meant to provide a single reliable way abstracting persistence
out of the netconf configurators as much as possible.
To achieve its purpose, it stores the network actions as setupNetwork
parameters serialized in json which are then used for rollback and
initialization.
Change-Id: I7137a96f84abd2c5e532c6c37737e36ef17567a9
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
M lib/vdsm/config.py.in
M lib/vdsm/netinfo.py
M vdsm/configNetwork.py
M vdsm/vdsm-store-net-config.in
4 files changed, 124 insertions(+), 11 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/99/16699/1
diff --git a/lib/vdsm/config.py.in b/lib/vdsm/config.py.in
index 2a5618a..05a820b 100644
--- a/lib/vdsm/config.py.in
+++ b/lib/vdsm/config.py.in
@@ -42,6 +42,9 @@
'Comma-separated list of fnmatch-patterns for dummy hosts nics to '
'be shown to vdsm.'),
+ ('persistence', 'ifcfg',
+ 'Whether to use "ifcfg" or "unified" persistence for
networks.'),
+
('nic_model', 'rtl8139,pv',
'NIC model is rtl8139, ne2k_pci pv or any other valid device '
'recognized by kvm/qemu if a coma separated list given then a '
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 37cd0b4..6b22c77 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -37,9 +37,14 @@
import libvirtconnection
NET_CONF_DIR = '/etc/sysconfig/network-scripts/'
+# ifcfg persistence directories
NET_CONF_BACK_DIR = constants.P_VDSM_LIB + 'netconfback/'
NET_LOGICALNET_CONF_BACK_DIR = NET_CONF_BACK_DIR + 'logicalnetworks/'
+# Unified persistence directories
+NET_CONF_RUN_DIR = constants.P_VDSM_RUN + 'netconf/nets/'
+BOND_CONF_RUN_DIR = constants.P_VDSM_RUN + 'netconf/bonds/'
+
NET_CONF_PREF = NET_CONF_DIR + 'ifcfg-'
PROC_NET_VLAN = '/proc/net/vlan/'
NET_FN_MATCH = '/sys/class/net/*'
diff --git a/vdsm/configNetwork.py b/vdsm/configNetwork.py
index 1fde263..9c72639 100755
--- a/vdsm/configNetwork.py
+++ b/vdsm/configNetwork.py
@@ -17,12 +17,14 @@
# Refer to the README and COPYING files for full details of the license
#
+import json
import sys
import os
import traceback
import time
import logging
+from vdsm.config import config
from vdsm import constants
from vdsm import utils
from storage.misc import execCmd
@@ -152,6 +154,7 @@
configurator=None, bondingOptions=None, bridged=True,
_netinfo=None, qosInbound=None, qosOutbound=None, **options):
nics = nics or ()
+ saveRunConf = configurator is None
if _netinfo is None:
_netinfo = netinfo.NetInfo()
bridged = utils.tobool(bridged)
@@ -203,6 +206,36 @@
qosInbound=qosInbound,
qosOutbound=qosOutbound)
netEnt.configure(**options)
+ if saveRunConf:
+ pass
+
+
+def _setBondAsRunning(self, bond):
+ bondFileName = os.path.join(netinfo.BOND_CONF_RUN_DIR, bond.name)
+ if bond.name not in self._bonds:
+ try:
+ self._bonds[bond.name] = json.load(open(bondFileName))
+ logging.debug("Backed up %s", bondFileName)
+ except IOError as e:
+ if e.errno == os.errno.ENOENT:
+ self._bonds[bond.name] = None
+ else:
+ raise
+ json.dump(bond.setupify(), open(bondFileName, 'w'))
+
+
+def _setNetworkAsRunning(self, network, topNetDev):
+ netFileName = os.path.join(netinfo.NET_CONF_RUN_DIR, network)
+ if network not in self._nets:
+ try:
+ self._nets[network] = json.load(open(netFileName))
+ logging.debug("Backed up %s", netFileName)
+ except IOError as e:
+ if e.errno == os.errno.ENOENT:
+ self._nets[network] = None
+ else:
+ raise
+ json.dump(topNetDev.setupify(), open(netFileName, 'w'))
def assertBridgeClean(bridge, vlan, bonding, nics):
@@ -475,6 +508,7 @@
_netinfo = netinfo.NetInfo()
configurator = Ifcfg()
networksAdded = set()
+ networksDeleted = set()
logger.debug("Setting up network according to configuration: "
"networks:%r, bondings:%r, options:%r" % (networks,
@@ -505,6 +539,7 @@
_delBrokenNetwork(network, libvirt_nets[network],
configurator=configurator)
if 'remove' in networkAttrs:
+ networksDeleted.add(network)
del networks[network]
del libvirt_nets[network]
else:
@@ -543,11 +578,35 @@
except:
configurator.rollback()
raise
+ else:
+ if config.get('vars', 'persistence') != 'unified':
+ return
+ for netName in networksDeleted:
+ logger.info('Removing network %s from running configuration',
+ netName)
+ os.unlink(netinfo.NET_CONF_RUN_DIR + netName)
+ for netName in networksAdded:
+ logger.info('Adding network %s to running configuration',
+ netName)
+ json.dump(networks[netName],
+ open(netinfo.NET_CONF_RUN_DIR + netName, 'w'))
+ existingBonds = netinfo.bondings()
+ for bondName, attr in bondings:
+ if bondName in existingBonds:
+ logger.info('Removing bond %s from running configuration',
+ bondName)
+ os.unlink(netinfo.BOND_CONF_RUN_DIR + bondName)
+ else:
+ logger.info('Adding bond %s to running configuration',
+ bondName)
+ json.dump(bondings[bondName],
+ open(netinfo.BOND_CONF_RUN_DIR + bondName, 'w'))
def setSafeNetworkConfig():
"""Declare current network configuration as
'safe'"""
- execCmd([constants.EXT_VDSM_STORE_NET_CONFIG])
+ execCmd([constants.EXT_VDSM_STORE_NET_CONFIG,
+ config.get('vars', 'persistency')])
def usage():
diff --git a/vdsm/vdsm-store-net-config.in b/vdsm/vdsm-store-net-config.in
index ed3af8a..0ad57c9 100755
--- a/vdsm/vdsm-store-net-config.in
+++ b/vdsm/vdsm-store-net-config.in
@@ -5,20 +5,22 @@
. @LIBEXECDIR(a)/ovirt_functions.sh
+# ifcfg persistence directories
NET_CONF_DIR='/etc/sysconfig/network-scripts/'
-NET_CONF_BACK_DIR=@VDSMLIBDIR@/netconfback
-DELETE_HEADER='# original file did not exist'
+NET_CONF_BACK_DIR="@VDSMLIBDIR@/netconfback"
-if isOvirt
-then
- # for ovirt, persist the changed configuration files
+# Unified persistence directories
+RUN_CONF_DIR='@VDSMRUNDIR@/netconf'
+PERS_CONF_PATH="@VDSMLIBDIR@/persistence"
+PERS_NET_CONF_PATH="$PERS_CONF_PATH/netconf"
- . /usr/libexec/ovirt-functions
+PERSISTENCE=$1
+ifcfg_node_persist() {
for f in "$NET_CONF_BACK_DIR"/*;
do
[ ! -f "$f" ] && continue
- bf=`basename "$f"`
+ bf=$(basename "$f")
if [ -f "$NET_CONF_DIR/$bf" ];
then
ovirt_store_config "$NET_CONF_DIR/$bf"
@@ -27,9 +29,53 @@
fi
rm "$NET_CONF_BACK_DIR/$bf"
done
-else
- # for rhel, remove the backed up configuration files, and thus mark the
- # ones under /etc/sysconfig as "safe".
+}
+ifcfg_nonnode_persist() {
+ # Remove the backed up configuration files thus marking the ones under
+ # /etc/sysconfig as "safe".
rm -rf "$NET_CONF_BACK_DIR"/*
+}
+
+unified_node_persist() {
+ unified_nonnode_persist
+
+ # oVirt node ovirt_store_config puts the dir in persistent storage and
+ # bind mounts it in the original place. So that's all we really need to do.
+ ovirt_store_config "$PERS_CONF_PATH"
+}
+
+unified_nonnode_persist() {
+ # Atomic directory copy by using the atomicity of overwriting a link
+ # (rename syscall).
+ TIMESTAMP=$(date +%s)
+ PERS_CONF_SYMLINK=$PERS_NET_CONF_PATH
+ PERS_CONF_DIR_ROOTNAME="$PERS_CONF_SYMLINK."
+ PERS_CONF_NEW_DIR="$PERS_CONF_DIR_ROOTNAME$TIMESTAMP"
+ PERS_CONF_NEW_SYMLINK="$PERS_CONF_SYMLINK.link.$TIMESTAMP"
+
+ cp -r "$RUN_CONF_DIR" "$PERS_CONF_NEW_DIR"
+ ln -s "$PERS_CONF_NEW_DIR" "$PERS_CONF_NEW_SYMLINK"
+ mv -fT "$PERS_CONF_NEW_SYMLINK" "$PERS_CONF_SYMLINK"
+ find "$PERS_CONF_PATH" -type d -path "$PERS_CONF_DIR_ROOTNAME" |
\
+ grep -v "$PERS_CONF_NEW_DIR" | xargs rm -fr
+}
+
+
+if isOvirt
+then
+ # for node, persist the changed configuration files
+
+ . /usr/libexec/ovirt-functions
+
+ if [ "$PERSISTENCE" == "unified"]; then
+ unified_node_persist
+ else
+ ifcfg_node_persist
+ fi
+else
+ if [ "$PERSISTENCE" == "unified"]; then
+ unified_nonnode_persist
+ else
+ ifcfg_nonnode_persist
fi
--
To view, visit
http://gerrit.ovirt.org/16699
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7137a96f84abd2c5e532c6c37737e36ef17567a9
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>