前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >D状态IO进程造成的麻烦

D状态IO进程造成的麻烦

作者头像
用户4700054
发布2022-08-17 12:47:59
1.3K0
发布2022-08-17 12:47:59
举报
文章被收录于专栏:存储内核技术交流

背景

  • 当后端是本地磁盘或者底层是一个分布式的块存储,底层磁盘或者分布式块存储出现问题,比如mount进程处于D状态,这时候内核会什么行为?重复挂载会出现什么问题?
模式出现D状态的mount
  • Interruptible Sleep :可中断睡眠,在 ps 命令中显示 S。处在这种睡眠状态的进程是可以通过给它发送信号来唤醒的。
  • Uninterruptible Sleep:不可中断睡眠,在 ps 命令中显示 D。处在这种睡眠状态的进程无法立即处理任何发送给它的信号,这也是无法用 kill 杀掉它的原因。
代码语言:javascript
复制
$ dd if=/dev/zero of=/tmp/disk1 count=4906 bs=1M

$ losetup --show -f /tmp/disk1 
/dev/loop0

$ pvcreate /dev/loop0
  Physical volume "/dev/loop0" successfully created.

$ vgcreate vgtest1 /dev/loop0
  Volume group "vgtest1" successfully created


$ lvcreate -n lvtest1 -L 1G vgtest1
  Logical volume "lvtest1" created.


$ mkfs.ext4 -m0 /dev/vgtest1/lvtest1


$ mount /dev/vgtest1/lvtest1 /mnt/lvtest1


// 写 IO 的同时暂停 lv
$ dmsetup suspend /dev/vgtest1/lvtest1 && dd if=/dev/urandom of=/mnt/lvtest1/file.img bs=1M count=1024


// 恢复 lv 的 IO。
$ dmsetup resume /dev/vgtest1/lvtest1



$ mount /dev/vgtest1/lvtest1 /mnt/lvtest1
$ dmsetup suspend /dev/vgtest1/lvtest1 && dd if=/dev/urandom of=/mnt/lvtest1/file.img bs=1M count=1024



$ echo w > /proc/sysrq-trigger
$ ps -eo ppid,pid,user,stat,pcpu,comm,wchan:32 |grep D
   PPID     PID USER     STAT %CPU COMMAND         WCHAN
   2099    2178 root     D+    0.0 dd              -
   2210    2231 root     D+    0.0 ls              -
   2264    2304 root     D+    0.0 mount           -
   2413    2435 root     D+    0.0 mount           -           -
原因分析
  • mount同一块磁盘挂载多个目录,只会有一个成功。内核会判断当前的挂载的目录的父目录是否是同一个目录,如果是则提示已经挂载;如果不是则会无损转嫁到新的挂载点。
  • D状态的dd导致某些设备处于执行IO的不可中断的模式。mount进程读取超级块先关资源时候hang主了.在了解这个问题之前需要了解下外设磁盘和系统之间的通信方式。目前系统判断设备上的数据是否就绪采用了轮询中断两种方式。轮询方式是不断的重复询问设备上的数据是否可用,如果可用,CPU就读取数据;中断方式中系统为每个CPU提供了中断线,可由各个系统设备共享。每个中断通过一个唯一的标识,内核对使用的每个中断提供一个中断服务。中断将暂停正常系统工作,在外设的数据已经就绪,需要由内核或者应用处理,外设会引发一个中断,系统就不需要频繁检查是否有新的数据可用,外设有新数据的情况会自动通知系统。既然IO通过方式,D状态的mount 进程设备处于做IO操作,无法被打断的状态,新的进程再次mount务必要进行一些IO操作,也必然产生中断,但是这个中断无法被响应,就一直处于D+状态。
代码语言:javascript
复制
// mount进程的stack
$ cat /proc/2304/stack
[<0>] generic_file_buffered_read+0x35b/0xbc0
[<0>] new_sync_read+0x10f/0x150
[<0>] vfs_read+0x91/0x140
[<0>] ksys_read+0x4f/0xb0
[<0>] do_syscall_64+0x5b/0x1a0
[<0>] entry_SYSCALL_64_after_hwframe+0x65/0xca


// 内核的日志,这时候可以看到寄存器的某些值是无法被访问,同时内核hang在了io调度这块
kernel: task:mount           state:D stack:    0 pid: 2304 ppid:  2264 flags:0x00000080
kernel: Call Trace:
kernel: __schedule+0x2c4/0x700
kernel: schedule+0x37/0xa0
kernel: io_schedule+0x12/0x40
kernel: generic_file_buffered_read+0x35b/0xbc0
kernel: ? file_fdatawait_range+0x20/0x20
kernel: new_sync_read+0x10f/0x150
kernel: vfs_read+0x91/0x140
kernel: ksys_read+0x4f/0xb0
kernel: do_syscall_64+0x5b/0x1a0
kernel: entry_SYSCALL_64_after_hwframe+0x65/0xca
kernel: RIP: 0033:0x7f30b6ffd5a5
kernel: Code: Unable to access opcode bytes at RIP 0x7f30b6ffd57b.
kernel: RSP: 002b:00007ffee1830e68 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
kernel: RAX: ffffffffffffffda RBX: 000056069ab0d640 RCX: 00007f30b6ffd5a5
kernel: RDX: 0000000000000040 RSI: 000056069ab0d668 RDI: 0000000000000003
kernel: RBP: 000056069ab0d4e0 R08: 000056069ab0d640 R09: 000056069ab0d630
kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 000000003fff0000
kernel: R13: 0000000000000040 R14: 000056069ab0d530 R15: 000056069ab0d658
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
    • 模式出现D状态的mount
      • 原因分析
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档