From 8431816ee3bed52e3ee9591e9f1e677e16f824aa Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Sat, 28 Nov 2015 07:27:05 +0000 Subject: [PATCH] CP-11979: Added FCoE driver and fixed sr-probe. Signed-off-by: Pritha Srivastava Reviewed-by: Chandrika Srinivasan GitHub: closes xapi-project/sm#281 --- Makefile | 4 ++ drivers/LVHDoFCoESR.py | 98 ++++++++++++++++++++++++++++++++++++++++++ drivers/cleanup.py | 2 +- drivers/devscan.py | 28 +++++++++--- drivers/fcoelib.py | 41 ++++++++++++++++++ drivers/mpathcount.py | 2 +- mk/sm.spec.in | 7 +++ 7 files changed, 174 insertions(+), 8 deletions(-) create mode 100755 drivers/LVHDoFCoESR.py create mode 100755 drivers/fcoelib.py diff --git a/Makefile b/Makefile index f03b1c1da..a211de6bc 100755 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ SM_DRIVERS += OCFSoISCSI SM_DRIVERS += OCFSoHBA SM_DRIVERS += SHM SM_DRIVERS += SMB +SM_DRIVERS += LVHDoFCoE SM_LIBS := SR SM_LIBS += SRCommand @@ -59,6 +60,7 @@ SM_LIBS += B_util SM_LIBS += wwid_conf SM_LIBS += trim_util SM_LIBS += pluginutil +SM_LIBS += fcoelib UDEV_RULES = 39-multipath 40-multipath 55-xs-mpath-scsidev 58-xapi MPATH_DAEMON = sm-multipath @@ -169,6 +171,7 @@ install: precheck cd $(SM_STAGING)$(SM_DEST) && rm -f LVHDSR && ln -sf LVHDSR.py LVMSR cd $(SM_STAGING)$(SM_DEST) && rm -f LVHDoISCSISR && ln -sf LVHDoISCSISR.py LVMoISCSISR cd $(SM_STAGING)$(SM_DEST) && rm -f LVHDoHBASR && ln -sf LVHDoHBASR.py LVMoHBASR + cd $(SM_STAGING)$(SM_DEST) && rm -f LVHDoFCoESR && ln -sf LVHDoFCoESR.py LVMoFCoESR cd $(SM_STAGING)$(SM_DEST) && rm -f OCFSSR cd $(SM_STAGING)$(SM_DEST) && rm -f OCFSoISCSISR cd $(SM_STAGING)$(SM_DEST) && rm -f OCFSoHBASR @@ -188,6 +191,7 @@ install: precheck install -m 755 drivers/LVHD.enable_thin_provisioning $(SM_STAGING)$(EXTENSION_SCRIPT_DEST) ln -sf $(PLUGIN_SCRIPT_DEST)vss_control $(SM_STAGING)$(SM_DEST) install -m 755 drivers/iscsilib.py $(SM_STAGING)$(SM_DEST) + install -m 755 drivers/fcoelib.py $(SM_STAGING)$(SM_DEST) mkdir -p $(SM_STAGING)$(LIBEXEC) install -m 755 scripts/local-device-change $(SM_STAGING)$(LIBEXEC) install -m 755 scripts/check-device-sharing $(SM_STAGING)$(LIBEXEC) diff --git a/drivers/LVHDoFCoESR.py b/drivers/LVHDoFCoESR.py new file mode 100755 index 000000000..33d7c551d --- /dev/null +++ b/drivers/LVHDoFCoESR.py @@ -0,0 +1,98 @@ +#!/usr/bin/python +# +# Copyright (C) Citrix Systems Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; version 2.1 only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# LVHDoFCoESR: LVHD over Fibre Channel over Ethernet driver +# + +import SR +import LVHDoHBASR +import LVHDSR +import SRCommand +import sys +import xs_errors +import util + +CAPABILITIES = ["SR_PROBE", "SR_UPDATE", "SR_METADATA", "SR_TRIM", + "VDI_CREATE", "VDI_DELETE", "VDI_ATTACH", "VDI_DETACH", + "VDI_GENERATE_CONFIG", "VDI_SNAPSHOT", "VDI_CLONE", + "VDI_RESIZE", "ATOMIC_PAUSE", "VDI_RESET_ON_BOOT/2", + "VDI_UPDATE"] + +CONFIGURATION = [['SCSIid', 'The scsi_id of the destination LUN'], + ['allocation', 'Valid values are thick or thin(optional,\ + defaults to thick)']] + +DRIVER_INFO = { + 'name': 'LVHD over FCoE', + 'description': 'SR plugin which represents disks as VHDs on Logical \ + Volumes within a Volume Group created on a FCoE LUN', + 'vendor': 'Citrix Systems Inc', + 'copyright': '(C) 2015 Citrix Systems Inc', + 'driver_version': '1.0', + 'required_api_version': '1.0', + 'capabilities': CAPABILITIES, + 'configuration': CONFIGURATION +} + + +class LVHDoFCoESR(LVHDoHBASR.LVHDoHBASR): + + """LVHD over FCoE storage repository""" + def handles(type): + if __name__ == '__main__': + name = sys.argv[0] + else: + name = __name__ + if name.endswith("LVMoFCoESR"): + return type == "lvmofcoe" # for the initial switch from LVM + if type == "lvhdofcoe": + return True + return False + handles = staticmethod(handles) + + def load(self, sr_uuid): + driver = SR.driver('hba') + if 'type' not in self.original_srcmd.params['device_config'] or \ + 'type' in self.original_srcmd.params['device_config'] and \ + self.original_srcmd.dconf['type'] == "any": + self.original_srcmd.dconf['type'] = "fcoe" + self.hbasr = driver(self.original_srcmd, sr_uuid) + pbd = None + try: + pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) + except: + pass + + if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: + print >>sys.stderr, self.hbasr.print_devs() + raise xs_errors.XenError('ConfigSCSIid') + + self.SCSIid = self.dconf['SCSIid'] + self._pathrefresh(LVHDoFCoESR) + LVHDSR.LVHDSR.load(self, sr_uuid) + + def vdi(self, uuid): + return LVHDoFCoEVDI(self, uuid) + + +class LVHDoFCoEVDI(LVHDoHBASR.LVHDoHBAVDI): + pass + +if __name__ == '__main__': + SRCommand.run(LVHDoFCoESR, DRIVER_INFO) +else: + SR.registerSR(LVHDoFCoESR) diff --git a/drivers/cleanup.py b/drivers/cleanup.py index 603e9dd2a..efc45cd52 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -2528,7 +2528,7 @@ def daemonize(): def normalizeType(type): if type in LVHDSR.SUBTYPES: type = SR.TYPE_LVHD - if type in ["lvm", "lvmoiscsi", "lvmohba"]: + if type in ["lvm", "lvmoiscsi", "lvmohba", "lvmofcoe"]: # temporary while LVHD is symlinked as LVM type = SR.TYPE_LVHD if type in ["ext", "nfs", "ocfsoiscsi", "ocfsohba", "smb"]: diff --git a/drivers/devscan.py b/drivers/devscan.py index eb4aac8ec..335d31c88 100644 --- a/drivers/devscan.py +++ b/drivers/devscan.py @@ -20,6 +20,7 @@ import xml.dom.minidom import xs_errors, time import glob +import fcoelib DEVPATH='/dev/disk/by-id' DMDEVPATH='/dev/mapper' @@ -47,6 +48,11 @@ def adapters(filterstr="any"): dict = {} devs = {} adt = {} + fcoe_eth_info = {} + + if filterstr == "fcoe": + fcoe_eth_info = fcoelib.parse_fcoe_eth_info() + for a in os.listdir(SYSFS_PATH1): proc = match_hbadevs(a, filterstr) if not proc: @@ -63,6 +69,7 @@ def adapters(filterstr="any"): for p in [os.path.join(SYSFS_PATH1,a,"device","session*"),os.path.join(SYSFS_PATH1,a,"device"),\ os.path.join(SYSFS_PATH2,"%s:*"%id)]: paths += glob.glob(p) + if not len(paths): continue for path in paths: @@ -90,8 +97,12 @@ def adapters(filterstr="any"): for lun in os.listdir(sysfs): if not match_LUNs(lun,tgt): continue + #Special casing for fcoe, populating eth information + eth = "" + if i in fcoe_eth_info.keys(): + eth = fcoe_eth_info[i] dir = os.path.join(sysfs,lun,"device") - (dev, entry) = _extract_dev(dir, proc, id, lun) + (dev, entry) = _extract_dev(dir, proc, id, lun, eth) update_devs_dict(devs, dev, entry) # for new mptsas sysfs entries, check for phy* node @@ -185,8 +196,10 @@ def _genMPPHBA(id): def match_hbadevs(s, filterstr): driver_name = _get_driver_name(s) if match_host(s) and not match_blacklist(driver_name) \ - and ( filterstr == "any" or match_filterstr(filterstr, driver_name) ): - return driver_name + and ( (filterstr == "any" \ + and not match_filterstr("fcoe", driver_name))\ + or match_filterstr(filterstr, driver_name) ): + return driver_name else: return "" @@ -244,13 +257,14 @@ def _get_block_device_name_with_kernel_3x(device_dir): else: return INVALID_DEVICE_NAME -def _extract_dev(device_dir, procname, host, target): +def _extract_dev(device_dir, procname, host, target, eths=""): """Returns device name and creates dictionary entry for it""" dev = _extract_dev_name(device_dir) entry = {} entry['procname'] = procname entry['host'] = host entry['target'] = target + entry['eth'] = eths return (dev, entry) def _add_host_parameters_to_adapter(dom, adapter, host_class, host_id, @@ -314,6 +328,8 @@ def scan(srobj): obj.id = ids[3] obj.lun = ids[4] obj.hba = hba['procname'] + if hba['eth']: + obj.eth = hba['eth'] obj.numpaths = 1 if vdis.has_key(obj.SCSIid): vdis[obj.SCSIid].numpaths += 1 @@ -339,11 +355,11 @@ def scan(srobj): d = dom.createElement("BlockDevice") e.appendChild(d) - for attr in ['path','numpaths','SCSIid','vendor','serial','size','adapter','channel','id','lun','hba','mpp']: + for attr in ['path','numpaths','SCSIid','vendor','serial','size','adapter','channel','id','lun','hba','mpp','eth']: try: aval = getattr(obj, attr) except AttributeError: - if attr in ['mpp']: + if attr in ['mpp'] or attr in ['eth']: continue raise xs_errors.XenError('InvalidArg', \ opterr='Missing required field [%s]' % attr) diff --git a/drivers/fcoelib.py b/drivers/fcoelib.py new file mode 100755 index 000000000..23d40db8a --- /dev/null +++ b/drivers/fcoelib.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# +# Copyright (C) Citrix Systems Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; version 2.1 only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import re +import util + + +def parse_fcoe_eth_info(): + fcoe_eth_info = {} + # create a dictionary of rport to eth + try: + cmd = ['fcoeadm', '-l'] + regex = re.compile("eth[0-9]") + for line in util.doexec(cmd)[1].split('\n'): + if line.find("Interface") != -1: + searchObj = regex.search(line, 0) + if searchObj: + eth = searchObj.group() + util.SMlog("eth: %s" % eth) + if line.find("rport") != -1: + str1, str2 = line.split(":", 1) + fcoe_eth_info[str2.strip()] = eth + eth = "" + except: + pass + + return fcoe_eth_info diff --git a/drivers/mpathcount.py b/drivers/mpathcount.py index c738bb7ba..526df35ca 100755 --- a/drivers/mpathcount.py +++ b/drivers/mpathcount.py @@ -24,7 +24,7 @@ import mpp_mpathutil import glob -supported = ['iscsi','lvmoiscsi','rawhba','lvmohba', 'ocfsohba', 'ocfsoiscsi', 'netapp'] +supported = ['iscsi','lvmoiscsi','rawhba','lvmohba', 'ocfsohba', 'ocfsoiscsi', 'netapp','lvmofcoe'] LOCK_TYPE_HOST = "host" LOCK_NS1 = "mpathcount1" diff --git a/mk/sm.spec.in b/mk/sm.spec.in index 39ac21337..897c3b3b2 100755 --- a/mk/sm.spec.in +++ b/mk/sm.spec.in @@ -147,9 +147,13 @@ fi /opt/xensource/sm/LVHDoISCSISR.py /opt/xensource/sm/LVHDoISCSISR.pyc /opt/xensource/sm/LVHDoISCSISR.pyo +/opt/xensource/sm/LVHDoFCoESR.py +/opt/xensource/sm/LVHDoFCoESR.pyc +/opt/xensource/sm/LVHDoFCoESR.pyo /opt/xensource/sm/LVMSR /opt/xensource/sm/LVMoHBASR /opt/xensource/sm/LVMoISCSISR +/opt/xensource/sm/LVMoFCoESR /opt/xensource/sm/NFSSR /opt/xensource/sm/NFSSR.py /opt/xensource/sm/NFSSR.pyc @@ -192,6 +196,9 @@ fi /opt/xensource/sm/iscsilib.py /opt/xensource/sm/iscsilib.pyc /opt/xensource/sm/iscsilib.pyo +/opt/xensource/sm/fcoelib.py +/opt/xensource/sm/fcoelib.pyc +/opt/xensource/sm/fcoelib.pyo /opt/xensource/sm/journaler.py /opt/xensource/sm/journaler.pyc /opt/xensource/sm/journaler.pyo