Por que o kill baseado em unshar apenas funciona de maneira confiável com o --fork?

0

De esta resposta , aprendemos que você pode implementar a eliminação confiável de subárvores inteiras de processo com namespaces Linux PID via unshare -p .

Aqui está um problema que eu não entendo:

  • Funciona somente quando eu uso a opção -f / --fork para cancelar o compartilhamento.

    unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"
    

    Quando eu executo isso, e kill -9 o PID desse bash , então observe, durma etc estão todos mortos, como eu desejo.

  • Mas quando eu uso sem -f :

    unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"
    

    e kill -9 do PID bash, então o watch é reparado no PID 1 (no meu Ubuntu que é systemd), então eu não tenho o efeito desejado de matar todas as crianças.

Perguntas:

  • Por que --fork é necessário para obter o efeito desejado? Por que unshare usando exec() sem garfo não é suficiente?
  • Existe uma solução para isso? Eu preferiria se eu pudesse enviar convenientemente kill -9 para o PID criado iniciando unshare para matar tudo abaixo dele. Mas quando eu uso --fork , matar o pid retornado quando eu iniciei o unshare irá, simplesmente, matar unshare e ter bash reparado no PID 1, porque unshare não está no meu namespace PID. li>

Note que o && echo hi é necessário porque se você der apenas um comando para bash -c , ele irá exec() e assim o processo bash será removido (substituído) e você não poderá matar seu PID .

    
por nh2 19.09.2017 / 16:41

1 resposta

0

Conforme descrito nesta resposta útil , os efeitos de -n ( unshare(CLONE_NEWPID) ) só entram em conta para o primeiro processo filho bifurcado.

Em particular, homem 2 sem compartilhamento diz sobre CLONE_NEWPID :

Unshare the PID namespace, so that the calling process has a new PID namespace for its children which is not shared with any previously existing process.

The calling process is not moved into the new namespace.

The first child created by the calling process will have the process ID 1 and will assume the role of init(1) in the new namespace.

Corrigindo unshare para tornar o trabalho de matar confiável

Desde que fiz minha pergunta, nas últimas duas horas eu escrevi um patch para util-linux ( pull request aqui ) que adiciona um sinal --kill-child a unshare .

Edit: Isso agora é mesclado e liberado como parte do util-linux v2.32 .

Você pode usá-lo assim:

unshare -fp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"

e a morte de unshare irá derrubar toda a árvore de processos conforme expulso.

Sem root

Você pode até usá-lo sem root privileges se o seu kernel tiver namespaces de usuário habilitados ( CONFIG_USER_NS=y ) passando o sinal -U :

unshare -Ufp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"
    
por 19.09.2017 / 23:37