Máximo de descritores de arquivos

2

Eu gostaria de escrever um script que utilizará todos os descritores de arquivos disponíveis em minha máquina Linux. Eu não tenho certeza de como exatamente fazer isso, ou se é mesmo possível? Mas eu gostaria de usar este script para uma experiência do tipo 'caos macaco' na minha VM Linux.

Eu prefiro que o roteiro esteja no bash, mas eu não sou muito exigente com relação a isso.

    
por user238113 28.06.2017 / 11:19

2 respostas

2

Isso fará isso (em cerca de 40 segundos no meu sistema):

#!/bin/bash
[ "$BASHPID" = "$$" ] || { echo "Must run in a new process group"; exit 1; }>&2
cnt0() { cnt0=$#; }
cnt1() { cnt1=$#; }

tmpd=
trap 'rm -rf "$tmpd"; exit 1' INT HUP QUIT EXIT
tmpd=$(mktemp -d)
mkfifo "$tmpd/fifo"
exec 4<>"$tmpd/fifo"
rm -rf "$tmpd"
trap - INT HUP QUIT EXIT


open_all()
{ 
    cnt0 /proc/self/fd/*; 
    while exec {fd}</dev/null; do :; done; 
    cnt1 /proc/self/fd/*;
    nopened=$((cnt1-cnt0));
    echo $nopened >&4;
    cat /proc/sys/fs/file-nr
    if ((nopened)); then
        sleep 10000000
    fi
}

( open_all )&
while :; do
    if read nopened <&4 && ((nopened)); then
        ( open_all )&
        continue
    fi
    break
done
kill -TERM -$$

Funciona abrindo /dev/null em um subshell o maior número de vezes possível (deve funcionar cerca de 1000-4000 vezes, dependendo do seu ulimit -n ). Se pelo menos um filedescriptor for aberto, o pai será notificado por meio de um pipe e a subshell será suspensa com sleep . O processo pai responde a uma alocação fd bem-sucedida no filho, continuando o processo em outra sub-shell até que uma sub-camada falhe.

/proc/sys/fs/file-nr é cat em cada iteração para que você saiba como o processo continua.

No final do processo, você deve receber algo como:

...
778192  0       786806
779248  0       786806
780272  0       786806
781264  0       786806
782256  0       786806
783280  0       786806
784304  0       786806
785328  0       786806
786352  0       786806
./open_all: line 35: cannot redirect standard input from /dev/null: Too many open files in system
./open_all: line 18: fd: Too many open files in system
Terminated

Uma coisa interessante que aprendi com isso é que os filedescriptors duplicados (de dup ou fork) não contam para o limite (gerar um processo pai com muitos descritores de arquivos não aumenta a contagem).

    
por 28.06.2017 / 13:34
1

Shell

while true ; do cat > $(( $RANDOM * $RANDOM )).file & done; Você provavelmente atingirá o limite maxprocess se não for root. Nesse caso, use um processo perl para abrir arquivos. Você pode diminuir maxfiles com sysctl, embora eu não conheça a variável off-hand.

    
por 28.06.2017 / 12:54