1# All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may 4# not use this file except in compliance with the License. You may obtain 5# a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations 13# under the License. 14 15from oslo_log import log as logging 16 17from os_brick import initiator 18from os_brick.initiator.connectors import fibre_channel 19from os_brick.initiator import linuxfc 20 21LOG = logging.getLogger(__name__) 22 23 24class FibreChannelConnectorS390X(fibre_channel.FibreChannelConnector): 25 """Connector class to attach/detach Fibre Channel volumes on S390X arch.""" 26 27 platform = initiator.PLATFORM_S390 28 29 def __init__(self, root_helper, driver=None, 30 execute=None, use_multipath=False, 31 device_scan_attempts=initiator.DEVICE_SCAN_ATTEMPTS_DEFAULT, 32 *args, **kwargs): 33 super(FibreChannelConnectorS390X, self).__init__( 34 root_helper, 35 driver=driver, 36 execute=execute, 37 device_scan_attempts=device_scan_attempts, 38 *args, **kwargs) 39 LOG.debug("Initializing Fibre Channel connector for S390") 40 self._linuxfc = linuxfc.LinuxFibreChannelS390X(root_helper, execute) 41 self.use_multipath = use_multipath 42 43 def set_execute(self, execute): 44 super(FibreChannelConnectorS390X, self).set_execute(execute) 45 self._linuxscsi.set_execute(execute) 46 self._linuxfc.set_execute(execute) 47 48 def _get_host_devices(self, possible_devs): 49 host_devices = [] 50 for pci_num, target_wwn, lun in possible_devs: 51 host_device = self._get_device_file_path( 52 pci_num, 53 target_wwn, 54 lun) 55 # NOTE(arne_r) 56 # LUN driver path is the same on all distros, so no need to have 57 # multiple calls here 58 self._linuxfc.configure_scsi_device(pci_num, target_wwn, 59 self._get_lun_string(lun)) 60 host_devices.extend(host_device) 61 return host_devices 62 63 def _get_lun_string(self, lun): 64 target_lun = 0 65 if lun <= 0xffff: 66 target_lun = "0x%04x000000000000" % lun 67 elif lun <= 0xffffffff: 68 target_lun = "0x%08x00000000" % lun 69 return target_lun 70 71 def _get_device_file_path(self, pci_num, target_wwn, lun): 72 # NOTE(arne_r) 73 # Need to add multiple possible ways to resolve device paths, 74 # depending on OS. Since it gets passed to '_get_possible_volume_paths' 75 # having a mismatch is not a problem 76 host_device = [ 77 # RHEL based 78 "/dev/disk/by-path/ccw-%s-zfcp-%s:%s" % ( 79 pci_num, target_wwn, self._get_lun_string(lun)), 80 # Debian based (e.g. for storwize) 81 "/dev/disk/by-path/ccw-%s-fc-%s-lun-%s" % ( 82 pci_num, target_wwn, lun), 83 # Debian based (e.g. for ds8k) 84 "/dev/disk/by-path/ccw-%s-fc-%s-lun-%s" % ( 85 pci_num, target_wwn, self._get_lun_string(lun)), 86 ] 87 return host_device 88 89 def _remove_devices(self, connection_properties, devices, device_info): 90 hbas = self._linuxfc.get_fc_hbas_info() 91 targets = connection_properties['targets'] 92 possible_devs = self._get_possible_devices(hbas, targets) 93 for platform, pci_num, target_wwn, lun in possible_devs: 94 target_lun = self._get_lun_string(lun) 95 self._linuxfc.deconfigure_scsi_device(pci_num, 96 target_wwn, 97 target_lun) 98