如何清理掉系统上 D 住的进程? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
hexler
V2EX    Linux

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

  •  
  •   hexler 2024-03-26 15:45:03 +08:00 2522 次点击
    这是一个创建于 640 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    你纠结能不能清理有啥意义呢,大概率是想眼不见为净,那就从读取进程信息的地方看起,不让它读出来,你应该去看读这块的代码
    mightybruce
        11
    mightybruce  
       2024-03-26 17:15:34 +08:00   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
       2024-03-26 17:37:53 +08:00
    @PTLin 我就是希望能有一种通用的方案自动处理这种情况
    hexler
        13
    hexler  
    OP
       2024-03-26 17:39:14 +08:00
    div class="reply_content">@xwwsxp .........我只是举个例子
    PTLin
        14
    PTLin  
       2024-03-26 17:39:48 +08:00
    @PTLin 一楼我说错了,自旋锁是防止内核抢占,不是 D 状态,记错了
    hexler
        15
    hexler  
    OP
       2024-03-26 17:51:52 +08:00
    @nagisaushio 我就是希望有一个通用的方案来解决 D 住的问题,至于原因 cat kstack ,看下源码,大概率就知道为啥卡住了。
    比如现在一种情况,插了一个 u 盘,dd 读写,然后我 u 盘在读写的某个过程中拔掉了,并且物理破坏了这个 u 盘,虽然有些极端,但是存在很多场景相应的块设备无法再恢复的情况,这种情况居然没有一种办法恢复!我一直深受其扰
    hexler
        16
    hexler  
    OP
       2024-03-26 17:53:49 +08:00
    @iminto 这个不现实,/proc 下面应该很多都没有实现删除的方法吧,直接报错的
    Hawthorne
        17
    Hawthorne  
       2024-03-26 17:54:51 +08:00
    这个想法挺好。既然能破坏性的删掉根目录,也应该允许 kill 掉 D 进程。

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

    echo w > /proc/sysrq-trigger 然后看内核日志
    hexler
        22
    hexler  
    OP
       2024-03-26 20:15:48 +08:00
    @asilin 容器命名空间啥的和主机上的是隔离的,容器内的应该是可以释放掉,我改天研究下看能不能有思路,谢谢
    julyclyde
        23
    julyclyde  
       2024-03-27 18:20:14 +08:00
    @xwwsxp 你整句都和问题没啥关系啊
    julyclyde
        24
    julyclyde  
       2024-03-27 18:21:12 +08:00
    @mightybruce KILL 、STOP 、CONT 等很多信号都是发给内核的,和进程没什么关系,它都没有任何感觉就直接消失了
    hanyuwei70
        25
    hanyuwei70  
       2024-04-08 23:54:18 +08:00
    D 住的进程一定有原因,你要做的是查出来原因。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2575 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 53ms UTC 05:15 PVG 13:15 LAX 21:15 JFK 00:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86