我让AI从hdparm把-C的功能抽出来单独做个程序,然后拿到一台机器上去测
结果AI抄代码愣是把两个指令参数抄错了(gemini 2.5 flash),源代码里根本没有这两个指令代码,结果就是跑出来的结果和hdparm不一致,然后我让AI改了半天终于发现是指令抄错了,把bug修复好了
然后我发现被用来测试的这块硬盘行为和同批次的其他硬盘行为出现了差异,这块硬盘一旦没有数据读写马上就会进入idle状态,而同批次的其他硬盘都是active/idle状态,要过很久才会进入standby状态
重启也无效,重启完了一看它就是idle状态
也不知道是不是错误指令触发了什么bug导致硬盘内固件设置被改了
以下是问题修复后,我让AI比较两个版本的差异造成的效果:
---
当使用eb70dab98d0版本在机器上运行hdstat /dev/sda时,程序会对硬盘发出以下指令并产生以下效果:
发出的指令:
通过SG_IO接口发送ATA命令:
程序会首先尝试通过SCSI通用接口(SG_IO)发送 ATA_OP_CHECKPOWERMODE1 (0xE5) 命令。
SCSI命令描述符块(CDB)中的 cdb[0] 为 0x85 (SG_ATA_16)。
cdb[1] 为 0x0E。根据hdparm源代码,这个值不对应任何已知的 SG_ATA_PROTO_XXX 组合(例如 SG_ATA_PROTO_PIO_IN 是 0x08,SG_ATA_PROTO_NON_DATA 是 0x06)。这可能导致SCSI层无法正确解释ATA协议类型。
cdb[2] 为 0x0E。这表示 TLEN: NSECT | TLEN: SECTORS 和 TDIR: FROM_DEV。这意味着SCSI层会期望从设备读取数据,并且传输长度以扇区和扇区计数寄存器为单位。
ATA任务文件中的 tf.dev 字段会被设置为 0xA0。
ATA命令 0xE5 (ATA_OP_CHECKPOWERMODE1) 会被放置在 cdb[14]。
如果第一个命令成功,它会继续尝试发送 ATA_OP_CHECKPOWERMODE2 (0x98) 命令,其CDB和ATA任务文件设置与 ATA_OP_CHECKPOWERMODE1 类似。
如果SG_IO接口失败,则回退到传统的IDE IOCTL:
程序会尝试通过 HDIO_DRIVE_CMD IOCTL 发送 ATA_OP_CHECKPOWERMODE1 (0xE5) 命令。
args[0] 为 0xE5 (ATA_OP_CHECKPOWERMODE1)。
args[1] (nsect) 和 args[2] (feat) 在发送时为0。
如果第一个命令失败,它会尝试发送 ATA_OP_CHECKPOWERMODE2 (0x98) 命令。
效果:
SG_IO命令的执行效果:
由于 cdb[1] 的值 0x0E 在 hdparm 的SG_IO协议定义中没有直接对应的含义,这很可能导致SCSI层无法正确解析ATA协议类型。因此,SG_IO命令可能执行失败,或者被SCSI层错误地解释,从而无法正确地将 ATA_OP_CHECKPOWERMODE1 或 ATA_OP_CHECKPOWERMODE2 命令传递给硬盘。
即使命令被传递,cdb[2] 中 TLEN: NSECT | TLEN: SECTORS 和 TDIR: FROM_DEV 的设置意味着SCSI层会期望从设备读取数据。然而,CHECKPOWERMODE 命令通常不涉及数据传输,而是通过寄存器返回状态。这种不匹配可能导致SCSI层在等待数据时超时,或者返回错误,从而无法获得预期的效果。
如果命令能够到达硬盘并被正确执行,硬盘会尝试执行 ATA_OP_CHECKPOWERMODE1 或 ATA_OP_CHECKPOWERMODE2 命令,并通常通过 nsect 寄存器返回其电源模式状态(例如,0x00表示待机,0x80表示空闲,0xFF表示活动/空闲)。
HDIO_DRIVE_CMD命令的执行效果:
如果SG_IO失败,程序会回退到传统的 HDIO_DRIVE_CMD IOCTL。这条路径会直接向硬盘发送 CHECKPOWERMODE 命令。
硬盘会执行这些命令并返回其电源模式状态。然而,eb70dab98d0版本在 HDIO_DRIVE_CMD 的处理中,从 args[2](对应 feat 寄存器)获取状态,而不是 args[1](对应 nsect 寄存器),这可能导致程序无法正确获取到硬盘返回的电源模式信息。
总结:
eb70dab98d0版本在执行 hdstat /dev/sda 时,虽然意图是查询硬盘电源模式,但由于其在SG_IO命令构建(cdb[1] 和 cdb[2] 的错误值和注释)和返回状态解析(HDIO_DRIVE_CMD 中读取错误的寄存器)上的缺陷,可能导致无法成功地向硬盘发出有效的查询指令,或者即使发出,也无法正确地获取和解释硬盘返回的电源模式信息。因此,程序对硬盘发出的指令可能无法达到预期的查询电源模式的效果。
--
FROM 182.108.9.*