可以从 shell 重新设置父级吗?

可以从 shell 重新设置父级吗?

这个问题与以下问题密切相关如何从 shell“正确”启动应用程序但试图解决更具体的问题。如何从 shell 生成应用程序,从而使其成为另一个进程的子进程。这是我用两个图形举例说明的意思:

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.但我想要实现的是将 firefox 和 chromium 作为dwm.因此,我想要与您在weston以下进程树的部分中看到的类似的行为,其中 Firefoxweston-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

一种可能的解决方案是使用nsenterfrom util-linux。我可以输入进程的命名空间dwm并派生一个新的 firefox 进程,该进程将成为dwm.然而,这似乎需要很多工作。有一些更简单的方法可以做到这一点吗?

答案1

您不能将一个进程作为 shell 的子进程启动,然后“重新设置其父进程”,以便另一个进程成为它的父进程。

因此,您需要使用显式启动子进程的父进程。

initPID 1 是一个例外,进程可以成为它的子进程,因为它收集丢失其原始父进程的进程。

(对于 upstart,可以有多个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;
}

在后台运行一些不需要 shell 参与的程序,退出 konsole,运行ps,退出程序,看看会发生什么。替换konsole为您想要的任何内容。

现在,为了实现您想要的目的,请使用prctl()PoC 中的调用,然后execve()使用 to dwm。希望这dwm wait()适用于非特定儿童,以免他们最终成为僵尸。

最后说明:仍然没有“重新养育”这样的事情。即,您仍然不能任意将父进程分配给进程。

答案3

我不相信您可以将进程作为父进程发送到 dwm 进程。但是,如果您可以将屏幕或 shell 作为 dwm 的子进程启动,那么您可以将所需的进程重新设置为该进程。请参阅此链接了解详细信息:http://monkeypatch.me/blog/move-a-running-process-to-a-new-screen-shell.html

答案4

雷普特尔,您可以将正在运行的程序重新设置为新终端。这里是一个更长的解释它是如何工作的。

相关内容