V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
hexler
V2EX  ›  Linux

如何清理掉系统上 D 住的进程?

  •  
  •   hexler · 219 天前 · 1951 次点击
    这是一个创建于 219 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有没有懂内核的大佬想过这个问题,我知道 D 住的是已经处于不可响应中断的状态,也知道把一个预期在等待的进程强行干掉是不好的动作。 但是我还是不能理解,linux 上我可以删掉根目录,但是却对一个 D 住的进程无可奈何,这点我很困扰。 不知道有没有专家想过这个问题,或者提供一些思路供研究,谢谢!

    25 条回复    2024-04-08 23:54:18 +08:00
    PTLin
        1
    PTLin  
       219 天前
    给你举几个 uninterruptible 状态进程的例子。
    等待文件读。
    拥有内核自旋锁。
    就拿内核自旋锁举例,假如这个进程在锁的临界区被 kill 的话可能导致整个系统 hung 住。
    idontnowhat2say
        2
    idontnowhat2say  
       219 天前 via iPhone
    改变进程信息结构在内存中的状态?从 D 改成其他的状态。我记得我同事说有命令可以,但我忘了
    yyzh
        3
    yyzh  
       219 天前 via Android
    hexler
        4
    hexler  
    OP
       219 天前
    @idontnowhat2say 这种方式我已经试过了,加载一个模块用来修改 task 的 state 值,如果 D 住的原因是进程进入了不可响应中断的状态的话是不可行的。
    hexler
        5
    hexler  
    OP
       219 天前
    @PTLin 我其实在想,能不能针对不同的情况来处理 D 住的进程,但是知识面太浅了,这才来 v2 找大佬要点灵感
    PTLin
        6
    PTLin  
       219 天前
    那我建议你还是用 perf 或者 bpftrace 找一找变成 D 的原因和调用栈。
    xwwsxp
        7
    xwwsxp  
       219 天前
    不是很懂,什么是 D 进程;但是,我知道的之所以能在 Linux 上将根也删除,是因为你删除的时候,Linux 是跑在内存中的,Linux 认为你可以删除 / 下的文件系统;但是,当重启之后,Linux 就会启动不了,因为需要从硬盘上加载内核(systemd 或 init),都没有对应的文件了,当然启动不了
    xwwsxp
        8
    xwwsxp  
       219 天前
    其实,也可能压根重启不了,因为 Linux 的命令分为内部命令( shell 中的)和外部命令(硬盘上的,如:/usr/loca/bin ),所谓的内部命令就是 Linux 启动的时候,shell 会直接加载到内存中,所以 shell 下的命令也会加载进内存;但是,对于外部命令就不会了,外部命令会通过 hash 算法缓存起来,以便加快访问速度,可以通过 hash 命令来查看。
    nagisaushio
        9
    nagisaushio  
       219 天前 via Android
    D 进程只是表象,原因有很多,比如 nfs 挂了,显卡挂了,系统忙于 swap 等等都有可能。你需要解决的是对应的具体问题
    iminto
        10
    iminto  
       219 天前
    没考虑过,直接手动删除 /proc/ 下对应的文件,估计没这么简单

    你纠结能不能清理有啥意义呢,大概率是想眼不见为净,那就从读取进程信息的地方看起,不让它读出来,你应该去看读这块的代码
    mightybruce
        11
    mightybruce  
       219 天前   ❤️ 1
    D 状态的进程是无法杀掉的。事实上,在 Linux 内核里,内核中是无法杀掉任何进程的,所有的进程都只能自杀。

    kill 的本质是向进程发送一个信号,每个进程每次在离开内核态前(例如刚被切换过来、从某个中断函数出来等),会检查自己是否收到信号,如果有就做相应的动作,如果是 SIGKILL ,就自杀。

    D 状态的进程,处于不可中断的状态,因此无法得知自己收到了信号,也就无法被杀掉。

    很多 D 状态( Uninterruptible Sleep State )进程都是硬件离线之类的故障导致的,基本不可控制。

    用 strace 查看 进程发起哪些系统调用,是什么导致这个原因。
    强行的做法 是写一个内核模块,插入模块修改进程结构将一个 uninterruptable 的进程变成 stopped 并杀掉,不过你自己承担可能出现的各种问题。
    http://blog.chinaunix.net/uid-20301055-id-2741526.html
    hexler
        12
    hexler  
    OP
       219 天前
    @PTLin 我就是希望能有一种通用的方案自动处理这种情况
    hexler
        13
    hexler  
    OP
       219 天前
    @xwwsxp .........我只是举个例子
    PTLin
        14
    PTLin  
       219 天前
    @PTLin 一楼我说错了,自旋锁是防止内核抢占,不是 D 状态,记错了
    hexler
        15
    hexler  
    OP
       219 天前
    @nagisaushio 我就是希望有一个通用的方案来解决 D 住的问题,至于原因 cat kstack ,看下源码,大概率就知道为啥卡住了。
    比如现在一种情况,插了一个 u 盘,dd 读写,然后我 u 盘在读写的某个过程中拔掉了,并且物理破坏了这个 u 盘,虽然有些极端,但是存在很多场景相应的块设备无法再恢复的情况,这种情况居然没有一种办法恢复!我一直深受其扰
    hexler
        16
    hexler  
    OP
       219 天前
    @iminto 这个不现实,/proc 下面应该很多都没有实现删除的方法吧,直接报错的
    Hawthorne
        17
    Hawthorne  
       219 天前
    这个想法挺好。既然能破坏性的删掉根目录,也应该允许 kill 掉 D 进程。

    有一个方法是 gdb 或许可以尝试,比如跳过卡住的代码,设置直接搞挂进程。
    hexler
        18
    hexler  
    OP
       219 天前
    @mightybruce 哥,我试过修改进程状态了,不好使,不过你针对 D 状态的说法很多。
    hexler
        19
    hexler  
    OP
       219 天前
    @Hawthorne 大部分卡在内核栈,gdb 修改不了
    asilin
        20
    asilin  
       219 天前
    之前在线上解决过同事写的一个大量产生 D 进程的程序,我的解决方案是跑在 Docker 中即可,主程序自己判断当前的 D 进程数量,超过 1000 就自杀,容器重启,D 进程就自然而然的消失了。
    LGA1150
        21
    LGA1150  
       219 天前
    @PTLin sysrq-trigger 就可以看到 D 进程状态

    echo w > /proc/sysrq-trigger 然后看内核日志
    hexler
        22
    hexler  
    OP
       219 天前
    @asilin 容器命名空间啥的和主机上的是隔离的,容器内的应该是可以释放掉,我改天研究下看能不能有思路,谢谢
    julyclyde
        23
    julyclyde  
       218 天前
    @xwwsxp 你整句都和问题没啥关系啊
    julyclyde
        24
    julyclyde  
       218 天前
    @mightybruce KILL 、STOP 、CONT 等很多信号都是发给内核的,和进程没什么关系,它都没有任何感觉就直接消失了
    hanyuwei70
        25
    hanyuwei70  
       206 天前
    D 住的进程一定有原因,你要做的是查出来原因。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3507 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 88ms · UTC 00:09 · PVG 08:09 · LAX 17:09 · JFK 20:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.