无法通过kill -9终止badblocks进程的技术求助
老哥我太懂你这种烦躁的心情了——明明就是个处理老软盘的进程,kill -9都干不掉,还逼得想重启?别慌,我给你捋清楚为啥杀不掉,还有不用重启就能解决的办法。
问题1:为什么这个进程这么难杀?
你看进程状态是D,这是不可中断睡眠状态(Uninterruptible Sleep)。这种状态下,进程正死死等着硬件I/O操作的结果(比如等着USB软驱返回磁盘检测的数据),内核为了保证数据一致性,会完全屏蔽所有信号——包括最狠的SIGKILL(也就是kill -9发的信号)。
简单说就是:这个badblocks现在“卡”在和软驱硬件交互的死胡同里,内核不让它处理任何终止请求,必须等硬件那边给个准信(哪怕是设备出错的信号),它才会从D状态退出来,才能响应kill命令。你dmesg里的blocked for more than 122 seconds提示也印证了这点——进程一直在等软驱的I/O响应,大概率是这个库存软盘或者USB软驱本身有硬件故障,导致I/O彻底卡住了。
问题2:怎么才能杀掉它(不用重启)?
按下面的方法依次尝试,大概率能解决:
1. 重置USB软驱设备(最有效)
问题根源在硬件I/O卡住,重置设备能让进程拿到I/O结果(比如设备断开的错误),从而自动退出:
- 先找到你的USB软驱的总线和设备号:执行
lsusb,找到类似这样的行:
这里的Bus 002 Device 005: ID 05e3:0718 Genesys Logic, Inc. USB 2.0 floppy disk drive002是bus号,005是device号,合起来就是2-5 - 进入USB驱动目录:
cd /sys/bus/usb/drivers/usb - 解绑设备:
echo "2-5" > unbind(把这里的2-5换成你自己的bus-device组合) - 等待3-5秒,再重新绑定:
echo "2-5" > bind
做完这步再用ps aux | grep badblocks看看,进程大概率已经消失了。
2. 强制卸载设备(如果挂载过)
如果这个软驱的分区被挂载过,先尝试卸载:
umount /dev/sdh
如果卸载成功,badblocks因为失去了设备资源,会直接退出。如果提示device is busy,还是得先做上面的设备重置。
3. 热插拔USB软驱
虽然看起来简单,但有时候直接拔下USB软驱再插回去,能直接终止卡住的I/O请求,让进程拿到设备断开的信号从而退出。紧急情况下可以试试,注意如果设备之前挂载过,最好先执行unbind操作再拔,避免内核报错。
4. 用sysrq工具排查(进阶操作)
如果上面的方法都没用,可以用sysrq查看进程的详细栈信息,确认它到底卡在哪个I/O环节:
- 先开启sysrq(如果没开的话):
echo 1 > /proc/sys/kernel/sysrq - 触发进程状态dump:
echo t > /proc/sysrq-trigger - 查看
dmesg或者系统日志(比如/var/log/messages),里面会有badblocks进程的调用栈信息,能帮你确定是不是硬件彻底挂了。
不过这步只是排查,不是直接杀进程,但能帮你判断有没有继续尝试的必要。
最后实在没辙的情况
如果所有方法都试过,进程还是死死卡在D状态,那确实没办法在不重启的情况下杀掉它——因为D状态的进程完全不受用户空间信号控制,内核为了避免数据损坏,也不会强制终止它。但这种情况很少见,一般重置USB设备就能解决。
备注:内容来源于stack exchange,提问作者AlphaCentauri

