如何告诉 Linux Kernel > 3.0 完全忽略故障磁盘?

Rma*_*ano 25 block-device linux-kernel

我有一个三星笔记本电脑(Chronos的S7)与总线一个SATA硬盘ata:1,它被检测为/dev/sda,一个8G SSD上ata:2/dev/sdb和上SATA接口的其余各种其他装置。

问题是SSD盘是

  • 焊接到主板上(不可移动)
  • 被破坏(它只会为任何操作提供 I/O 错误)
  • 它没有出现在 bios 中(可能是因为它坏了)

现在这个磁盘:

  • 尝试探测故障磁盘的启动延迟了三到五分钟,这很烦人;
  • 但最烦人的是系统因为/dev/sdb失败而无法挂起。

请注意,我可以忍受启动时的延迟——让我担心的是恢复/挂起的事情。


所以问题是:我可以告诉内核避免在 ata:2 上探测设备吗?

在较旧的内核 (<3.0) 中,当我仍然能够深入挖掘源代码时,有一个样式的命令行参数hdb=ignore可以解决问题。

我已经尝试了下面提出的所有技巧udevlibata:force内核参数,但无济于事。具体来说,以下不起作用:

  1. 添加到以下/etc/udev/rules.d/文件之一(在早期执行中00-ignoredisk.rules或晚期执行99-ignoredisk.rules或在两个地方)

    SUBSYSTEMS=="scsi", DRIVERS=="sd", ATTRS{rev}=="SSD ", ATTRS{model}=="SanDisk iSSD P4 ", ENV{UDISKS_IGNORE}="1" 
    
    Run Code Online (Sandbox Code Playgroud)

    也不

    KERNEL=="sdb", ENV{UDISKS_IGNORE}="1"
    
    Run Code Online (Sandbox Code Playgroud)

    也没有很多中间解决方案——这使得启动后无法访问磁盘,但它在启动时被探测,并在挂起时仍然检查——导致挂起失败。

  2. 编辑系统文件/lib/udev/rules.d/60-persistent-storage.rules(和udisks, udisks2)改变

    KERNEL=="ram*|loop*|fd*|nbd*|gnbd*|dm-|md", GOTO="persistent_storage_end"
    
    Run Code Online (Sandbox Code Playgroud)

    KERNEL=="ram*|loop*|fd*|nbd*|gnbd*|dm-|md|sdb*", GOTO="persistent_storage_end"
    
    Run Code Online (Sandbox Code Playgroud)

    同样,这也有一些效果,从用户空间屏蔽了磁盘,但内核仍然可以看到磁盘。

  3. 使用参数的所有可能组合(好吧,很多)引导libata:force(例如在这里找到)以禁用 DMA、降低速度或任何有关故障磁盘的问题 --- 不起作用。使用了该参数,但磁盘仍被探测并失败。

    完整udevadm info -a -n /dev/sdb粘贴到http://paste.ubuntu.com/6186145/

    smartctl -i /dev/sdb -T permissive 给出:

    root@samsung-romano:/home/romano# smartctl -i /dev/sdb -T permissive
    smartctl 5.43 2012-06-30 r3573 [x86_64-linux-3.8.0-31-generic] (local build)
    Copyright (C) 2002-12 by Bruce Allen, http://smartmontools.sourceforge.net
    
    Vendor:               /1:0:0:0
    Product:              
    User Capacity:        600,332,565,813,390,450 bytes [600 PB]
    Logical block size:   774843950 bytes
    >> Terminate command early due to bad response to IEC mode page
    
    Run Code Online (Sandbox Code Playgroud)

    这显然是错误的。尽管如此:

    root@samsung-romano:/home/romano# fdisk -b 512 -C 970 -H 256 -S 63 /dev/sdb
    fdisk: unable to read /dev/sdb: Input/output error
    
    Run Code Online (Sandbox Code Playgroud)

(SSD 数据来自http://ubuntuforums.org/showthread.php?t=1935699&p=11739579#post11739579)。

rob*_*at2 29

libata根本没有 noprobe 选项;那是一个传统的 IDE 选项......

但是我去为你写了一个内核补丁来实现它。它应该很容易地应用于许多内核(它上面的行是在 2013-05-21/v3.10-rc1* 中添加的,但可以在没有该行的情况下安全地手动应用)。

更新补丁现在是上游(至少在 3.12.7 稳定内核中)。它位于随 Ubuntu 14.04(基于 3.13-stable)分发的标准内核中。

安装补丁后,添加

 libata.force=2.00:disable
Run Code Online (Sandbox Code Playgroud)

内核引导参数将隐藏磁盘对 Linux 内核。仔细检查号码是否正确;搜索设备名称会有所帮助(显然,您必须添加引导参数之前检查内核消息):

(0)samsung-romano:~% dmesg | grep iSSD
[    1.493279] ata2.00: ATA-8: SanDisk iSSD P4 8GB, SSD 9.14, max UDMA/133
[    1.494236] scsi 1:0:0:0: Direct-Access     ATA      SanDisk iSSD P4  SSD  PQ: 0 ANSI: 5
Run Code Online (Sandbox Code Playgroud)

重要的数字是ata2.00在上面的第一行。

  • @robbat2:谢谢你,谢谢你 - 你把我 20 分钟的启动(等待一个粗略的硬连线存储最终超时)变成了 30 秒的启动。谢谢你! (2认同)

Emm*_*uel 18

硬件问题有物理硬件解决方案。您是否考虑过拆焊或切断驱动器的电源?

编辑:好的,如果那不是人们之前使用它来热插拔硬盘驱动器的选项。你可以用它来禁用你的驱动器。

echo 1 > /sys/block/sdb/device/delete
Run Code Online (Sandbox Code Playgroud)

请注意,任何其他进程都可以强制扫描 SATA 总线,然后使其返回。尝试在使笔记本电脑休眠之前执行此操作。

由 OP 编辑​​:它有效。我添加了以下文件:

-rwxr-xr-x 1 root root 204 Dec  6 16:03 99_delete_sdb
Run Code Online (Sandbox Code Playgroud)

内容:

#!/bin/sh

# Tell grub that resume was successful

case "$1" in
    suspend|hibernate)
        if [ -d /sys/block/sdb ]; then
            echo Deleting device sdb 
            echo 1 > /sys/block/sdb/device/delete       
        fi
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

...现在系统正确挂起(和恢复)。