Identifica um processo que ainda está usando um arquivo em um sistema de arquivos não montado

5

Eu tenho uma matriz RAID 0 /dev/md127 mdadm que há algum tempo foi montada como /mnt/storage1 . Em algum momento eu abri uma sessão bash e mudei o CWD para /mnt/storage1 e a sessão bash ainda está ativa. Eu decidi então desmontar o array e destruí-lo, então eu fiz:

/# umount /mnt/storage1
Device or resource busy msg
/# umount -l /mnt/storage1
(Succeeded)
/# rmdir /mnt/storage1
(Succeeded)

Confirmei que /mnt/storage1 foi eliminado. mount não mostra /dev/md127 como montado. Ainda assim, a sessão bash que mencionei ainda tem /mnt/storage1 como seu diretório de trabalho:

/mnt/storage1# _

Agora, quando eu tento parar e destruir o array / dev / md127 eu recebo retorno:

/# mdadm --stop /dev/md127
mdadm: Cannot get exclusive access to /dev/md127:Perhaps a running process, mounted filesystem or active volume group?

lsof não lista nenhum arquivo como estando ainda aberto em / dev / md127 ou / mnt / storage1

/# lsof |grep storage1
/# (No results)
/# lsof |grep md127
/# (No results)

Eu até tentei listar arquivos abertos pelo processo bash que ainda está no diretório /mnt/storage1 mas sem sucesso (e sim, 3172 é o PID correto do processo bash)

/# 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

Eu até tentei obter o CWD do processo bash, mas isso deu resultado errado (?):

/# pwdx 3172
3172: /

Vamos por um segundo assumir que não sei qual processo está me impedindo de parar o array. Como posso identificá-lo?

Esta questão está relacionada com link - o problema tem me incomodado há vários anos e agora, uma vez que me aconteceu novamente, quero resolvê-lo corretamente. A sessão do bash ainda está aberta e pronta para testar sua resposta: -)

Por favor, note que esta questão não é sobre como parar a matriz, mas como identificar o processo que ainda está usando um arquivo da matriz / impede que ele seja destruído.

    
por matt 16.02.2017 / 12:09

1 resposta

1

Como por Encontrando referências a sistemas de arquivos desmontados preguiçosos página, a ferramenta lsof não parece listar caminhos não-absolutos (a saída do lsof é irregular) e o que é pior, não lista outras dependências do sistema de arquivos como mapas de memória.

Quanto à solução alternativa, você terá que analisar /proc/*/maps , que apresenta os mapeamentos de memória que pertencem a cada processo para indicar o tipo de mapeamento e, se for um arquivo ou caminho. No entanto, como lsof , o caminho absoluto não estará disponível se o sistema de arquivos que hospeda o arquivo estiver ocioso e desmontado.

Aqui está o script sugerido:

!/bin/bash
cat /proc/*/maps 
  | awk '{print $6}'
  | grep -v '^/'         # remove absolute paths
  | grep -v '^$' 
  | grep -v '(deleted)' 
  | grep -v '^.vdso.$' 
  | grep -v '^.heap.$' 
  | grep -v '^.stack.$' 
  | grep -v '^.vsyscall.$' 
  | grep -v '^socket:$'

que pode ajudar a remover falsos positivos conhecidos.

Além disso, você também pode fazer check-in em /proc/X/fd/* e /proc/X/cwd .

    
por 01.11.2017 / 15:44