Linux SCSI磁盘工作原理与故障诊断实战
发布时间:2026/10/10 3:48:17 锦皓数字建站

1. 项目概述从一块“看不见”的硬盘说起你有没有遇到过这种情况服务器上明明插着一块新硬盘lsblk列表里却找不到它或者fdisk -l输出里突然多出几个/dev/sdb、/dev/sdc这样的设备名但它们既不响应分区命令又在系统日志里反复报错“SCSI command timeout”这时候你面对的不是一块普通的U盘或NVMe固态而是一个典型的SCSI磁盘——它不靠USB协议握手也不走PCIe直连通道而是通过一套更古老、更严谨、也更“讲规矩”的通信机制在和主机对话。这个机制的名字就叫 SCSISmall Computer System Interface。很多人一听到“SCSI”第一反应是“老古董”觉得那是90年代服务器机柜里嗡嗡作响的宽条带线缆和带拨码开关的硬盘阵列。但事实恰恰相反今天你用的每一块企业级SAS硬盘、每一台全闪存存储阵列、甚至云服务商底层物理节点上挂载的高性能块设备背后驱动它们与主机通信的绝大多数仍是 SCSI 协议栈。只不过它早已脱下并行电缆的外壳穿上 SASSerial Attached SCSI的西装再悄悄藏进 NVMe over Fabrics 的抽象层之下。SCSI 磁盘不是历史遗迹而是现代数据中心块存储的隐形骨架。它解决的核心问题非常朴素如何让主机操作系统能以统一、可靠、可扩展的方式去发现、识别、读写、管理成百上千块物理或虚拟磁盘无论它们是机械盘、SSD还是远程存储网关映射过来的LUN。我第一次真正“看见”SCSI磁盘是在某次线上故障排查中。一台数据库服务器IO延迟突增iostat显示某块盘的%util长期卡在100%但dmesg里却不断刷出scsi 0:0:0:0: rejecting I/O to offline device。当时完全懵了——设备明明在线怎么又说“offline”后来才明白这不是硬件坏了而是 SCSI 中间层的“设备状态机”在告诉你这块盘虽然物理链路通但它的内部逻辑单元LUN已因某种原因被主动隔离。这种细粒度的状态反馈能力正是 SCSI 区别于其他接口的本质特征。它不只传数据更在持续传递“健康语义”。所以这篇内容不是教你怎么格式化一块硬盘而是带你钻进 Linux 内核的 SCSI 子系统看清一块磁盘从加电自检、到被内核识别、再到最终挂载为/dev/sdX的完整生命旅程。适合所有需要直面存储底层的运维工程师、存储开发人员、以及想搞懂“为什么我的新盘死活不认”的系统管理员。你不需要会写内核模块但得愿意看懂sg_inq的输出、理解rescan-scsi-bus.sh在做什么、知道sd_mod和scsi_mod模块谁先加载谁后加载。2. SCSI磁盘的设计逻辑与核心架构解析2.1 为什么非得是SCSI——协议分层与设计哲学要真正理解 SCSI 磁盘必须先扔掉“它就是一种硬盘接口”的简单认知。SCSI 本质上是一套面向设备的客户端-服务器通信协议族它的设计哲学和 TCP/IP 很像把复杂问题分层解决每一层只关心自己的事。整个协议栈可以清晰地划分为三层物理层Physical Layer负责电信号传输。早期是并行SCSI50针/68针现在主流是串行SCSISAS速率从3Gbps一路升级到24Gbps。这一层决定了线缆能跑多快、能接几米、最多挂多少设备。传输层Transport Layer定义数据包如何封装、寻址、路由。SAS 使用类似以太网的“源/目的地址”方式SAS Address而 FCFibre Channel则用 WWNWorld Wide Name。这一层让 SCSI 命令能跨网络传输为 SANStorage Area Network打下基础。应用层Application Layer也就是我们常说的SCSI Command Set。这才是 SCSI 的灵魂所在。它定义了一套标准化的、设备无关的命令集比如INQUIRY查询设备身份、READ CAPACITY读取容量、TEST UNIT READY测试设备是否就绪、READ(10)/WRITE(10)读写数据等等。关键点在于这些命令对所有符合 SCSI 标准的设备都一样。无论是希捷的机械盘、三星的SSD还是某厂商的磁带库只要它宣称支持 SCSI就必须正确响应INQUIRY命令并返回标准格式的 Vendor ID、Product ID、Revision Level。这使得操作系统内核只需编写一套 SCSI 中间层驱动就能管理千差万别的后端存储设备。这种“协议即驱动”的思想是 SCSI 能统治企业存储三十年的根本原因。对比一下 USB 存储类USB Mass Storage Class它其实也是在模拟 SCSI 命令把 USB 设备包装成一个“伪SCSI设备”来用。而 NVMe 虽然原生是 PCIe 协议但为了兼容现有工具链Linux 内核也提供了nvme-cli工具其命令风格如nvme id-ctrl明显是在向sg_inq看齐。这恰恰说明SCSI 的命令语义已经成了存储领域的“通用语言”。2.2 SCSI设备模型Target、LUN与Host Bus Adapter的三角关系在 SCSI 世界里没有“硬盘”这个说法只有Target目标设备和LUNLogical Unit Number逻辑单元号。这是一个非常重要的概念转换。一台物理的 SAS 硬盘在 SCSI 模型中通常表现为一个 Target由其 SAS 地址唯一标识而这个 Target 内部可以包含多个 LUN。对于普通单盘它只有一个 LUN 0但对于高端存储阵列一个 Target 可能暴露几十个 LUN每个 LUN 对应一个独立的逻辑卷Volume。而主机这边则由HBAHost Bus Adapter主机总线适配器来扮演“SCSI Initiator发起者”的角色。HBA 不是简单的信号转换器它是一个智能的通信协处理器。当你插入一块 LSI SAS 9300-8i HBA 卡时Linux 内核会加载mpt3sas驱动该驱动会创建一个hostX如host0实例。这个hostX就是 SCSI 总线的根节点。随后内核会扫描这条总线上所有可能的 Target ID通常是 0-15 或 0-127对每个发现的 Target再遍历其 LUN 0-255逐个发送INQUIRY命令。只有成功收到响应的 TargetLUN 组合才会被注册为一个 SCSI 设备并最终映射为/dev/sdX。这个过程可以用一个真实命令链来验证# 查看当前系统中所有的SCSI Host $ ls /sys/class/scsi_host/ host0 host1 # 查看host0下扫描到了哪些Target设备 $ ls /sys/class/scsi_host/host0/device/target0:0/ 0:0:0 0:0:1 0:0:2 # 进入其中一个Target查看其LUN信息 $ ls /sys/class/scsi_host/host0/device/target0:0/0:0:0/ device driver power subsystem uevent # 注意这里的 0:0:0 表示 host0, channel 0, target 0, lun 0你会发现/sys/class/scsi_host/host0/device/target0:0/0:0:0/这个路径就是内核为这个 SCSI 设备创建的“数字身份证”。所有关于它的属性型号、序列号、状态都挂在这个目录下。这种基于 sysfs 的层次化组织正是 Linux 内核对 SCSI 设备模型的完美实现。2.3 SCSI磁盘在Linux中的生命周期从加电到/dev/sdX一块 SCSI 磁盘在 Linux 系统中的“出生”是一个严格遵循状态机的流程。它不是一插上就立刻可用而是要经历一系列内核事件的触发与响应。这个生命周期大致可分为四个阶段物理连接与链路建立Link UpHBA 卡检测到 SAS 信号稳定完成 PHY 初始化建立与 Target 的 SAS Link。此时dmesg会输出类似mpt3sas0: sas_device_add: handle(0x0001), sas_addr(0x5000c500a1234567)的日志。注意这时设备还只是“物理可见”内核尚未开始逻辑识别。设备发现与初始化Discovery InitializationHBA 驱动调用scsi_scan_target()函数向该 Target 的 LUN 0 发送INQUIRY命令。如果得到有效响应内核就会为这个 TargetLUN 创建一个struct scsi_device结构体并将其加入 SCSI 设备链表。紧接着会发送READ CAPACITY获取容量MODE SENSE获取配置参数。这是最关键的一步也是最容易失败的一步。如果INQUIRY超时内核会标记该设备为offline后续所有 IO 都会被拒绝。块设备注册Block Device Registration当 SCSI 设备初始化成功后内核会调用scsi_add_lun()为其分配一个struct scsi_disk结构体并最终调用add_disk()将它注册为一个通用块设备gendisk。此时/dev/sdX才真正出现在文件系统中lsblk才能看到它。用户空间接管User Space Takeoverudev守护进程监听内核的uevent一旦发现新的block类型设备就会根据规则如/lib/udev/rules.d/60-persistent-storage.rules为其生成持久化设备名如/dev/disk/by-id/wwn-0x5000c500a1234567并可能触发partprobe扫描分区表。这个过程之所以重要是因为每一个环节都对应着一个可诊断的故障点。比如如果你的盘在dmesg里能看到sas_device_add但lsblk里没有那问题一定出在第二步——INQUIRY命令没响。这时候你就该怀疑是盘本身固件问题、HBA 固件版本不匹配、或者 SAS 线缆质量不过关了。3. 核心细节解析与实操要点从命令行到内核日志3.1 必须掌握的5个SCSI诊断命令及其深层含义在日常运维中有五个命令是你定位 SCSI 磁盘问题的“瑞士军刀”。它们不只是显示信息更是与 SCSI 设备进行直接对话的接口。下面我逐个拆解其原理、输出解读和典型应用场景。1.sg_inq设备的“身份证扫描仪”sg_inq是sg3_utils工具包中的核心命令用于发送 SCSIINQUIRY命令。它比hdparm -I或smartctl -i更底层因为它绕过了块设备层直接与 SCSI 设备通信。# 基本用法查询/dev/sdb的INQUIRY信息 $ sg_inq /dev/sdb standard INQUIRY: PQual0 Device_type0 RMB0 version0x06 [SPC-4] [AERC0] [TrmTsk0] [NormACA0] [HiSUP0] [VSD0] [MChngr0] [MultI0] [Addr160] [RelAdr0] [WBus160] [Sync0] [Linked0] [CmdQue1] [SftRe0] length96 (0x60) Peripheral device type: disk Vendor identification: SEAGATE Product identification: ST4000NM0035 Product revision level: EN03 Unit serial number: ZA1B2C3D这段输出里藏着大量关键信息Device_type0表示这是一个 Direct Access DeviceDAD即我们常说的磁盘。如果是0x05那就是 CD/DVD 驱动器。CmdQue1表示该设备支持命令队列Command Queuing这是实现高并发 IO 的基础。Vendor identification和Product identification这是设备的“真名”比lsblk里的MODEL字段更权威因为它是设备固件直接返回的。Unit serial number全球唯一的序列号是资产管理和故障追踪的黄金字段。提示如果sg_inq执行超时或报错SCSI status: CHECK CONDITION说明设备根本没响应INQUIRY命令。此时不要急着换盘先检查dmesg | grep -i scsi.*error看是否有链路层错误如SAS link down。2.sg_readcap获取“真实容量”的终极手段fdisk -l或lsblk显示的容量有时会和你预期的不符。这往往是因为分区表损坏或者设备被做了逻辑卷映射。sg_readcap直接向设备询问其原始物理容量结果最可信。$ sg_readcap /dev/sdb Read capacity (10) returns: last logical block address7814037167, number of blocks7814037168 Logical block length512 bytes这里last logical block addressLBA是最后一个扇区的编号number of blocks是总扇区数。计算总容量7814037168 * 512 / 1024^4 ≈ 3.64 TB。这个数字就是这块盘出厂时标称的裸容量不受任何软件层影响。3.sg_turs测试设备“心跳”的最快方法TEST UNIT READYTUR命令是 SCSI 中最轻量级的“ping”。它不读写任何数据只问设备一句“你还活着吗” 响应时间极短是监控设备在线状态的首选。# 发送一次TUR-r 表示静默模式只返回状态码 $ sg_turs -r /dev/sdb # 返回0表示成功非0表示失败你可以把它写进一个简单的监控脚本每隔5秒执行一次一旦连续3次失败就触发告警。这比依赖iostat的%util或await更早发现问题。4.sg_vpd挖掘设备隐藏的“技术档案”VPDVital Product Data是 SCSI 设备中一个特殊的“扩展信息区”里面存放着标准INQUIRY不包含的深度信息比如设备的固件版本、支持的命令集、电源管理特性等。# 查询设备的固件版本VPD page 0xB0 $ sg_vpd -p b0 /dev/sdb SAS device descriptor VPD page (B0h): Device type: disk SAS address: 0x5000c500a1234567 Device vendor: SEAGATE Device product: ST4000NM0035 Device revision: EN03 Firmware revision: EN03注意这里的Firmware revision和INQUIRY里的Product revision level是同一个东西但VPD还能查到更多比如sg_vpd -p 0x83可以查到设备的 WWNWorld Wide Name这是 SAN 环境中做 LUN Masking 的关键依据。5.sg_logs解读设备“健康日记”的密钥高端 SCSI 设备尤其是企业级 SSD 和 SAS 盘内部都有一个LOG SENSE机制用来记录详细的运行日志包括温度、重分配扇区计数、校验错误等。sg_logs就是用来读取这些日志的。# 读取错误日志页page 0x0d $ sg_logs -p 0xd /dev/sdb Error Recovery page (0dh): ... Read retry count: 0x00000000 Write retry count: 0x00000000 Total errors corrected: 0x00000000如果Total errors corrected数值在缓慢增长说明盘正在默默修复坏道这是即将失效的早期预警信号。而Read retry count如果非零则表明读取时遇到了困难需要重点关注。3.2/sys/class/scsi_device/内核为你准备的“设备控制台”Linux 内核通过sysfs文件系统将每一个 SCSI 设备的内部状态以文件的形式暴露给用户空间。这是比任何命令行工具都更直接、更实时的诊断入口。进入/sys/class/scsi_device/目录你会看到一堆形如0:0:0:0的子目录。这个四元组的含义是host:bus:target:lun。例如0:0:0:0表示 host0 上channel 0通常SAS HBA只有一个channeltarget 0lun 0 的设备。在这个目录下有几个关键文件值得你每天打开看看state设备的当前状态。常见值有running一切正常可接受IO。blocked设备被手动或自动阻塞如echo 1 /sys/class/scsi_device/0:0:0:0/device/state。offline设备已离线所有IO都会失败。这是最危险的状态。transport-offline物理链路断开。iodone_cnt和ioerr_cnt这两个计数器是性能分析的黄金指标。iodone_cnt记录了该设备成功完成的IO请求数ioerr_cnt记录了失败的请求数。你可以用watch -n 1 cat /sys/class/scsi_device/0:0:0:0/device/iodone_cnt; cat /sys/class/scsi_device/0:0:0:0/device/ioerr_cnt实时观察。如果ioerr_cnt在稳定增长而iodone_cnt增长缓慢那基本可以断定是硬件问题。queue_depth设备的队列深度。这个值决定了该设备一次最多能处理多少个并发IO请求。对于高性能SSD这个值通常设为256或更高而对于老式机械盘32就足够了。你可以动态调整它# 将队列深度临时改为128需root权限 $ echo 128 /sys/class/scsi_device/0:0:0:0/device/queue_depth这个操作无需重启立即生效。但要注意设得太高可能导致设备固件处理不过来反而增加延迟。timeoutSCSI命令的超时时间单位秒。默认是30秒。对于某些慢速设备如磁带库你可能需要把它调大到300秒否则一个正常的备份操作就会被内核误判为超时。注意对sysfs文件的写操作是危险的务必确认自己清楚后果。修改queue_depth或timeout是安全的但修改state为offline会立刻让设备不可用。3.3dmesg日志读懂内核的“故障报告单”当 SCSI 磁盘出现问题时dmesg输出的日志就是内核给你写的“故障分析报告”。它不像smartctl那样只告诉你“SMART Status: PASSED”而是详细描述了问题发生的精确时刻、具体命令、错误代码和可能原因。学会阅读它是成为资深存储工程师的第一步。一条典型的 SCSI 错误日志如下[123456.789012] sd 0:0:0:0: [sdb] tag#123 FAILED Result: hostbyteDID_OK driverbyteDRIVER_SENSE [123456.789013] sd 0:0:0:0: [sdb] tag#123 Sense Key : Medium Error [current] [123456.789014] sd 0:0:0:0: [sdb] tag#123 Add. Sense: Unrecovered read error [123456.789015] sd 0:0:0:0: [sdb] tag#123 CDB: Read(10) 28 00 00 00 00 00 00 00 08 00 [123456.789016] print_req_error: I/O error, dev sdb, sector 0我们来逐行解读tag#123这是内核为这个IO请求分配的唯一标签用于在日志中追踪。FAILED Result: hostbyteDID_OK driverbyteDRIVER_SENSEhostbyteDID_OK表示HBA卡本身工作正常没有链路错误driverbyteDRIVER_SENSE表示错误信息在 SCSI Sense Data 中需要进一步解析。Sense Key : Medium Error [current]这是 SCSI 错误分类的最高级别。Medium Error意味着介质即磁盘盘片或SSD NAND出了问题不是控制器或缓存的问题。Add. Sense: Unrecovered read error这是更具体的错误描述意思是“无法恢复的读取错误”即磁盘尝试了所有纠错手段ECC后仍然无法正确读出数据。这通常意味着该扇区已经物理损坏。CDB: Read(10) ...这是导致错误的原始 SCSI 命令Command Descriptor BlockRead(10)表示10字节长度的读命令后面的十六进制数是LBA地址和长度。这里00 00 00 00 00表示LBA 0也就是硬盘的第一个扇区MBR。这条日志告诉我们问题出在磁盘的物理介质上位置是第一个扇区而且是不可修复的。这时候smartctl -a /dev/sdb的输出里Reallocated_Sector_Ct或Current_Pending_Sector计数器一定会很高。这就是dmesg日志的价值——它把模糊的“IO错误”精准定位到了“哪个扇区、什么错误类型”。4. 实操过程与核心环节实现从故障复现到根因定位4.1 场景还原一次真实的“盘消失”故障排查全过程让我们把前面学到的所有知识放进一个真实的、高压的故障场景里手把手带你走一遍完整的排查流程。这个场景是我去年在某金融客户现场处理的一个经典案例。故障现象一台运行Oracle RAC的数据库服务器凌晨3点左右集群心跳中断crsctl check crs显示CRS-4638: Oracle High Availability Services is online但crsctl stat res -t显示所有数据库资源都处于OFFLINE状态。dmesg里滚动刷出大量 SCSI 错误lsblk输出中原本应该存在的/dev/sdc和/dev/sdd两块用于OCR和Voting Disk的共享盘彻底消失了。第一步快速确认物理连接5分钟这不是一个“软故障”首先排除物理层。我立刻登录服务器拔掉机箱侧板找到那块 LSI SAS 9207-8i HBA 卡。卡上的两个 SAS 接口指示灯Link LED都是绿色常亮说明物理链路是通的。接着我检查连接到存储阵列的 SAS 线缆两端的接头都插得严丝合缝没有松动。物理层暂时过关。第二步检查内核SCSI Host状态3分钟$ dmesg | grep -i sas\|scsi [123456.123456] mpt3sas0: LSISAS3008: FWVersion(16.00.00.00), ChipRevision(0x02), BiosVersion(00.00.00.00) [123456.123457] mpt3sas0: sas_device_add: handle(0x0001), sas_addr(0x5000c500a1234567) [123456.123458] mpt3sas0: sas_device_add: handle(0x0002), sas_addr(0x5000c500a1234568) ... [123456.789012] sd 0:0:0:0: [sdb] tag#123 FAILED Result: hostbyteDID_OK driverbyteDRIVER_SENSE ... [123456.999999] mpt3sas0: removing device: handle(0x0001), sas_addr(0x5000c500a1234567)关键线索出现了最后一条日志removing device说明内核已经主动将这个 SAS 设备从 SCSI 总线上移除了。handle(0x0001)对应的就是那块丢失的盘。这证明问题不在物理连接而在设备自身的逻辑状态。第三步尝试强制重扫2分钟既然设备被移除了最直接的办法就是让它重新“上线”。我执行# 向host0发送重扫命令 $ echo - - - /sys/class/scsi_host/host0/scan # 或者使用更精确的命令只扫特定target $ echo 0 0 0 /sys/class/scsi_host/host0/scan等待10秒再次执行lsblk。结果令人失望/dev/sdc和/dev/sdd依然不见踪影。dmesg里也没有新的sas_device_add日志。这意味着重扫失败设备没有响应。第四步深入诊断——用sg_inq直连8分钟既然lsblk看不到那就跳过块设备层直接和 SCSI 设备对话。我找到了这块盘在存储阵列上的 WWN5000c500a1234567然后用sg_inq尝试$ sg_inq -p 0x83 /dev/sg0 # /dev/sg0 是HBA卡对应的SCSI Generic设备输出为空且命令卡住。这证实了我的猜想设备对INQUIRY命令完全无响应。此时我立刻联系了存储阵列的管理员让他在阵列管理界面里查看这块LUN的状态。果然界面显示该LUN处于Degraded降级状态原因是其所在的RAID组中有一块成员盘报告了Predictive Failure预测性故障。第五步根因定位与修复10分钟问题根源找到了不是服务器的问题而是后端存储阵列的一块物理盘即将失效导致整个LUN被阵列控制器主动隔离以保护数据一致性。阵列控制器的这种行为正是 SCSI 协议中“设备状态机”的体现——当它判断一个LUN不再可靠时就会停止响应任何命令让前端主机“感知”到它的消失从而触发上层应用的故障转移。修复方案很简单更换那块故障的物理盘让RAID组重建。整个过程耗时约2小时。而我们的排查只用了不到30分钟就精准锁定了问题边界避免了在服务器上进行无谓的内核参数调优或驱动升级。这个案例告诉我们SCSI 磁盘的“消失”从来都不是一个孤立事件。它一定是某个更上游的、更根本的故障所触发的连锁反应。你的任务就是沿着dmesg-sg_inq-存储阵列管理界面这条链路一层层向上追溯直到找到那个最初的“蝴蝶翅膀”。4.2 动手实验在虚拟机中模拟SCSI设备的热插拔理论学得再多不如亲手做一次。下面我将指导你在一台 Linux 虚拟机中利用qemu和libvirt创建一个虚拟的 SCSI 磁盘并模拟真实的热插拔过程。这不仅能加深你对 SCSI 生命周期的理解还能让你在不碰真实硬件的情况下练习所有诊断命令。前提条件一台安装了qemu-kvm、libvirt和virt-manager的 Ubuntu 22.04 虚拟机。步骤1创建一个空的虚拟磁盘镜像# 创建一个2GB的qcow2格式镜像 $ qemu-img create -f qcow2 /var/lib/libvirt/images/scsi-test.qcow2 2G步骤2编辑虚拟机XML配置添加SCSI控制器和磁盘# 编辑你的虚拟机配置假设名为centos8 $ virsh edit centos8在devices标签下添加以下内容!-- 添加一个LSI Logic SAS控制器 -- controller typescsi index0 modellsilogic / !-- 将磁盘挂载到该SCSI控制器上 -- disk typefile devicedisk driver nameqemu typeqcow2/ source file/var/lib/libvirt/images/scsi-test.qcow2/ target devsdb busscsi/ address typedrive controller0 bus0 target0 unit0/ /disk保存退出。此时虚拟机重启后就会多出一个/dev/sdb。步骤3在虚拟机内部观察SCSI设备的诞生启动虚拟机执行# 查看SCSI Host $ ls /sys/class/scsi_host/ host0 host1 host2 # 查看host2我们新加的LSI控制器下的设备 $ ls /sys/class/scsi_host/host2/device/ target2:0:0/ # 查看该Target下的LUN $ ls /sys/class/scsi_host/host2/device/target2:0:0/ 2:0:0:0/ # 查看设备状态 $ cat /sys/class/scsi_device/2:0:0:0/device/state running你已经成功“制造”了一个 SCSI 磁盘步骤4模拟热插拔关键实验现在我们来模拟一次“拔盘”# 在宿主机上执行热拔 $ virsh detach-disk centos8 sdb --config --live # 等待几秒回到虚拟机内部 $ dmesg | tail -10 # 你会看到类似这样的日志 # [123456.789012] scsi 2:0:0:0: rejecting I/O to offline device # [123456.789013] sd 2:0:0:0: [sdb] killing request $ lsblk | grep sdb # 输出为空/dev/sdb消失了再执行一次热插# 在宿主机上重新attach $ virsh attach-disk centos8 /var/lib/libvirt/images/scsi-test.qcow2 sdb --driver qemu --subdriver qcow2 --targetbus scsi --config --live # 回到虚拟机等待10秒 $ dmesg | tail -10 # 你会看到新的 sas_device_add 日志 $ lsblk | grep sdb # /dev/sdb 重新出现这个实验完美复现了真实世界中 SCSI 磁盘的整个生命周期。每一次detach/attach都是一次对scsi_scan_target()和scsi_remove_target()函数的调用。你亲眼看到了state文件如何从running变成offline再变回running。这种亲手操控的感觉是任何文档都无法替代的。4.3 生产环境最佳实践SCSI磁盘的健康巡检清单在生产环境中不能等到故障发生才去排查。一套标准化的、自动化的健康巡检清单是保障存储稳定性的基石。下面是我总结的、已在多个大型项目中落地的巡检项你可以直接写成一个check_scsi_health.sh脚本。巡检项1设备在线状态检查#!/bin/bash for dev in /sys/class/scsi_device/*/device; do if [ -e $dev/state ]; then state$(cat $dev/state 2/dev/null) if [ $state ! running ]; then echo ALERT: SCSI device $(basename $(dirname $dev)) is $state fi fi done这个脚本会遍历所有 SCSI 设备检查其 state
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。