Yeela Kaplan has uploaded a new change for review. Change subject: Move multipath configuration to vdsm-tool configurator ......................................................................
Move multipath configuration to vdsm-tool configurator Previously multipath is reconfigured on each vdsm service restart. Now it will be reconfigured only on user demand. Change-Id: Ife045908dc6e2aea9829b51482b909af1faf79da Signed-off-by: Yeela Kaplan <ykap...@redhat.com> --- M lib/vdsm/tool/configurator.py M vdsm/storage/hsm.py M vdsm/storage/multipath.py M vdsm/supervdsmServer 4 files changed, 147 insertions(+), 121 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/09/30909/1 diff --git a/lib/vdsm/tool/configurator.py b/lib/vdsm/tool/configurator.py index 1e446a6..57923e8 100644 --- a/lib/vdsm/tool/configurator.py +++ b/lib/vdsm/tool/configurator.py @@ -26,6 +26,7 @@ import rpm import shutil import sys +import tempfile import traceback import uuid @@ -665,9 +666,155 @@ return configured +class MultipathModuleConfigure(_ModuleConfigure): + + _MPATH_CONF = "/etc/multipath.conf" + + _STRG_MPATH_CONF = ( + "\n\n" + "defaults {\n" + " polling_interval 5\n" + " getuid_callout \"%(scsi_id_path)s --whitelisted " + "--replace-whitespace --device=/dev/%%n\"\n" + " no_path_retry fail\n" + " user_friendly_names no\n" + " flush_on_last_del yes\n" + " fast_io_fail_tmo 5\n" + " dev_loss_tmo 30\n" + " max_fds 4096\n" + "}\n" + "\n" + "devices {\n" + "device {\n" + " vendor \"HITACHI\"\n" + " product \"DF.*\"\n" + " getuid_callout \"%(scsi_id_path)s --whitelisted " + "--replace-whitespace --device=/dev/%%n\"\n" + "}\n" + "device {\n" + " vendor \"COMPELNT\"\n" + " product \"Compellent Vol\"\n" + " no_path_retry fail\n" + "}\n" + "}" + ) + + _MAX_CONF_COPIES = 5 + + _OLD_TAGS = ["# RHAT REVISION 0.2", "# RHEV REVISION 0.3", + "# RHEV REVISION 0.4", "# RHEV REVISION 0.5", + "# RHEV REVISION 0.6", "# RHEV REVISION 0.7", + "# RHEV REVISION 0.8", "# RHEV REVISION 0.9"] + + _MPATH_CONF_TAG = "# RHEV REVISION 1.0" + _MPATH_CONF_PRIVATE_TAG = "# RHEV PRIVATE" + + _MPATH_CONF_TEMPLATE = _MPATH_CONF_TAG + _STRG_MPATH_CONF + + _scsi_id = utils.CommandPath("scsi_id", + "/sbin/scsi_id", # EL6 + "/usr/lib/udev/scsi_id", # Fedora + "/lib/udev/scsi_id", # Ubuntu + ) + + def getName(self): + return 'multipath' + + def getServices(self): + return ["multipathd"] + + def configure(self): + """ + Set up the multipath daemon configuration to the known and + supported state. The original configuration, if any, is saved + """ + if os.getuid() != 0: + raise UserWarning("Must run as root") + + if self.isconfigured(): + return + + if os.path.exists(self._MPATH_CONF): + utils.rotateFiles( + os.path.dirname(self._MPATH_CONF), + os.path.basename(self._MPATH_CONF), + self._MAX_CONF_COPIES, + cp=True, persist=True) + with tempfile.NamedTemporaryFile() as f: + f.write(self._MPATH_CONF_TEMPLATE % + {'scsi_id_path': self._scsi_id.cmd}) + f.flush() + cmd = [constants.EXT_CP, f.name, + self._MPATH_CONF] + rc, out, err = utils.execCmd(cmd) + + if rc != 0: + raise RuntimeError("Failed to perform Multipath config.") + utils.persistFile(self._MPATH_CONF) + + # Flush all unused multipath device maps + utils.execCmd([constants.EXT_MULTIPATH, "-F"]) + + cmd = [constants.EXT_VDSM_TOOL, "service-reload", "multipathd"] + rc, out, err = utils.execCmd(cmd) + if rc != 0: + sys.stdout.write("Failed to reload Multipath.") + + def isconfigured(self, *args): + """ + Check the multipath daemon configuration. The configuration file + /etc/multipath.conf should contain private tag in form + "RHEV REVISION X.Y" for this check to succeed. + If the tag above is followed by tag "RHEV PRIVATE" the configuration + should be preserved at all cost. + """ + if os.getuid() != 0: + raise UserWarning("Must run as root") + + if os.path.exists(self._MPATH_CONF): + first = second = '' + with open(self._MPATH_CONF) as f: + mpathconf = [x.strip("\n") for x in f.readlines()] + try: + first = mpathconf[0] + second = mpathconf[1] + except IndexError: + pass + if self._MPATH_CONF_PRIVATE_TAG in second: + sys.stdout.write("Manual override for multipath.conf detected" + " - preserving current configuration") + if self._MPATH_CONF_TAG not in first: + sys.stdout.write("This manual override for multipath.conf " + "was based on downrevved template. " + "You are strongly advised to " + "contact your support representatives") + return True + + if self._MPATH_CONF_TAG in first: + sys.stdout.write("Current revision of multipath.conf detected," + " preserving") + return True + + for tag in self._OLD_TAGS: + if tag in first: + sys.stdout.write("Downrev multipath.conf detected, " + "upgrade required") + return False + + sys.stdout.write("multipath Defaulting to False") + return False + + def validate(self): + return self.isconfigured() + + def reconfigureOnForce(self): + return self.isconfigured() + + __configurers = ( LibvirtModuleConfigure(), SanlockModuleConfigure(), + MultipathModuleConfigure(), ) diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py index 320a50a..49f3680 100644 --- a/vdsm/storage/hsm.py +++ b/vdsm/storage/hsm.py @@ -355,9 +355,6 @@ self._preparedVolumes = defaultdict(list) - if not multipath.isEnabled(): - multipath.setupMultipath() - self.__validateLvmLockingType() oop.setDefaultImpl(config.get('irs', 'oop_impl')) diff --git a/vdsm/storage/multipath.py b/vdsm/storage/multipath.py index d626305..0c05409 100644 --- a/vdsm/storage/multipath.py +++ b/vdsm/storage/multipath.py @@ -25,7 +25,6 @@ import os import errno from glob import glob -import tempfile import logging import re from collections import namedtuple @@ -37,53 +36,11 @@ import supervdsm import devicemapper -import storage_exception as se - DEV_ISCSI = "iSCSI" DEV_FCP = "FCP" DEV_MIXED = "MIXED" -MAX_CONF_COPIES = 5 - TOXIC_CHARS = '()*+?|^$.\\' - -MPATH_CONF = "/etc/multipath.conf" - -OLD_TAGS = ["# RHAT REVISION 0.2", "# RHEV REVISION 0.3", - "# RHEV REVISION 0.4", "# RHEV REVISION 0.5", - "# RHEV REVISION 0.6", "# RHEV REVISION 0.7", - "# RHEV REVISION 0.8", "# RHEV REVISION 0.9"] -MPATH_CONF_TAG = "# RHEV REVISION 1.0" -MPATH_CONF_PRIVATE_TAG = "# RHEV PRIVATE" -STRG_MPATH_CONF = ( - "\n\n" - "defaults {\n" - " polling_interval 5\n" - " getuid_callout \"%(scsi_id_path)s --whitelisted " - "--replace-whitespace --device=/dev/%%n\"\n" - " no_path_retry fail\n" - " user_friendly_names no\n" - " flush_on_last_del yes\n" - " fast_io_fail_tmo 5\n" - " dev_loss_tmo 30\n" - " max_fds 4096\n" - "}\n" - "\n" - "devices {\n" - "device {\n" - " vendor \"HITACHI\"\n" - " product \"DF.*\"\n" - " getuid_callout \"%(scsi_id_path)s --whitelisted " - "--replace-whitespace --device=/dev/%%n\"\n" - "}\n" - "device {\n" - " vendor \"COMPELNT\"\n" - " product \"Compellent Vol\"\n" - " no_path_retry fail\n" - "}\n" - "}" -) -MPATH_CONF_TEMPLATE = MPATH_CONF_TAG + STRG_MPATH_CONF log = logging.getLogger("Storage.Multipath") @@ -108,76 +65,6 @@ # Now let multipath daemon pick up new devices misc.execCmd([constants.EXT_MULTIPATH], sudo=True) - - -def isEnabled(): - """ - Check the multipath daemon configuration. The configuration file - /etc/multipath.conf should contain private tag in form - "RHEV REVISION X.Y" for this check to succeed. - If the tag above is followed by tag "RHEV PRIVATE" the configuration - should be preserved at all cost. - - """ - if os.path.exists(MPATH_CONF): - first = second = '' - svdsm = supervdsm.getProxy() - mpathconf = svdsm.readMultipathConf() - try: - first = mpathconf[0] - second = mpathconf[1] - except IndexError: - pass - if MPATH_CONF_PRIVATE_TAG in second: - log.info("Manual override for multipath.conf detected - " - "preserving current configuration") - if MPATH_CONF_TAG not in first: - log.warning("This manual override for multipath.conf " - "was based on downrevved template. " - "You are strongly advised to " - "contact your support representatives") - return True - - if MPATH_CONF_TAG in first: - log.debug("Current revision of multipath.conf detected, " - "preserving") - return True - - for tag in OLD_TAGS: - if tag in first: - log.info("Downrev multipath.conf detected, upgrade required") - return False - - log.debug("multipath Defaulting to False") - return False - - -def setupMultipath(): - """ - Set up the multipath daemon configuration to the known and - supported state. The original configuration, if any, is saved - """ - if os.path.exists(MPATH_CONF): - utils.rotateFiles( - os.path.dirname(MPATH_CONF), - os.path.basename(MPATH_CONF), MAX_CONF_COPIES, - cp=True, persist=True) - with tempfile.NamedTemporaryFile() as f: - f.write(MPATH_CONF_TEMPLATE % {'scsi_id_path': _scsi_id.cmd}) - f.flush() - cmd = [constants.EXT_CP, f.name, MPATH_CONF] - rc = misc.execCmd(cmd, sudo=True)[0] - if rc != 0: - raise se.MultipathSetupError() - utils.persistFile(MPATH_CONF) - - # Flush all unused multipath device maps - misc.execCmd([constants.EXT_MULTIPATH, "-F"], sudo=True) - - cmd = [constants.EXT_VDSM_TOOL, "service-reload", "multipathd"] - rc = misc.execCmd(cmd, sudo=True)[0] - if rc != 0: - raise se.MultipathReloadError() def deduceType(a, b): diff --git a/vdsm/supervdsmServer b/vdsm/supervdsmServer index aa58a13..4ab65f6 100755 --- a/vdsm/supervdsmServer +++ b/vdsm/supervdsmServer @@ -139,11 +139,6 @@ return _getDevicePartedInfo(*args, **kwargs) @logDecorator - def readMultipathConf(self): - with open(MPATH_CONF) as f: - return [x.strip("\n") for x in f.readlines()] - - @logDecorator def getScsiSerial(self, *args, **kwargs): return _getScsiSerial(*args, **kwargs) -- To view, visit http://gerrit.ovirt.org/30909 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ife045908dc6e2aea9829b51482b909af1faf79da Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Yeela Kaplan <ykap...@redhat.com> _______________________________________________ vdsm-patches mailing list vdsm-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches