浅析Linux SCSI子系统:错误恢复

文章目录

    • 概述
    • SCSI错误恢复处理
      • 添加错误恢复命令
      • 错误恢复线程
        • scsi_eh_ready_devs
    • IO超时处理
    • 相关参考

概述

IO路径是一个漫长的过程,从SCSI命令请求下发到请求完成返回,中间的任何一个环节出现问题都会导致IO请求的失败。从SCSI子系统到低层驱动,再到实际的物理设备,每一层都应该在出现问题的时候,将错误的原因返回给上一层。SCSI子系统提供了错误恢复机制,对低层上报的错误IO执行可能的恢复策略,包括IO重试、复位设备,严重的还会对整个SCSI主机适配器进行复位等。

SCSI错误恢复处理

对于出错的IO请求,SCSI子系统会将其挂到SCSI主机适配器的错误处理链表中,然后唤醒错误恢复线程,对链表中的异常IO进行错误处理。

添加错误恢复命令

SCSI子系统调用scsi_eh_scmd_add接口将SCSI命令加入到错误处理中,scsi_eh_scmd_add处理流程如下:

  1. 将错误的scsi命令通过eh_entry字段链入到SCSI host维护的eh_cmd_q链表中;
  2. 设置SCSI host中shost_state中SHOST_RECOVERY位;
  3. 递增SCSI host的host_failed计数;
  4. 当SCSI host中host_busy统计等于host_failed相等时,唤醒SCSI错误处理线程。

在这里插入图片描述

错误恢复线程

SCSI使用单独的内核线程来完成错误恢复的处理,对于每个SCSI Host都会维护这样的一个线程,线程命名的方式是scsi_eh_#,其中#为系统为SCSI Host分配的唯一编号。错误恢复线程的入口函数是scsi_error_handler。
在这里插入图片描述

scsi_error_handler会优先调用SCSI Transport层定义错误恢复回调,若Transport层未定义,则会使用SCSI中层默认的错误恢复策略,入口函数为scsi_unjam_host。scsi_unjam_host维护两条临时队列:work_q和done_q,其中work_q存放错误的IO请求,done_q存放恢复的IO请求。scsi_unjam_host通过一系列修复动作,处理work_q中的错误IO请求,并在处理完成后转移到done_q,最后将done_q中的请求按照诊断结果统一进行处理。

scsi_eh_ready_devs

scsi_eh_ready_devs会执行一系列的修复动作,以试图修复错误的IO,在出现严重的IO错误时,甚至会将整个SCSI主机适配器进行复位;如果到最后还有错误的IO无法恢复,那么SCSI会将关联的设备置为离线状态,离线的设备将不允许再下发IO请求。
在这里插入图片描述

IO超时处理

通常来说,IO的完成状态是明确的,要么是成功返回,要么是出现IO错误返回,但还有一种异常场景是IO请求下发后,一直未返回,这种情况下,由于IO的状态是未知的,需要进行特殊处理。

从块层下发的IO请求,都会配置一个超时定时器,对于SCSI默认设置是30s。当IO请求下发后,超过这个时间没有返回,就会触发超时处理。SCSI注册的超时回调接口是scsi_times_out。当IO超时产生时,scsi_times_out函数将:

  1. 调用scsi host注册的eh_timed_out回调(如果有),由驱动决定超时IO的处理策略。eh_timed_out回调的返回结果有两种:
    • BLK_EH_RESET_TIMER:重新设置超时定时器;
    • BLK_EH_DONE:表示驱动未能处理这个超时IO,交由SCSI继续处理。
  2. 调用scsi_abort_command取消SCSI命令请求;
  3. 调用scsi_eh_scmd_add将超时的IO请求加入到错误处理队列中,等待错误恢复线程处理。

在这里插入图片描述

相关参考

  • 《存储技术原理分析:基于Linux 2.6内核源代码分析》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/117032.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【快手小玩法-弹幕游戏】开发者功能测试报告提交模板

背景 快手有明确的要求,准入和准出更加严格,要求有明确的测试报告。格式如下: *本文参考字节wiki:CP侧测试报告模板(复制填写轻雀文档) 其他文章推荐:【抖音小玩法-弹幕游戏】开发者功能测试报告提交模板 一、前言…

Java后端开发面试题——集合篇

ArrayList底层的实现原理是什么 底层数据结构 ArrayList底层是用动态的数组实现的 初始容量 ArrayList初始容量为0,当第一次添加数据的时候才会初始化容量为10 扩容逻辑 ArrayList在进行扩容的时候是原来容量的1.5倍,每次扩容都需要拷贝数组 添加逻…

MMSegmentation训练自己的语义分割数据集

全流程,训练语义分割数据集 数据标注json转mask 运行源码MMSegmentation模型选择运行部分 数据标注 # 安装 pip install labelme # 启动labelme labelme然后 ctrl N 开启多边形标注即可,命名类为person 之后会保存到同目录下json文件: js…

WordPress(6)网站侧边栏倒计时进度小工具

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 效果图在这里插入图片描述一、添加位置二、主题style.css文件中添加美化1.引入库2.添加自定义的HTML模块效果图 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加位置 在主题中 child.js…

【1++的数据结构】之AVL树

👍作者主页:进击的1 🤩 专栏链接:【1的数据结构】 文章目录 一,什么是AVL树二,AVL树的插入三,AVL树的旋转3.1 向左旋转3.2 向右旋转3.3 左右双旋3.4 右左双旋 四,验证AVL树是否平衡 …

Data truncation: Out of range value for column ‘id‘ at row 1

错误信息:Data truncation: Out of range value for column id at row 1 数据截断:第1行“id”列的值超出范围 很多人会回复:数据库 类型由int改为 bigInt 我看了表结构 可以放的下的。 是 bigint(20) 没有问题啊。 默认的 bigint 类型…

C语言面试题值反转字符串

知识捡漏本 1.C语言优先级 :左高于高于 右 2.定义宏函数product,调用product后,里面的i和i都是加两次1,i就是两个加2后的i相乘,i是开始的i和1后的i相乘。 3.用i (j4,k 8,m 16);这种定义方法,最终i和最后一…

dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构

文章目录 1、整体项目结构1.1、 目录launch1.2、文件CMakeLists.txt1.3、文件package.xml1.4、目录include1.4、目录srv在ROS框架下创建一个无人机的节点dji_sdk,实现必需的订阅(控制指令)、发布(无人机里程计)、服务(无人机起飞降落、控制权得很)功能,就能实现一个类似…

全球免费编程教育网站:Code.org

全球免费编程教育网站:Code.org 官网地址注册使用 你还在为小朋友的编程教育而发愁吗? 你还在为小朋友放假无聊而头疼吗? 他来了他来了,全球免费编程教育网站来了。 2013年成立的Code.org是一个非营利组织。 它致力于为年轻女子、…

【RISC-V】RISC-V寄存器

一、通用寄存器 32位RISC-V体系结构提供32个32位的整型通用寄存器寄存器别名全称说明X0zero零寄存器可做源寄存器(rs)或目标寄存器(rd)X1ra链接寄存器保存函数返回地址X2sp栈指针寄存器指向栈的地址X3gp全局寄存器用于链接器松弛优化X4tp线程寄存器常用于在OS中保存指向进程控…

Qt/C++编写视频监控系统81-Onvif报警抓图和录像并回放

一、前言 视频监控系统中的图文警情模块,是通过Onvif协议的事件订阅拿到的,通过事件订阅后,设备的各种报警事件比如入侵报警/遮挡报警/越界报警/开关量报警等,触发后都会主动往订阅者发送,而且一般都是会发送两次&…

Node.js crypto模块 加密算法

背景 微信小程序调用飞蛾热敏纸打印机,需要进行参数sig签名校验,使用的是sha1进行加密 // 通过crypto.createHash()函数,创建一个hash实例,但是需要调用md5,sha1,sha256,sha512算法来实现实例的…

企业架构LNMP学习笔记7

PHP介绍: HTML:超文本标记语言 http: 超文本传输协议 端口80 浏览器将html代码解析成web页面。 PHP:超文本预处理器。后端语言开发,页面上需要动态改变修改的,需要连接数据库查询数据,转为html。 主要…

流媒体弱网优化之路(BBR应用)——GCC与BBR的算法思想分析

流媒体弱网优化之路(WebRTC)——GCC与BBR的算法思想分析 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标:可以让大家熟悉各类Qos能力、带宽估计能力,提供每个环节关键参数调节接口并实现一个json全配置&…

WebSocket(一)

一.什么是WebSocket 【1】WebSocket是一种协议,设计用于提供低延迟,全双工和长期运行的连接。 全双工:通信的两个参与方可以同时发送和接收数据,不需要等待对方的响应或传输完成。 【2】比较 传统通信(http协议&am…

Docker 的快速使用

ubuntu安装 centos安装 安装完毕之后执行一下这条命令,可以避免每次使用docker命令都需要sudo权限 sudo usermod -aG docker $USER阿里云docker镜像加速 DockerHub 遇到不懂或者不会使用的命令可以使用docker --help查看文档 docker --help 如: dock…

JavaWeb 文件上传和下载

目录 一、文件上传 1.文件上传和下载的使用说明 : 2.文件上传基本原理 : 3.文件上传经典案例 : 3.1 页面实现: 3.2 servlet实现 : 3.3 工具类实现 : 3.4 运行测试 : 3.5 注意事项 : 二、文件下载 1.文件下载基本原理 : 2.文件下载经典案例 : 2.1 准备工作 2.2 页面…

关于C语言参数传递的

一、C语言参数传递是整体带入 #include <stdio.h> #define DF(a,b) (a2*b) int main() { int s5; int k DF((s1),(s-3)); printf("%d",k); }输出结果 原因&#xff1a; #define DF(a,b) (a2*b) int k DF((s1),(s-3)); //等效 int k DF((s1)2 * (s-3)); …

useEffect 不可忽视的 cleanup 函数

在 react 开发中&#xff0c; useEffect 是我们经常会使用到的钩子&#xff0c;一个基础的例子如下&#xff1a; useEffect(() > {// some code here// cleanup 函数return () > {doSomething()} }, [dependencies])上述代码中&#xff0c; cleanup 函数的执行时机有如下…

代码随想录笔记--栈与队列篇

目录 1--用栈实现队列 2--用队列实现栈 3--有效的括号 4--删除字符串中的所有相邻重复项 5--逆波兰表达式求值 6--滑动窗口的最大值 7--前k个高频元素 1--用栈实现队列 利用两个栈&#xff0c;一个是输入栈&#xff0c;另一个是输出栈&#xff1b; #include <iostrea…