como determinar com segurança processos usando arquivos após 'umount -l' no linux

5

A questão

Após umount -l ser executado em algum sistema de arquivos montado, e este sistema de arquivos ainda permanece montado (embora oculto) por causa de algum processo mantendo (pelo menos) um identificador de arquivo aberto em algum arquivo (s) neste sistema de arquivos, adquirir uma lista de tais processos?

A configuração de teste

Eu executei os seguintes passos para criar uma situação deste tipo e explorar o sistema e experimentar vários comandos (usando o bach no debian jessie com um kernel linux 3.16):

sudo -i
cd $(mktemp -d) # get empty directory to play around with
# create empty file system with one file
dd if=/dev/zero of=disk bs=1M count=4
mkfs.ext4 disk
# mount the filesytem and create a file
mkdir mounted
mount disk mounted # uses /dev/loop0 in my case, actual device my vary
touch mounted/file
# fork of a process with an open file handle to file
bash -c 'cd mounted; exec 3<>file; while true; do sleep inf; done' &
# verify that the file is open in the background
lsof mounted/file
# lazy unmount
umount -l mounted
# even remove the mountpoint 
rmdir mounted

Então qual comando exibiria todos os processos abrindo alguns arquivos no arquivo / dev / loop0?

Tentativas com falha

lsof

lsof -p <thepid>

Primeiramente, isso requer conhecimento prévio do id do processo (que é a informação pesquisada aqui) e, em segundo lugar, mesmo assim, o arquivo aberto é mostrado como /file sem nenhuma indicação de que esteja no sistema de arquivos montado oculto e não na raiz normal sistema de arquivos.

fusor

Não consegui obter nenhuma saída útil do fusor. Eu acho que algo na manpage me ilude.

inspecionando / sys / fs /

Nesta configuração de teste específica, o sistema de arquivos ( ext4 ) e o dispositivo ( loop0 ) são conhecidos. Lá, ele poderia ser verificado se o sistema de arquivos já mudava do estado oculto para o estado não montado.

if [ -e /sys/fs/ext4/loop0/ ]; then
    echo "still not unmounted";
else
    echo "finally unmounted";
fi

Mas isso não fornece uma lista de processos que tenham um identificador de arquivo aberto.

inspecionando manualmente / proc

No proc algumas informações são encontradas:

assumindo que mnt_id é único em todo o sistema (não tenho conhecimento se essa suposição for verdadeira!) pode-se fazer uma lista de todos os mnt_ids não ocultos em todos processos:

find /proc/ -maxdepth 1 -type d -regex '/proc/[0-9]+' -exec "cat" "{}/mountinfo" ";" | cut -d " " -f 1 | sort -gu

e faça uma lista de todos os mnt_ids usados por qualquer fd aberto :

find /proc/ -regex '/proc/[0-9]+/fdinfo/[0-9]+' -exec cat "{}" ";" | grep mnt_id | cut -f 2 | sort -gu
# maybe gives some errors like 'Operation not permitted' or 'No such file or directory' because of inspecting it's own process and sub-process and possibly parallel things happening. probably this is an unreliable way of inspecting /proc.

Se uma abordagem sofisticada for usada para comparar essas duas listas, poder-se-ia determinar mnt_ids ocultos junto com o fd usando-os e ids de processo desses fds. Mas mesmo com esse resultado, o último passo de saber qual destes mnt_ids ocultos corresponde ao sistema de arquivos de interesse oculto, ainda estaria faltando.

    
por Max-Julian Pogner 28.05.2016 / 19:19

1 resposta

3

Devido à maneira como o ponto de montagem fica oculto com umount -l , não há como descobrir quais processos ainda estão usando arquivos afetados.

A única maneira de obter a lista é usar lsof antes de umount -l para atrair o caminho relevante. Exemplo: lsof | grep "/mountPoint/" .

Se você quiser, pode pegar essa saída para extrair os PIDs e continuar monitorando-os.

    
por 28.05.2016 / 19:56