原理:使用 LVM 卷的 suspend 特性,暂停 IO,使得上层应用程序处于 D 状态。

Setps :

  1. 使用 losetup 创建一个卷作为 pv 的磁盘。

     [tmp]# pwd
     /root/tmp
     [tmp]# dd if=/dev/zero of=disk count=2048 bs=1M
     ...
     [tmp]# losetup --show -f disk
     ...
     [tmp]# lsblk
     ...
     loop0             7:0    0    2G  0 loop
     ...
    
  2. 使用 /dev/loop0 创建 pv, vg 和 lv。

     [tmp]# pvcreate /dev/loop0
       Physical volume "/dev/loop0" successfully created.
     [tmp]# vgcreate vgtest /dev/loop0
       Volume group "vgtest" successfully created
     [tmp]# lvcreate -n lvtest -L 1G vgtest
       Logical volume "lvtest" created.
    
  3. 在 lv 上创建一个文件系统

     [tmp]# mkfs.ext4 -m0 /dev/vgtest/lvtest
     [tmp]# mount /dev/vgtest/lvtest /mnt
     [tmp]# lsblk
     ...
     loop0             7:0    0    2G  0 loop
     └─vgtest-lvtest 253:0    0    1G  0 lvm  /root/tmp/mnt
     ...
    
  4. 写 IO 的同时暂停 lv。

     [tmp]# dmsetup suspend /dev/vgtest/lvtest && dd if=/dev/urandom of=/root/tmp/file.img bs=1M count=1024
    

    此时,该进程就会处于 D 状态,不会返回。可以通过另一个 shell 来检查这个进程。

     [~]# ps aux | grep D | grep '/root/tmp/mnt/'
     root     19492  0.0  0.0 107996   620 pts/0    D+   11:16   0:00 dd if=/dev/urandom of=/root/tmp/mnt/file.img bs=1M count=1024
    
     [~]# pstree -g -a --show-parents 19492
     systemd,1 --switched-root --system --deserialize 22
       └─sshd,5398 -D
             └─sshd,2515
                       └─bash,2643
                             └─dd,19492 if=/dev/urandom of=/root/tmp/mnt/file.img bs=1M count=1024
    
  5. 恢复 lv 的 IO。

     [~]# dmsetup resume /dev/vgtest/lvtest
    

    之前卡住的 dd 命令会继续。


知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。