討論下Linux下SCSI棧的IO錯誤處理策略

2022-09-15 01:21:09 字數 3061 閱讀 6066

(一)盡快報錯  or  盡力重試?

先討論乙個問題:如果上級交給的任務暫時無法完成,那麼我們應該:

(策略1)應該盡快向上報錯(abort),等待上級做出下一步的指令。

(策略2)暫不報告失敗,而是帶著未完成的任務,去修復和重試。

(二)linux的scsi對錯誤的處理策略

目前linux的scsi棧,預設的策略是暫時不要向上報錯,而是修復和重試。希望能對上級遮蔽底層錯誤,返回乙個重試後的成功的結果。

如果scsi裝置驅動完整的註冊了各個修復函式(scsi_en_xx_reset ),

那麼底層回錯的結果就是, 從下向上,逐級修復, 最後把堆積的io再提交一遍。

如果scsi裝置驅動沒有註冊scsi_en_xx_reset函式,那麼就沒有相關修復處理。

static void scsi_unjam_host(struct scsi_host *shost)

void scsi_eh_ready_devs(struct scsi_host *shost,

struct list_head *work_q,

struct list_head *done_q)

這段**看的我心驚膽戰。

這個反覆重試的策略,對單機系統是合理的,但是對分布式系統不合理。

本來分布式系統可以選擇這個盤,也可以選擇那個盤,但肯定不會選擇故障的盤。早點讓上級知道,能更快的把後續讀寫任務切到其他盤。然後故障盤再執行硬體修復(比如smart查詢,壞道掃瞄,硬碟上下電)就從容了。再說,如果遇到硬體故障,簡單的重試大概率還是失敗。

(三)學習結論:

(策略1)如果是集中式的單控系統,讀寫任務遷移困難,那麼遇到困難先別急著abort,還是盡量重試吧。

(策略2)如果是分布式系統,讀寫任務可以遷移,那麼應該盡快abort,因為分布式系統的可靠性從來不是構築在單裝置可靠性之上,而是用冗餘來彌補單裝置可靠性的不足。如果底層早點報錯,那麼上層就能早點切換。

scsi_queue_rq

=> scsi_dispatch_cmd

==> scsi_host->hostt->queuecommand

==> scsi_cmnd->scsi_done

scsi_execute_req

=> scsi_execute

==> __scsi_execute

===> blk_execute_rq

handle_level_irq

_base_interrupt

mpt_callbacks

_scsih_io_done

scsi_cmnd->scsi_done

scsi_mq_done

blk_mq_complete_request

blk_mq_complete_request_remote

blk_mq_trigger_softirq

raise_softirq_irqoff

// 放到軟中斷中去處理:block_softirq

do_softirq

do_softirq_own_stack

_do_softirq

softirq_action->action

// subsys_initcall(blk_softirq_init)

// block_softirq    blk_done_softirq

blk_done_softirq

request_queue->softirq_done_fn

scsi_softirq_done

scsi_decide_disposition

//  scsi操作完成

(a)scsi_finish_command

scsi_io_completion

scsi_end_request

blk_update_request

req_bio_endio

bio_endio

bio->bi_end_io

end_bio_bh_io_sync

blk_finish_request

request->end_io

// blk_end_sync_rq

scsi_run_queue

(b) scsi_queue_insert

_scsi_queue_insert

blk_requeue_request

elv_requeue_request

kblockd_schedule_work

(c) scsi_eh_scmd_add

我再強調下結論,分布式系統要盡快返回結果。

先abort,然後再修復底層故障。

不要一邊hung住未完成的io,一邊來修復底層故障!

scsi_error_handler //while迴圈任務   

(a)eh_strategy_handler //自定義處理策略

# ata_scsi_error

(b)scsi_unjam_host  //scsi預設處理策略

scsi_eh_ready_devs

scsi_eh_bus_device_reset

scsi_eh_target_reset

scsi_eh_bus_reset

scsi_eh_host_reset

scsi_eh_flush_done_q

blk_mq_check_expired

blk_mq_rq_timed_out

request->q->mq_ops->timeout

scsi_timeout

scsi_times_out

scsi_eh_scmd_add

scsi_eh_wakeup

scsi_host->ehandler

討論下IDS的繞過

自從知道dedecms自帶了80sec的內建mysqlids後,一直以來也沒有想到繞過的辦法。或者是自己mysql的根底太差了吧。於是分析dedecms原始碼時,只找模板執行,本地包含,上傳等,完全沒有想到注入存在的可能性了。可以看看某牛的很久以前的分析 其中 80sec的內建mysqlids可能的...

linux下的棧溢位實驗

關於作業系統的aslr位址隨機化 首先我們在實驗之前需要了解以下aslr機制。即linux平台下的位址隨機化機制。它將程序中的某些記憶體空間位址進行隨機化來增大入侵者 目的位址的難度。從而降低被成功入侵的風險。當前linux windows等主流作業系統都已經採用該技術。linux下的aslr分為0...

linux下列印呼叫棧

include include include include stacktrace.h 列印呼叫棧的最大深度 define dump stack depth max 16 列印呼叫棧函式 void dump trace char stack strings null int stack depth...