支持 System z 上 Linux 的 ECKD 卷¶
https://blueprints.launchpad.net/cinder/+spec/linux-ficon-support
FICON(光纤连接)是一种光纤通道 FC-4 层协议。它在大型机上用于通过光纤通道连接 ECKD 卷。为了允许 Cinder 管理 Linux on System z 上的基于 FICON 的块存储,需要进行一些更改。
此外,需要为支持 ECKD(例如 IBM DS8000)的存储子系统的现有 Cinder 驱动程序添加支持。
Nova 中所需的支持由单独的蓝图描述,该蓝图列为以下依赖项。
问题描述¶
FICON 和 FCP 都是光纤通道 FC-4 层协议。FICON 使用与 FCP 不同的方案来寻址卷。
ECKD 卷通过控制单元和单元地址进行寻址,而不是 WWPN 和 LUN。
System z 使用与 System z 上 FCP 使用的文件路径类似的基于 ccw 的设备文件路径格式(而不是基于 pci 的格式)。
在使用 ECKD 卷之前,需要将其设置为联机状态并进行格式化
用例¶
允许最终用户创建和管理基于连接到 FICON 的存储子系统的 Cinder 块设备,这些存储子系统支持 ECKD 协议。例如:创建、删除、镜像部署、快照等。
我们将扩展 IBM DS8000 的 Cinder 驱动程序。其他供应商,如 EMC、日立或 HP 也支持 ECKD。它们是潜在的候选者。
提议的变更¶
更改 os-brick 中的代码以解决这些问题,具体取决于驱动程序提供的新的协议类型“fibre_channel_eckd”。有关详细信息,请参阅 工作项目 部分。
备选方案¶
无
数据模型影响¶
无
REST API 影响¶
无
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
支持 FICON/ECKD 的平台需要为其驱动程序实现此功能。
实现¶
负责人¶
- 主要负责人
stefan-amann
- 其他贡献者
arecknag maiera
工作项¶
在 os-brick/initiator/connector.py
提供新的连接器 FibreChannelECKDConnector
connect_volume 需要为卷启用中断并将卷设置为联机状态。这是通过调用新的 configure_eckd_device() 函数完成的)
disconnect_volume 需要将卷设置为脱机状态。这是通过调用新的 deconfigure_eckd_device() 函数完成的
在 os-brick/initiator/linuxeckd.py
用于将卷设置为联机状态、验证其格式是否正确以及在需要时对其进行格式化的实用程序函数
def _is_online(self, device): """ Return True if device is online, else return False :param device: device id """ if os.access('/sys/bus/ccw/devices/%s/online' % device, os.R_OK): online_file = None try: online_file = open('/sys/bus/ccw/devices/%s/online' % device) value = online_file.readline() if value and value.strip() == '1': return True finally: if online_file: online_file.close() return False def _is_formatted(self, device): """ Return True if device is online, else return False :param device: device id """ if os.access('/sys/bus/ccw/devices/%s/status' % device, os.R_OK): formatted = None (out, _err) = self._execute('cat', '/sys/bus/ccw/devices/%s/status' % device, run_as_root=True, root_helper=self._root_helper) if out and out.strip() == 'unformatted': return False return True def format_eckd_volume(self, path): """ formats ECKD volume :param device: device path """ name = os.path.realpath(path) if name.startswith("/dev/"): format_cmd = 'dasdfmt -y -b 4096 -d ldl ' + name (out, _err) = self._execute(format_cmd, run_as_root=True, root_helper=self._root_helper) return True else: return False
在 os-brick/initiator/linuxfc.py
新的类 LinuxFibreChannelECKD
def configure_eckd_device(self, device_number):
"""Add the eckd volume to the Linux configuration. """
full_device_identifier = "0.0.%04x" % device_number
eckd_device_command = ('cio_ignore', '-r',
'%(dev_id)s' % {"dev_id": full_device_identifier})
LOG.debug("issue cio_ignore for s390: %s", eckd_device_command)
out, info = None, None
try:
out, info = self._execute('cio_ignore', '-r',
'%(dev_id)s' % {"dev_id": full_device_identifier},
run_as_root=True,
root_helper=self._root_helper)
except putils.ProcessExecutionError as exc:
LOG.warning(_LW("cio_ignore call for s390 failed exit"
" %(code)s, stderr %(stderr)s"),
{'code': exc.exit_code, 'stderr': exc.stderr})
eckd_device_command = ('chccwdev', '-e',
'%(dev_id)s' % {"dev_id": full_device_identifier})
LOG.debug("add ECKD command for s390: %s", eckd_device_command)
out, info = None, None
try:
out, info = self._execute('chccwdev', '-e',
'%(dev_id)s' % {"dev_id": full_device_identifier},
run_as_root=True,
root_helper=self._root_helper)
except putils.ProcessExecutionError as exc:
LOG.warning(_LW("add ECKD call for s390 failed exit"
" %(code)s, stderr %(stderr)s"),
{'code': exc.exit_code, 'stderr': exc.stderr})
def deconfigure_eckd_device(self, device_number):
"""Remove the eckd volume from the Linux configuration. """
LOG.debug("Deconfigure ECKD volume: device_number=%(device_num)s ",
{'device_num': device_number})
full_device_identifier = "0.0.%04x" % device_number
eckd_device_command = ('chccwdev', '-d',
'%(dev_id)s' % {"dev_id": full_device_identifier})
LOG.debug("remove ECKD command for s390: %s", eckd_device_command)
out, info = None, None
try:
out, info = self._execute('chccwdev', '-d',
'%(dev_id)s' % {"dev_id": full_device_identifier},
run_as_root=True,
root_helper=self._root_helper)
except putils.ProcessExecutionError as exc:
LOG.warning(_LW("remove ECKD call for s390 failed exit"
" %(code)s, stderr %(stderr)s"),
{'code': exc.exit_code, 'stderr': exc.stderr})
对 volume.filters 的调整,以允许发送新的命令
Cinder 驱动程序需要报告 ECKD 卷的控制单元地址和单元地址,并将 driver_volume_type 设置为“fibre_channel_eckd”。
希望支持 FICON 的任何驱动程序都需要针对连接到 FICON 的主机运行 CI 报告结果。
依赖项¶
Nova 蓝图,用于为 System z 上的 Linux 添加对 ECKD 的支持。该蓝图可以在这里找到:https://blueprints.launchpad.net/nova/+spec/linux-ficon-support
测试¶
单元测试
将在 System z 以及基于 Intel 的机器上添加和执行单元测试。
CI 环境
我们将为 DS8000 提供第三方 CI 环境。
文档影响¶
我们将根据需要更新文档。
参考资料¶
Linux on System z 设备驱动程序手册,http://public.dhe.ibm.com/software/dw/linux390/docu/l316dd25.pdf
Linux on System z,http://www.ibm.com/developerworks/linux/linux390/