别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 工作
  • 规范

  • Linux

  • 数据库

  • Git

  • 👨‍💻Web

  • 英语

  • Docker

  • 编辑器

  • 网络

  • 前端

  • 存储

    • 双活

      • 基于 DRBD 实现的双活方案文档阅读记录
      • AA-ALUA-AP
      • 基于 DRBD 实现的双活方案
    • OpenStack

    • DRBD

    • SCSI、FC、iSCSI 三大协议详解及比较
    • 各种同步工具之间的差异| DRBD vs SCP vs rsync vs mirror
    • RAID 是什么?各类型之间的区别?
    • 磁盘模块
      • 简介
      • 设计实现说明
        • 磁盘名和磁盘位置对应关系模块 - digidiskmap.py
        • 背板厂商判定模块 - digidiskproduct.py
        • 磁盘灯设置模块 - digidisklight.py
        • 使用方法
        • 磁盘名和磁盘位置对应关系模块 - digidiskmap.py
        • 磁盘灯设置模块 - digidisklight.py
    • SAN 和 NAS 的对比
    • scstadmin 命令汇总
    • 双控接管理解
    • 待办事务
    • Storcli 常用管理命令汇总
    • 磁盘阵列控制卡(RAID 卡)MegaCli 常用管理命令汇总
  • 备忘录

  • 如何开始你的单元测试
  • 以程序员的视角看中国——西安篇
  • 💻工作
  • 存储
佚名
2020-05-23
目录

磁盘模块

# 简介

磁盘模块从功能上来说包含两个部分:磁盘名、磁盘位置、背板等磁盘基本信息获取及磁盘灯设置。

从模块上划分为三部分:

  • digidiskmap.py 磁盘名和磁盘位置对应关系模块。
  • digidiskproduct.py 背板厂商判定模块,包含背板上磁盘位置和 phyid 对应关系,包含背板磁盘灯和磁盘状态对应关系。
  • digidisklight.py 磁盘灯设置模块。

# 设计实现说明

# 磁盘名和磁盘位置对应关系模块 - digidiskmap.py

盘位对应关系获取的原理依据背板上 phyid 的位置不变化(固件需要一致,因为厂家更新固件时有可能会改变该对应关系)。

在该原理的前提下,将背板上磁盘位置的顺序也规定下来(从下到上,从左到右,依次增加),这样就能生成磁盘位置和 phyid 的对应关系。

背板插入磁盘后,磁盘名称和 phyid 之间也形成对应,这样通过phyid的衔接,就能找到磁盘名称和磁盘位置的对应关系。

如下表: {%raw%}

Disk Location PhyID Disk Name
21 22 23 24 0 1 2 3 sdb sdc sdd sde
17 18 19 20 4 5 6 7 sdf sdg sdh sdi
13 14 15 16 8 9 10 11 sdj sdk sdl sdm
9 10 11 12 12 13 14 15 sdn sdo sdp sdq
5 6 7 8 16 17 18 19 sdr sds sdt sdu
1 2 3 4 20 21 22 23 sdv sdw sdx sdy
{%endraw%}

# 磁盘位置和 phyid

磁盘位置和 phyid 对应关系的获取,目前是通过 sg3_utils (opens new window) 工具包里的 sg_ses 命令来实现。

执行如下命令,将指定的 phyid 对应的 led 灯点亮,获取磁盘位置和 phyid 之间的对应。

sg_ses --set=fault --index=phyid sg 设备
1
  • –set=fault 将 phyid 对应位置的 led 灯设置为 fault 状态(红色常亮状态)
  • –index=phyid 指定要设置的 phyid。一般来说,phyid 的索引从 0 开始,如果背板有 24 盘位,那么背板的 phyid 就是 0~23。
  • sg 设备 背板对应的设备,可以通过多种方式获取,最简单的方式是通过 sg3_utils 工具包里的 sg_map 命令获取,没有磁盘对应的 sg 设备就是背板的 sg 设备。如下例,/dev/sg4 就是背板的 sg 设备。
[root@Storage ~]# sg_map
/dev/sg0  /dev/sda
/dev/sg1  /dev/sdb
/dev/sg2  /dev/sdc
/dev/sg3  /dev/sdd
/dev/sg4
1
2
3
4
5
6

# 磁盘名称和 phyid

磁盘名称和 phyid 之间的对应关系,是通过目录的遍历来完成(/sys/class/sas_device/),先找到插到背板上所有的磁盘。

[root@Storage ~]# ls -1d /sys/class/sas_device/expander-0:0/device/phy-*/port/end_device-*/target*/*/block/*
/sys/class/sas_device/expander-0:0/device/phy-0:0:13/port/end_device-0:0:0/target0:0:0/0:0:0:0/block/sdb
/sys/class/sas_device/expander-0:0/device/phy-0:0:17/port/end_device-0:0:1/target0:0:1/0:0:1:0/block/sdc
/sys/class/sas_device/expander-0:0/device/phy-0:0:21/port/end_device-0:0:2/target0:0:2/0:0:2:0/block/sdd
1
2
3
4

依次处理:

  1. 每行记录截取到/port/之前的位置,比如”/sys/class/sas_device/expander-0:0/device/phy-0:0:13/port/end_device-0:0:0/target0:0:0/0:0:0:0/block/sdb”,截取的路径为”/sys/class/sas_device/expander-0:0/device/phy-0:0:13”。
  2. 进入截取目录位置,找到子目录”sas_phy”。
  3. 进入”sas_phy”目录,找到以字符”phy-“开始的子目录,一般和第一步截取后目录名相同,这里就是”phy-0:0:13”。
  4. 进入”phy-0:0:13”,读取该目录下的”phy_identifier”文件,获取到的值即为磁盘对应的 phyid。

则磁盘”sdb”对应的 phyid 文件全路径为”/sys/class/sas_device/expander-0:0/device/phy-0:0:13/sas_phy/phy-0:0:13/phy_identifier”,对应的 phyid 为”13”。

# 背板厂商判定模块 - digidiskproduct.py

背板厂商判定模块其实是 Phyid 和磁盘位置关系的固化,当某个固件的背板把 Phyid 和磁盘位置关系找出来以后,在固件不发生大的改变的情况下,这种对应关系是稳定的,为了避免重复性工作,需要将这种关系固化下来。

这样就又需要一种关系映射,也就是需要一个标示、关键字,python 里讲就是需要一个 key,因为这种关系是同背板固件相关,所以就想着从背板上获取这个标示,最后选择根据背板的 product_id(/sys/class/sas_expander/expander-X/product_id)来判断。

还有一个状态会体现在这个 key 里,背板上的插槽数量,也就是这个背板是多少盘位的(8、12、16 还是 24)。

注意:这里 key 没有直接使用 product_id 的值,因为可读性太差,根据不同的 product_id,生成一个厂家和盘位的组合,这个组合被用来当做 key。

比如 product_id 为 80H10341807A0,根据适配的过程,可以知道这是一款勤诚的 24 盘位的背板,那么 key 就是 CHENBROPHYIDMAP24 ,CHENBRO 表示勤诚,PHYIDMAP 表示这是通过 phyid 找位置的映射(phyid 是 key,位置是 value),24 表示 24 盘位。

CHENBROPHYIDMAP24 = {
    '20' : '21','21' : '22','22' : '23','23' : '24',
    '16' : '17','17' : '18','18' : '19','19' : '20',
    '12' : '13','13' : '14','14' : '15','15' : '16',
    '8'  : '9',  '9' : '10','10' : '11','11' : '12',
    '4'  : '5',  '5' : '6',  '6' : '7',  '7' : '8',
    '0'  : '1',  '1' : '2',  '2' : '3',  '3' : '4'
}
1
2
3
4
5
6
7
8

# 磁盘灯设置模块 - digidisklight.py

磁盘灯设置也是使用 sg3_utils 工具包里的 sg_ses 命令来实现(和获取磁盘位置和 phyid 对应关系方法一样)。

模块在通过 phyid 设置 led 灯的基础上进行了扩展,允许通过磁盘位置和磁盘名称来设置 led 灯(对应关系固化前提下)。

sg_ses 命令功能很强大,查看它的帮助信息,可以看到如下:

[root@Storage ~]# sg_ses --help
Usage: sg_ses [--byte1=B1] [--clear=STR] [--control] [--data=H,H...]
              [--descriptor=DN] [--enumerate] [--filter] [--get=STR]
              [--help] [--hex] [--index=IIA | --index=TIA,II]
              [--inner-hex] [--join] [--list] [--nickname=SEN]
              [--nickid=SEID] [--page=PG] [--raw] [--set=STR]
              [--status] [--verbose] [--version] DEVICE
1
2
3
4
5
6
7

我们只使用了其中的 led 灯点亮/熄灭功能。

设置磁盘灯命令如下:

sg_ses --set=STR --index=TIA,II DEVICE
1

清除磁盘灯命令如下:

sg_ses --clear=STR --index=TIA,II DEVICE
1

通过控制背板的 led 灯闪烁的频率或是常亮,我们可以实现不同的组合,对每个组合进行定义,就能表达我们想要的内容。(由于每个背板固件对 led 灯控制的支持不尽相同,所以实际效果是有出入的,需要保证的一点是 损坏 状态一定要明确的表现出来,以便于坏盘的更换。)

和 phyid 和磁盘位置关系的固化一样,这里也是通过背板厂家来区分不同背板 led 灯对应不同的状态,目前已支持的状态如下:

  • 鲸鲨背板
{
    '1' : '',           #使用中
    '2' : 'missing',    #未使用
    '3' : '',           #热备
    '4' : '',           #重构
    '-2': 'fault',      #损坏
    '-1': 'active'      #未激活
}
1
2
3
4
5
6
7
8
  • 迎广背板:
{
    '1' : '',           #使用中
    '2' : 'ok',         #未使用
    '3' : 'hotspare',   #热备
    '4' : 'active',     #重构
    '-2': 'fault',      #损坏
    '-1': 'rsvddevice'  #未激活
}
1
2
3
4
5
6
7
8
  • 勤诚背板:
{
    '1' : '',           #使用中
    '2' : '',           #未使用
    '3' : '',           #热备
    '4' : '',           #重构
    '-2': 'fault',      #损坏
    '-1': ''            #未激活
}
1
2
3
4
5
6
7
8

# 使用方法

磁盘模块使用时主要是调用磁盘名和磁盘位置对应关系模块(digidiskmap.py)和磁盘灯设置模块(digidisklight.py),digidiskproduct.py 基本是常量模块,只有在新的背板适配时才会修改。

# 磁盘名和磁盘位置对应关系模块 - digidiskmap.py

该模块会获取所有的背板和磁盘信息,从固化的磁盘位置和 phyid 映射中查找,匹配成功会返回磁盘和盘位的对应关系,磁盘和 phyid 的对应关系,背板信息。

{%raw%}

作用:

获取当前设备的 磁盘名:磁盘位置 对应关系、磁盘名:phyid 对应关系、背板信息

输入:

jsonformat

参数 值 类型 释义
jsonformat True|False bool 是否以JSON字符串格式返回
输出:

[disknamemap,disknamephymap,expanders]

参数 值 类型 释义
disknamemap {磁盘名称:磁盘位置} dict 磁盘和盘位对应关系
disknamephymap {磁盘名称:phyid} dict 磁盘和盘位对应关系
expanders {背板编号:{背板信息}} dict 背板信息
示例:
>>> from digidisk import digidiskmap
>>> digidiskmap.get_diskmap(False)
[
   {'sdd': '0-22', 'sdb': '0-14', 'sdc': '0-18'},
   {'sdd': '21', 'sdb': '13', 'sdc': '17'},
   {'0':
       {
           'id': '0',
           'name': 'expander-0:0',
           'count': '24',
           'product': 'CHENBRO',
           'smpdevice': 'sg4',
           'model': '80H10341807A0',
           'sasaddress': '0x5001c45001d099bf',
           'hard': False
       }
   }
]
{%endraw%}

# 磁盘灯设置模块 - digidisklight.py

该模块会根据用户传入的 phyid、磁盘位置、磁盘名称,状态等参数,设置或清除对应位置的 led 灯状态。

传入的状态可以为具体的状态值(string),也可以预定义的状态值对应的数字。

磁盘状态 {%raw%}

磁盘状态¶
数字 对应的状态 释义
1 inuse 使用中
2 unuse 未使用
3 spare 热备
4 rebuild 重构
-1 inactive 未激活
-2 broken 损坏
{%endraw%}

# 设置磁盘灯状态

setdisklight(**kwargs)¶ {%raw%}

作用:

设置 指定位置 或 整个背板 的 磁盘灯 为 指定状态

说明:
  1. dpid、dlid和dname中的任意一个参数都对应背板上一个固定位置。使用dpid和dlid时,如果未体现背板信息(如:0-X),就需要通过eid或esg等参数来补充。
  2. 未指定dpid、dlid、dname等定位参数但指定esg、eid等背板参数时,设置整个背板。
输入:

键值对

参数 值 类型 释义
dpid X-X|X,X为数字 string 磁盘对应的phy_identifier编号。格式为0-0,表示expanderid:phyid,如果格式为0,则需要指定eid或esg。
dlid X-X|X,X为数字 string 磁盘对应的位置编号。格式为0-1,表示expanderid:locateid;如果格式为1,则需要指定eid或esg。
dname sdX。 string 磁盘名称。如果指定esg或eid,在对应背板上搜索磁盘;未指定时需遍历所有背板。
esg /dev/sgX,X为数字 string 背板对应的sg设备
eid X,X为数字 string 背板对应的编号
eproduct INWIN|CHENBRO|ESTOR string 背板厂商。和ecount组合,在只提供dlid的时候获取phy_identifier编号。
ecount 8|12|16|24 string 背板盘位
light 1|2|3|4|-1|-2 inuse|unuse|spare|rebuild|inactive|fault missing|fault|active|locate|hotspare|rsvddevice string 磁盘灯状态。参考 磁盘状态。
输出:

数字

参数 值 类型 释义
retcode 0|-1|-2|-3|-4 int 设置磁盘灯结果
释义:
值 释义
0 成功
-1 参数不足
-2 错误的磁盘灯
-3 未适配背板灯
-4 未适配背板盘位
示例:
#设置phyid为22的位置状态为'-2'(broken)
>>> from digidisk import digidisklight
>>> digidisklight.setdisklight({'dpid':'22','esg':'sg4','light':'-2'})
0
#设置磁盘位置为12的状态为broken
>>> digidisklight.setdisklight({'dlid':'0-12','light':'broken'})
0
#设置phyid为22的位置状态为broken
>>> digidisklight.setdisklight({'dpid':'0-22','light':'broken'})
0
#设置磁盘sdb状态为broken
>>> digidisklight.setdisklight({'dname':'sdb','light':'broken'})
0
{%endraw%}

# 清除磁盘灯状态

cleardisklight(**kwargs)¶

{%raw%}

作用:

清除 指定位置 或 整个背板 的 磁盘灯 的 指定状态 或 全部状态

说明:
  1. 指定磁盘灯状态时只清除该状态,不指定磁盘灯状态时清除所有状态。
  2. 未指定dpid、dlid、dname等定位磁盘参数但指定esg、eid等背板参数时,清除整个背板。
  3. 需要注意的是,因为背板固件支持的不同,不是所有磁盘状态都有表现在磁盘灯上,这里只能保证 磁盘损坏 时的磁盘灯状态。
输入:

键值对

参数 值 类型 释义
dpid X-X|X,X为数字 string 磁盘对应的phy_identifier编号。格式为0-0,表示expanderid:phyid,如果格式为0,则需要指定eid或esg。
dlid X-X|X,X为数字 string 磁盘对应的位置编号。格式为0-1,表示expanderid:locateid;如果格式为1,则需要指定eid或esg。
dname sdX。 string 磁盘名称。如果指定esg或eid,在对应背板上搜索磁盘;未指定时需遍历所有背板。
esg /dev/sgX,X为数字 string 背板对应的sg设备
eid X,X为数字 string 背板对应的编号
eproduct INWIN|CHENBRO|ESTOR string 背板厂商。和ecount组合,在只提供dlid的时候获取phy_identifier编号。
ecount 8|12|16|24 string 背板盘位
light 1|2|3|4|-1|-2 inuse|unuse|spare|rebuild|inactive|fault missing|fault|active|locate|hotspare|rsvddevice string 磁盘灯状态。参考 磁盘状态。
输出:

数字

参数 值 类型 释义
retcode 0|-1|-2|-3|-4 int 清除磁盘灯结果
释义:
值 释义
0 成功
-1 参数不足
-2 错误的磁盘灯
-3 未适配背板灯
-4 未适配背板盘位
示例:
#清除编号为0的背板上所有位置所有状态
>>> from digidisk import digidisklight
>>> digidisklight.cleardisklight({'eid':'0'})
0
#清除编号为0的背板上phyid为22位置的所有状态
>>> digidisklight.cleardisklight({'dpid':'0-22'})
0
#phyid不包含背板信息时,需要单独指定eid或esg。
>>> digidisklight.cleardisklight({'dpid':'22','eid':'0'})
0
#清除磁盘sdb状态broken
>>> digidisklight.cleardisklight({'dname':'sdb','light':'broken'})
0
{%endraw%}

编辑 (opens new window)
#面试#Python
上次更新: 2024-07-15, 08:03:22
RAID 是什么?各类型之间的区别?
SAN 和 NAS 的对比

← RAID 是什么?各类型之间的区别? SAN 和 NAS 的对比→

最近更新
01
提升沟通亲和力的实用策略
03-26
02
工作
07-15
03
如何选房子
06-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式