이 질문은 다음과 밀접한 관련이 있습니다.셸에서 애플리케이션을 "올바르게" 시작하는 방법하지만 좀 더 구체적인 문제를 해결하려고 합니다. 다른 프로세스의 하위 프로세스가 되도록 셸에서 애플리케이션을 생성하는 방법입니다. 이것이 두 가지 그래픽 예에서 의미하는 바입니다.
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
프로세스 트리 에서는 chromium과 firefox가 부팅 init
시 시작 되고 PID 1
. 프로세스:dwm
weston
weston-desktop
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
가능한 해결책 중 하나는 nsenter
from 을 사용하는 것입니다 util-linux
. 프로세스의 네임스페이스 dwm
에 들어가서 dwm
. 이 작업을 수행하는 더 쉬운 방법이 있습니까?
답변1
프로세스를 쉘의 하위로 시작한 다음 다른 프로세스가 해당 상위 프로세스가 되도록 "상위 재지정"할 수는 없습니다.
따라서 하위 프로세스를 명시적으로 시작하는 상위 프로세스를 사용해야 합니다.
init
PID 1은 예외입니다. 프로세스는 원래 상위를 잃은 프로세스를 수집하기 때문에 해당 프로세스의 하위가 될 수 있습니다.
init
(업스타트의 경우 PID 1을 공유하지 않지만 매우 유사한 역할을 갖는 여러 프로세스가 있을 수 있습니다 .)
(또한 참조PR_SET_CHILD_SUBREAPER in man 2 prctl
)
답변2
당신이 요구하는 것은 단순히 불가능합니다. Unix와 Linux의 설계에 따라 내부 프로세스 관리는 init
상위 프로세스가 종료되는 모든 프로세스의 상위 프로세스가 됩니다. 이는 프로세스에 부모가 있어야 하고(설계상) init가 죽으면 init
시스템이 종료되기 때문에 항상 존재하기 때문입니다. 하지만 그 이상에는 "재육아" 과정 같은 것이 없습니다.
편집하다
하지만:lord.garbage가 지적했듯이 prctl()
정말 멋지고 이를 사용하는 모든 프로그램을 이식 불가능하게 만드는 신비한 시스템 호출이 있습니다. 우리는 상관하지 않는다고 가정합니다. 이 PR_SET_CHILD_SUBREAPER
옵션은 wait()
귀하의 자녀(이전과 마찬가지로)뿐만 아니라 모든 후손(부모가 조기 사망한 경우)에게도 사용하십시오. 따라서 이 기능을 사용하는 프로세스는 init
해당 하위 항목에 대한 역할을 맡을 수 있습니다. 다음 코드는 개념 증명입니다.
#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;
}
쉘 참여가 필요하지 않은 일부 프로그램을 백그라운드에서 실행하십시오. konsole을 종료하고 ps
프로그램을 종료한 후 무슨 일이 일어나는지 확인하십시오. konsole
원하는 것으로 교체하십시오 .
이제 원하는 것을 달성하려면 prctl()
PoC의 호출을 사용한 다음 execve()
to 를 사용하세요 dwm
. 이것이 dwm
wait()
비특이적 어린이에게 효과가 있어서 그들이 결국 좀비가 되지 않기를 바랍니다.
최종 참고사항:아직 '재육아' 같은 것은 없습니다. 즉, 프로세스에 부모를 임의로 할당할 수는 없습니다.
답변3
프로세스를 상위 프로세스로 dwm 프로세스에 보낼 수 있다고 생각하지 않습니다. 그러나 dwm의 하위 프로세스로 screen 또는 shell을 시작할 수 있는 경우 원하는 프로세스를 해당 프로세스로 재설정할 수 있습니다. 자세한 내용은 다음 링크를 참조하세요.http://monkeypatch.me/blog/move-a-running-process-to-a-new-screen-shell.html