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 会话仍然打开并准备测试您的答案:-)
请注意,这个问题不是关于如何停止阵列,而是如何识别仍在使用阵列中的文件的进程/防止它被破坏。
根据查找对延迟卸载文件系统的引用页面,该lsof工具似乎没有列出非绝对路径(lsof\xe2\x80\x99s 输出不规则),更糟糕的是,它没有\xe2\ x80\x99t 列出其他文件系统依赖项,例如内存映射。
至于解决方法,您必须查看/proc/*/maps其中显示属于每个进程的内存映射,以指示映射的类型,以及它是否是文件或路径。然而lsof,与 一样,如果托管文件的文件系统被延迟卸载,则绝对路径不可用。
这是建议的脚本:
\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:$\'\nRun Code Online (Sandbox Code Playgroud)\n\n这可以帮助消除已知的误报。
\n\n此外,您还可以签到/proc/X/fd/*和/proc/X/cwd。