通过把jbd2不调度来实现,方式是把他和一个rt进程绑到一个cpu上。
README
代码语言:txt复制该脚本利用ext4的日志功能模拟一个io hang的场景
在使用该脚本前,请确保:
1.机器上有盘是挂载为ext4的,可通过 mount | grep ext4 命令查看确认
2.挂载点的ext4打开了日志功能,可通过 dumpe2fs /dev/vda1(这里是挂载为ext4的盘,上面mount命令可以看到)| grep features | grep has_journal 命令查看确认
3./proc/sys/kernel/hung_task_panic 和 /proc/sys/kernel/nmi_watchdog 为0(这里如果不为0,内核会对长期占有CPU的进程做检查,如果有进程长期占用CPU,则会导致重启。而本脚本中起了一个会长期占用CPU的进程来完成模拟io hang的效果,所以置0是为了关闭内核的检查以防止重启)
4.机器至少有两个核
5.root权限执行
使用:
chmod x io_hang_simulator.sh
./io_hang_simulator.sh 0 vda1 # 开始io hang功能,第一个参数0表示打开功能,第二个参数为想要模拟io hang的挂载为ext4的盘的名字,比如想要在/dev/vda1上模拟io hang则输入vda1,如果不输入(或输入一个不存在的盘),则默认在所有ext4挂载点上模拟
到这里就可以开始您的IO表演了,比如:在模拟的盘的挂载点上随便后台cp或者修改什么文件然后执行sync命令,再执行ps就可以看到cp/sync进程D住
./io_hang_simulator.sh 1 vda1 # 结束io hang功能,第一个参数1表示关闭功能,第二个参数同上
脚本
代码语言:txt复制# ./io_hang_simulator.sh 0/1 vda1
# 第一个参数是0表示打开功能
# 第一个参数是1表示关闭功能
# 第二个参数是盘的名字,dev目录下的xxx,如vda1或vdb1
# 第二个参数如果不输入,默认是所有挂载为ext4的盘
#####################################################
if [ $# -lt 1 ]
then
echo "Usage:"
echo " ./io_hang_simulator.sh [0: start simulator / 1: shut simulator] [disk name]"
echo "Example:"
echo " ./io_hang_simulator.sh 0 vda1"
exit 0
fi
switch=$1
shift
disk_name=$1
jbd2_pids=`ps --ppid 2 -p 2 -o pid,cmd | grep "jbd2/"$disk_name | awk '{print $1}'`
if [ x$jbd2_pids == x ]; then jbd2_pids=`ps --ppid 2 -p 2 -o pid,cmd | grep jbd2 | awk '{print $1}'`; fi;
affinity_mask=`lscpu | grep list | awk '{print $NF}'`
do_nothing_pid=
if [ x$switch == x"0" ]
then
sysctl -w kernel.sched_rt_runtime_us=-1
affinity_mask="0"
chmod x ./do_nothing.sh
./do_nothing.sh &
#echo "start doing nothing process"
do_nothing_pid=`ps --ppid $$ -p $$ -o pid,cmd | grep do_nothing | awk '{print $1}'`
chrt --fifo -p 99 $do_nothing_pid
#echo "change doing nothing to fifo"
taskset -pc $affinity_mask $do_nothing_pid
#echo "bind doing nothing to specific cpu"
else
do_nothing_pid=`ps --ppid 1 -p 1 -o pid,cmd | grep do_nothing | awk '{print $1}'`
kill -9 $do_nothing_pid
sysctl -w kernel.sched_rt_runtime_us=950000
fi
for pid in `echo $jbd2_pids`
do
taskset -pc $affinity_mask $pid
done
do nothing
代码语言:txt复制#!/bin/bash
while true;do :;done;