Linux

Linux下能否禁用硬碟超時(嘗試任務中止)

  • August 26, 2016

不幸的是,當硬碟驅動器(通常是虛擬驅動器)速度很慢時,Linux 會在超時後中止對該驅動器的請求,這可能會導致數據損壞。

上次這種情況發生在我身上時,我在一個儲存上執行了 2 個 vm(Linux 和 FreeBSD),它存在連接問題並且被凍結了一個多小時。儲存本身很好,沒有錯誤,修復連接後,虛擬機(顯然也被凍結了)似乎又可以工作了。

然而,Linux 虛擬機決定中止請求,導致系統無法使用(大多數目錄上的 ls 卡住了,所以掛載沒有選項,許多其他事情不再起作用);重新啟動是必要的。這些是錯誤(dmesg):

...
[86707.916728] Write(10): 2a 00 02 4c 9e 38 00 03 c0 00
[86707.916732] mptscsih: ioc0: task abort: SUCCESS (rv=2002) (sc=ffff880036865500)
[86707.916734] mptscsih: ioc0: attempting task abort! (sc=ffff880036866100)
[86707.916735] sd 2:0:0:0: [sda] CDB: 
[86707.916736] Write(10): 2a 00 02 4c a1 f8 00 03 c0 00
[86707.916739] mptscsih: ioc0: task abort: SUCCESS (rv=2002) (sc=ffff880036866100)
[86707.916741] mptscsih: ioc0: attempting task abort! (sc=ffff880036865c80)
[86707.916742] sd 2:0:0:0: [sda] CDB: 
[86707.916743] Write(10): 2a 00 02 4c a5 b8 00 03 c0 00
[86707.916746] mptscsih: ioc0: task abort: SUCCESS (rv=2002) (sc=ffff880036865c80)
[86707.916748] mptscsih: ioc0: attempting task abort! (sc=ffff880036864300)
[86707.916749] sd 2:0:0:0: [sda] CDB: 
[86707.916750] Write(10): 2a 00 02 4c a9 78 00 02 b0 00
[86707.916753] mptscsih: ioc0: task abort: SUCCESS (rv=2002) (sc=ffff880036864300)

有趣的是,FreeBSD vm 沒有記錄錯誤並且工作正常。顯然,只有 FreeBSD 能按預期工作,沒有中止任何事情(儘管我認為我在 FreeBSD 系統上看到過類似的核心消息)。

我不知道為什麼核心在超時後會殺死掛起的寫請求。在某些情況下這可能是有道理的,但在我的情況下肯定不是——這實際上是一個不必要的風險(如果沒有超時,Linux vm 在連接恢復後會繼續正常執行,一切都會再次執行)。

如何禁用凍結硬碟驅動器的 Linux 核心超時 (vm)?


編輯:

Linux vm 只有 1 個硬碟驅動器 (/dev/sda),它看起來應該像一個普通的(SCSI 類型的)物理驅動器。

lspci 列出此控制器:“SCSI 儲存控制器

$$ 0100 $$: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI$$ 1000:0030 $$(修訂版 01)”。 這是另一個範例(不同的虛擬機,相同的主機,也是 Linux)(在這種情況下,儲存並沒有消失,但主機負載很重):

[1179039.664031] ata2: lost interrupt (Status 0x18)
[1179039.727188] ata2: drained 8 bytes to clear DRQ
[1179039.727272] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[1179039.740720] sr 1:0:0:0: CDB:
[1179039.740759] Get event status notification: 4a 01 00 00 10 00 00 00 08 00
[1179039.740768] ata2.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 0 pio 16392 in
        res 40/00:02:00:08:00/00:00:00:00:00/a0 Emask 0x4 (timeout)
[1179039.740770] ata2.00: status: { DRDY }
[1179039.748067] ata2: soft resetting link
[1179039.937757] ata2.00: configured for UDMA/33
[1179039.943435] ata2: EH complete

編輯:

這就是 Debian/kBSD(FreeBSD 核心)系統(相同的主機,相同的情況,不同的虛擬機)上的超時錯誤的樣子:

mpt0: request 0xffffff80007305d0:62955 timed out for ccb 0xfffffe000a3bb800 (req->ccb 0xfffffe000a3bb800)
mpt0: request 0xffffff800072fa90:62956 timed out for ccb 0xfffffe000a3d1000 (req->ccb 0xfffffe000a3d1000)
mpt0: request 0xffffff8000726070:62962 timed out for ccb 0xfffffe000a428000 (req->ccb 0xfffffe000a428000)
mpt0: attempting to abort req 0xffffff80007305d0:62955 function 0
mpt0: completing timedout/aborted req 0xffffff8000726070:62962
mpt0: completing timedout/aborted req 0xffffff80007305d0:62955
mpt0: completing timedout/aborted req 0xffffff800072fa90:62956
mpt0: abort of req 0xffffff80007305d0:0 completed
mpt0: request 0xffffff8000726190:64136 timed out for ccb 0xfffffe000a3d1800 (req->ccb 0xfffffe000a3d1800)
mpt0: attempting to abort req 0xffffff8000726190:64136 function 0
mpt0: completing timedout/aborted req 0xffffff8000726190:64136
mpt0: abort of req 0xffffff8000726190:0 completed
mpt0: request 0xffffff8000721990:50970 timed out for ccb 0xfffffe00024bf800 (req->ccb 0xfffffe00024bf800)
mpt0: attempting to abort req 0xffffff8000721990:50970 function 0
mpt0: completing timedout/aborted req 0xffffff8000721990:50970
mpt0: abort of req 0xffffff8000721990:0 completed
mpt0: request 0xffffff80007279c0:61393 timed out for ccb 0xfffffe000a3cf000 (req->ccb 0xfffffe000a3cf000)
mpt0: request 0xffffff8000732550:61395 timed out for ccb 0xfffffe000a428000 (req->ccb 0xfffffe000a428000)
mpt0: attempting to abort req 0xffffff80007279c0:61393 function 0
mpt0: completing timedout/aborted req 0xffffff80007279c0:61393
mpt0: completing timedout/aborted req 0xffffff8000732550:61395
mpt0: abort of req 0xffffff80007279c0:0 completed

我發現了一個超時,在大多數係統上似乎預設為 30 秒。我不完全確定這是相關的超時,但我已經在一些虛擬機上增加了它,使系統處於顯著負載下,到目前為止我在虛擬機中沒有任何硬碟超時。

此外,一些評論對我在 vm 中配置的硬碟表示困惑,因此我已將該資訊添加到問題中。而且我有幾個 Linux 虛擬機同時執行,因此錯誤不會只出現在一個虛擬機中。

超時設置(例如 in /etc/rc.local):

Linux:

TIMEOUT=86400
for f in /sys/block/sd?/device/timeout; do
   echo $TIMEOUT >"$f"
done

如果此模式 ( sd?) 與您的硬體不匹配,請搜尋超時並手動檢查:

find /sys/ -name timeout

Debian/kBSD (GNU/kFreeBSD 9.0-2-amd64):

sysctl kern.cam.da.default_timeout=86400

(我已經顯著增加了超時而不是禁用它;如果這是罪魁禍首,可能會設置一個更合適的值。)

同樣,我還沒有確認這正是我的虛擬機正在執行的超時(或者這是唯一的超時),但鑑於我已將系統置於高負載(用於觸發 hdd 的那種負載)超時)並且還沒有發生硬碟超時(儘管網路超時,就像以前一樣),看起來這至少可能是解決方案的一部分。

引用自:https://unix.stackexchange.com/questions/174400