É reparável a partir do shell possível?

0

Esta questão está intimamente relacionada com Como " corretamente "iniciar um aplicativo de um shell , mas tenta resolver um problema mais específico. Como posso gerar um aplicativo a partir de um shell e, assim, torná-lo filho de outro processo. Aqui está o que quero dizer exemplificado com dois gráficos:

systemd-+-acpid
        |-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
        |                 |                           '-chromium---5*[chromium-+-{Chrome_ChildIOT}]
        |                 |                                                    |-{Compositor}]
        |                 |                                                    |-{HTMLParserThrea}]
        |                 |                                                    |-{OptimizingCompi}]
        |                 |                                                    '-3*[{v8:SweeperThrea}]]
        |                 |-chromium
        |                 |-chromium-+-chromium
        |                 |          |-{Chrome_ChildIOT}
        |                 |          '-{Watchdog}
        |                 |-{AudioThread}
        |                 |-3*[{BrowserBlocking}]
        |                 |-{BrowserWatchdog}
        |                 |-5*[{CachePoolWorker}]
        |                 |-{Chrome_CacheThr}
        |                 |-{Chrome_DBThread}
        |                 |-{Chrome_FileThre}
        |                 |-{Chrome_FileUser}
        |                 |-{Chrome_HistoryT}
        |                 |-{Chrome_IOThread}
        |                 |-{Chrome_ProcessL}
        |                 |-{Chrome_SafeBrow}
        |                 |-{CrShutdownDetec}
        |                 |-{IndexedDB}
        |                 |-{LevelDBEnv}
        |                 |-{NSS SSL ThreadW}
        |                 |-{NetworkChangeNo}
        |                 |-2*[{Proxy resolver}]
        |                 |-{WorkerPool/1201}
        |                 |-{WorkerPool/2059}
        |                 |-{WorkerPool/2579}
        |                 |-{WorkerPool/2590}
        |                 |-{WorkerPool/2592}
        |                 |-{WorkerPool/2608}
        |                 |-{WorkerPool/2973}
        |                 |-{WorkerPool/2974}
        |                 |-{chromium}
        |                 |-{extension_crash}
        |                 |-{gpu-process_cra}
        |                 |-{handle-watcher-}
        |                 |-{inotify_reader}
        |                 |-{ppapi_crash_upl}
        |                 '-{renderer_crash_}
        |-2*[dbus-daemon]
        |-dbus-launch
        |-dhcpcd
        |-firefox-+-4*[{Analysis Helper}]
        |         |-{Cache I/O}
        |         |-{Cache2 I/O}
        |         |-{Cert Verify}
        |         |-3*[{DOM Worker}]
        |         |-{Gecko_IOThread}
        |         |-{HTML5 Parser}
        |         |-{Hang Monitor}
        |         |-{Image Scaler}
        |         |-{JS GC Helper}
        |         |-{JS Watchdog}
        |         |-{Proxy R~olution}
        |         |-{Socket Thread}
        |         |-{Timer}
        |         |-{URL Classifier}
        |         |-{gmain}
        |         |-{localStorage DB}
        |         |-{mozStorage #1}
        |         |-{mozStorage #2}
        |         |-{mozStorage #3}
        |         |-{mozStorage #4}
        |         '-{mozStorage #5}
        |-gpg-agent
        |-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
        |                               |          '-{Xorg.bin}
        |                               '-dwm-+-dwmstatus
        |                                     '-xterm---bash-+-bash
        |                                                    '-pstree
        |-systemd---(sd-pam)
        |-systemd-journal
        |-systemd-logind
        |-systemd-udevd
        |-wpa_actiond
        '-wpa_supplicant

A árvore de processos mostra o cromo e o firefox como filhos do processo init que começa na inicialização e tem PID 1 . Mas o que eu quero alcançar é iniciar o firefox e o cromo como filhos de dwm . Portanto, quero um comportamento semelhante ao que você pode ver na parte weston da seguinte árvore de processos, na qual o firefox tem weston-desktop como pai:

systemd-+-acpid
        |-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
        |                 |                           '-chromium-+-3*[chromium-+-{Chrome_ChildIOT}]
        |                 |                                      |             |-{Compositor}]
        |                 |                                      |             |-{HTMLParserThrea}]
        |                 |                                      |             |-{OptimizingCompi}]
        |                 |                                      |             '-3*[{v8:SweeperThrea}]]
        |                 |                                      '-4*[chromium-+-{Chrome_ChildIOT}]
        |                 |                                                    |-{CompositorRaste}]
        |                 |                                                    |-{Compositor}]
        |                 |                                                    |-{HTMLParserThrea}]
        |                 |                                                    |-{OptimizingCompi}]
        |                 |                                                    '-3*[{v8:SweeperThrea}]]
        |                 |-{AudioThread}
        |                 |-3*[{BrowserBlocking}]
        |                 |-{BrowserWatchdog}
        |                 |-5*[{CachePoolWorker}]
        |                 |-{Chrome_CacheThr}
        |                 |-{Chrome_DBThread}
        |                 |-{Chrome_FileThre}
        |                 |-{Chrome_FileUser}
        |                 |-{Chrome_HistoryT}
        |                 |-{Chrome_IOThread}
        |                 |-{Chrome_ProcessL}
        |                 |-{Chrome_SafeBrow}
        |                 |-{Chrome_SyncThre}
        |                 |-{CrShutdownDetec}
        |                 |-{IndexedDB}
        |                 |-{NSS SSL ThreadW}
        |                 |-{NetworkChangeNo}
        |                 |-2*[{Proxy resolver}]
        |                 |-{WorkerPool/2315}
        |                 |-{WorkerPool/2316}
        |                 |-{WorkerPool/2481}
        |                 |-{chromium}
        |                 |-{extension_crash}
        |                 |-{gpu-process_cra}
        |                 |-{handle-watcher-}
        |                 |-{inotify_reader}
        |                 |-{renderer_crash_}
        |                 '-{sandbox_ipc_thr}
        |-2*[dbus-daemon]
        |-dbus-launch
        |-dhcpcd
        |-gpg-agent
        |-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
        |                               |          '-{Xorg.bin}
        |                               '-dwm-+-dwmstatus
        |                                     '-xterm---bash
        |-login---bash---weston-launch---weston-+-Xwayland---4*[{Xwayland}]
        |                                       |-weston-desktop--+-firefox-+-firefox
        |                                       |                 |         |-4*[{Analysis Helper}]
        |                                       |                 |         |-{Cache2 I/O}
        |                                       |                 |         |-{Cert Verify}
        |                                       |                 |         |-{DNS Resolver #1}
        |                                       |                 |         |-{DNS Resolver #2}
        |                                       |                 |         |-2*[{DOM Worker}]
        |                                       |                 |         |-{Gecko_IOThread}
        |                                       |                 |         |-{HTML5 Parser}
        |                                       |                 |         |-{Hang Monitor}
        |                                       |                 |         |-{Image Scaler}
        |                                       |                 |         |-{ImageDecoder #1}
        |                                       |                 |         |-{ImageDecoder #2}
        |                                       |                 |         |-{ImageDecoder #3}
        |                                       |                 |         |-{JS GC Helper}
        |                                       |                 |         |-{JS Watchdog}
        |                                       |                 |         |-{Socket Thread}
        |                                       |                 |         |-{Timer}
        |                                       |                 |         |-{URL Classifier}
        |                                       |                 |         |-{gmain}
        |                                       |                 |         |-{localStorage DB}
        |                                       |                 |         |-{mozStorage #1}
        |                                       |                 |         |-{mozStorage #2}
        |                                       |                 |         |-{mozStorage #3}
        |                                       |                 |         |-{mozStorage #4}
        |                                       |                 |         '-{mozStorage #5}
        |                                       |                 '-weston-terminal---bash---pstree
        |                                       '-weston-keyboard
        |-systemd---(sd-pam)
        |-systemd-journal
        |-systemd-logind
        |-systemd-udevd
        |-tmux---bash
        |-wpa_actiond
        '-wpa_supplicant

Uma possível solução seria usar nsenter de util-linux . Eu poderia inserir o namespace do processo dwm e bifurcar um novo processo do firefox que seria então o filho de dwm . No entanto, isso parece muito trabalho. Existe alguma maneira mais fácil de fazer isso?

    
por lord.garbage 27.08.2014 / 11:04

3 respostas

5

Você não pode iniciar um processo como o filho do shell e, em seguida, "repará-lo" para que outro processo se torne pai.

Você precisa usar um processo pai que inicie explicitamente os filhos.

init com o PID 1 é uma exceção, os processos podem tornar-se secundários à medida que coleta processos que perderam o processo pai original.

(Com o upstart, pode haver vários processos init , eles não compartilham o PID 1, mas os papéis são muito semelhantes.) (Veja também PR_SET_CHILD_SUBREAPER in man 2 prctl )

    
por 27.08.2014 / 13:31
4

O que você pede é simplesmente impossível. Pelo design do gerenciamento interno de processos Unix e Linux, o init se torna o pai de todos os processos cujos pais morrem. Isso ocorre porque os processos devem ter pais (também por design), e o init sempre está lá, pois se init morre, o sistema é encerrado. Mas além disso, não existem processos de "re-paternidade".

EDITAR

No entanto: Como lord.garbage apontou, há a chamada de sistema arcano prctl() , que é legal e faz com que qualquer programa que a use não seja portável. Suponha que não nos importamos. Usando a opção PR_SET_CHILD_SUBREAPER , ela pode wait() não apenas para seus próprios filhos (como antes), mas também para todos os seus descendentes, caso seus pais morram prematuramente. Assim, um processo usando esse recurso pode assumir o papel de init para seus descendentes. O código a seguir é uma prova de conceito:

#include        <sys/prctl.h>
#include        <sys/wait.h>
#include        <unistd.h>
#include        <stdio.h>

int
main (int argc, const char* const argv[], char* const envp[])
{
        pid_t   pid;

        if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) < 0) {
                perror("prctl");
                return 4;
        }
        pid = fork();
        if (pid < 0) {
                perror("fork");
                return 4;
        }
        if (pid == 0) {
                // child
                char* const argv[] = { "/usr/bin/konsole", "-e", "/bin/bash", NULL };
                if (execve("/usr/bin/konsole", argv, envp) < 0) {
                        perror("execve");
                }
        }

        // parent
        while (1) {
                pid_t   wpid;
                int     s;

                wpid = waitpid(-1, &s, 0);
                if (wpid > 0) {
                        printf("child with pid %u has exited\n", wpid);
                }
        }

        return 0;
}

Execute alguns programas em segundo plano que não precisam de atendimento ao shell, saia do konsole, execute ps , saia dos programas e veja o que acontece. Substitua konsole por qualquer coisa que seu coração desejar.

Agora, para alcançar o que você deseja, use a chamada prctl() como no PoC e, em seguida, execve() to dwm . E espero que dwm wait() s para crianças inespecíficas para que não acabem como zumbis.

Nota final: Ainda não existe o parentesco. Ou seja você ainda não pode atribuir arbitrariamente um pai a um processo.

    
por 27.08.2014 / 22:51
0

Não acredito que você possa enviar um processo para o processo dwm como pai. Mas se você pudesse iniciar uma tela ou shell como um processo filho de dwm, então poderia reparar seus processos desejados nisso. Consulte este link para obter detalhes: link

    
por 29.09.2014 / 14:55