• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 博客專欄

    EEPW首頁 > 博客 > nvme磁盤故障注入方法

    nvme磁盤故障注入方法

    發(fā)布人:天翼云開發(fā)者 時間:2024-08-12 來源:工程師 發(fā)布文章

    本文分享自天翼云開發(fā)者社區(qū)《nvme磁盤故障注入方法》,作者:曹****飛 

    在存儲系統(tǒng)中,磁盤的故障是很可能出現(xiàn)的問題。存儲軟件的設計需要對故障進行處理,提高系統(tǒng)的健壯性。然而磁盤的故障是不可控的,當我們想測試軟件故障處理的分支時,不是很方便。用軟件模擬的方法能覆蓋的場景比較少,而且和實際故障的差距會比較大。因此,如果能讓故障下沉到磁盤,盡可能的靠近磁盤,才能構造出盡可能真實的故障場景。本文針對nvme磁盤,在磁盤驅動這一層調研了幾種可以注入磁盤故障的方法。

    1. write uncorrectable

    通過向nvme控制器發(fā)送write uncor命令,標記指定的LBA范圍為invalid,當讀到這個LBA范圍時,ctrl會返回Unrecovered Read Error錯誤。可以用于模擬讀的media error。如果要清除invalid狀態(tài),需要向這個LBA范圍寫入數(shù)據,覆蓋調invalid標記。

    不過,write uncor命令不是所有廠家的盤都支持。如果不支持,會返回invalid op code錯誤。查看是否支持的方法,可以看controller數(shù)據結構中的oncs->write_unc是否為1。

    還有一個缺點是只能注入讀故障。

    2. write protect

    通過設置namespace的屬性,可以讓namespace寫保護,當這個namespace收到寫請求時,會返回write error。

    缺點是有的廠商的盤不支持這個屬性,而且只能注入寫故障。

    3. 驅動層模擬故障

    這是最通用的一種方法,可以構造出各種故障。spdk的代碼中就實現(xiàn)了這一功能。下面詳細介紹下它的接口。

    /**

     * \brief Inject an error for the next request with a given opcode.

     * \param ctrlr NVMe controller.

     * \param qpair I/O queue pair to add the error command,

     *  NULL for Admin queue pair.

     * \param opc Opcode for Admin or I/O commands.

     * \param do_not_submit True if matching requests should not be submitted

     * to the controller, but instead completed manually

     * after timeout_in_us has expired.  False if matching

     * requests should be submitted to the controller and

     * have their completion status modified after the

     * controller completes the request.

     * \param timeout_in_us Wait specified microseconds when do_not_submit is true.

     * \param err_count Number of matching requests to inject errors.

     * \param sct Status code type.

     * \param sc Status code.

     * \return 0 if successfully enabled, ENOMEM if an error command

     * structure cannot be allocated.

     * The function can be called multiple times to inject errors for different

     * commands. If the opcode matches an existing entry, the existing entry

     * will be updated with the values specified.

     */

    int spdk_nvme_qpair_add_cmd_error_injection(struct spdk_nvme_ctrlr *ctrlr,

    struct spdk_nvme_qpair *qpair,

    uint8_t opc,

    bool do_not_submit,

    uint64_t timeout_in_us,

    uint32_t err_count,

    uint8_t sct, uint8_t sc);

    ctrlr: nvme盤的控制器數(shù)據結構,每個盤有一個;

    qpair: 注入故障的qpair,可以是io qpair,也可以是admin qpair。使用哪一種取決于希望在IO路徑上還是在管理路徑上產生故障;

    opc: 操作類型,比如read,write等;

    do_not_submit:如果是true,則這個opc的cmd不會提交到ctrl,而是在 timeout_in_us 到期后手動返回指定的sct,sc。如果是false,則這個opc的cmd會提交到ctrl,等ctrl返回cpl后,將sct和sc改成指定的sct,sc,回調的時候用改過的cpl。命令實際上是執(zhí)行成功的;

    timeout_in_us:do_not_submit=true時有效,等待timeout_in_us后再返回sct,sc。范圍是(0-18446744073709551615)

    err_count: 表示注入故障后,此后的多少個該opc的cmd會按照注入的故障來處理,每返回一個注入的故障,err_count減1。減為0的時候不再注入故障,但cmd也不會從 qpair->err_cmd_head 中摘除;

    sct: 返回的狀態(tài)碼類型;

    sc: 返回的狀態(tài)碼;

    實現(xiàn)的原理是向指定qpair的err_cmd_head鏈表中添加一個錯誤的cmd,當下個該類型的cmd提交到該qpair的時候在 _nvme_qpair_submit_request 中遍歷這個鏈表,處理這個cmd,強制修改cpl中的返回值,然后再調用回調,從而模擬故障。

    使用此接口可以模擬出讀寫錯誤,IO hang住或超時的錯誤等,在開發(fā)測試中比較實用。

    *博客內容為網友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。



    關鍵詞: nvme 磁盤故障

    相關推薦

    技術專區(qū)

    關閉
    主站蜘蛛池模板: 岳池县| 海城市| 河南省| 岳池县| 通渭县| 辽源市| 盘锦市| 毕节市| 武川县| 二连浩特市| 芒康县| 施秉县| 定南县| 全椒县| 密云县| 澄迈县| 徐水县| 遂溪县| 五家渠市| 武汉市| 大安市| 湘乡市| 永顺县| 天峻县| 巴塘县| 南昌县| 张家界市| 醴陵市| 武安市| 泸水县| 东台市| 黄骅市| 新蔡县| 腾冲县| 故城县| 嘉兴市| 眉山市| 临西县| 镇原县| 华阴市| 双峰县|