识别仍在使用惰性卸载文件系统上的文件的进程

mat*_*att 5 linux mdadm mount unmounting open-files

我有一个/dev/md127mdadm RAID 0 阵列,前段时间安装为/mnt/storage1. 在某些时候,我打开了一个 bash 会话并将 CWD 更改/mnt/storage1为 bash 会话仍然处于活动状态。然后我决定卸载阵列并销毁它,所以我做了:

/# umount /mnt/storage1
Device or resource busy msg
/# umount -l /mnt/storage1
(Succeeded)
/# rmdir /mnt/storage1
(Succeeded)
Run Code Online (Sandbox Code Playgroud)

我确认/mnt/storage1已删除。mount未显示/dev/md127为已安装。尽管如此,我提到的 bash 会话仍然有/mnt/storage1它的工作目录:

/mnt/storage1# _
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试停止并销毁 /dev/md127 数组时,我得到了回报:

/# mdadm --stop /dev/md127
mdadm: Cannot get exclusive access to /dev/md127:Perhaps a running process, mounted filesystem or active volume group?
Run Code Online (Sandbox Code Playgroud)

lsof 没有列出任何文件仍然在 /dev/md127 或 /mnt/storage1 上打开

/# lsof |grep storage1
/# (No results)
/# lsof |grep md127
/# (No results)
Run Code Online (Sandbox Code Playgroud)

我什至试图列出仍然在/mnt/storage1目录中的 bash 进程打开的文件,但没有成功(是的,3172 是 bash 进程的正确 PID)

/# lsof -p 3172
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
bash    3172 root  cwd    DIR   0,40       40      256 /
bash    3172 root  rtd    DIR    9,0     4096        2 /
bash    3172 root  txt    REG    9,0  1037528 10485776 /bin/bash
bash    3172 root  mem    REG    9,0    47600  1310937 /lib/x86_64-linux-gnu/libnss_files-2.23.so
bash    3172 root  mem    REG    9,0    47648  1310851 /lib/x86_64-linux-gnu/libnss_nis-2.23.so
bash    3172 root  mem    REG    9,0    93128  1310763 /lib/x86_64-linux-gnu/libnsl-2.23.so
bash    3172 root  mem    REG    9,0    35688  1310755 /lib/x86_64-linux-gnu/libnss_compat-2.23.so
bash    3172 root  mem    REG    9,0  2981280 16522333 /usr/lib/locale/locale-archive
bash    3172 root  mem    REG    9,0  1864888  1311188 /lib/x86_64-linux-gnu/libc-2.23.so
bash    3172 root  mem    REG    9,0    14608  1311189 /lib/x86_64-linux-gnu/libdl-2.23.so
bash    3172 root  mem    REG    9,0   167240  1311191 /lib/x86_64-linux-gnu/libtinfo.so.5.9
bash    3172 root  mem    REG    9,0   162632  1311181 /lib/x86_64-linux-gnu/ld-2.23.so
bash    3172 root  mem    REG    9,0    26258 16523837 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
bash    3172 root    0u   CHR  136,0      0t0        3 /dev/pts/0
bash    3172 root    1u   CHR  136,0      0t0        3 /dev/pts/0
bash    3172 root    2u   CHR  136,0      0t0        3 /dev/pts/0
bash    3172 root  255u   CHR  136,0      0t0        3 /dev/pts/0
Run Code Online (Sandbox Code Playgroud)

我什至试图获得 bash 进程的 CWD,但这给出了错误的(?)结果:

/# pwdx 3172
3172: /
Run Code Online (Sandbox Code Playgroud)

让我们再假设我不知道哪个进程阻止我停止数组。我怎样才能识别它?

这个问题与https://superuser.com/questions/471327/how-to-force-mdadm-to-stop-raid5-array有关- 这个问题已经困扰我好几年了,现在一旦发生在我身上再次我想正确解决它。bash 会话仍然打开并准备测试您的答案:-)

请注意,这个问题不是关于如何停止阵列,而是如何识别仍在使用阵列中的文件的进程/防止它被破坏。

ken*_*orb 2

根据查找对延迟卸载文件系统的引用页面,该lsof工具似乎没有列出非绝对路径(lsof\xe2\x80\x99s 输出不规则),更糟糕的是,它没有\xe2\ x80\x99t 列出其他文件系统依赖项,例如内存映射。

\n\n

至于解决方法,您必须查看/proc/*/maps其中显示属于每个进程的内存映射,以指示映射的类型,以及它是否是文件或路径。然而lsof,与 一样,如果托管文件的文件系统被延迟卸载,则绝对路径不可用。

\n\n

这是建议的脚本:

\n\n
!/bin/bash\ncat /proc/*/maps \n  | awk \'{print $6}\'\n  | grep -v \'^/\'         # remove absolute paths\n  | grep -v \'^$\' \n  | grep -v \'(deleted)\' \n  | grep -v \'^.vdso.$\' \n  | grep -v \'^.heap.$\' \n  | grep -v \'^.stack.$\' \n  | grep -v \'^.vsyscall.$\' \n  | grep -v \'^socket:$\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

这可以帮助消除已知的误报。

\n\n

此外,您还可以签到/proc/X/fd/*/proc/X/cwd

\n