새로 시작된 프로세스의 상위 프로세스를 설정하고 싶은데 가능한가요?
예를 들어, 로그인 관리자를 통해 새로운 데스크톱 환경 세션을 시작한다고 가정하면 프로세스 트리는 다음과 같습니다.
init
\- login-manager
\- de-session
이제 세션에서 시작되어야 하는 가장 중요한 응용 프로그램을 시작하는 스크립트가 있으며 여러 가지 이유로 이를 DE의 자동 시작 관리자로 마이그레이션하는 대신 스크립트로 유지하고 싶습니다. 다음과 같습니다.
#!/usr/bin/env
application1 &
application2 &
application3 &
세션 시작 시 이 명령을 자동으로 실행한 후 프로세스 트리는 다음과 같습니다.
init
|- application1
|- application2
|- application3
\- login-manager
\- de-session
하지만 내가 실제로 원하는 것은 세션에서 이러한 프로세스를 다음과 같이 "재정의"하는 것입니다.
init
\- login-manager
\- de-session
|- application1
|- application2
\- application3
그렇다면 다른 프로세스에서 "상위 프로세스를 재설정"하는 방법이 있습니까?
답변1
일부 시스템에서는 프로세스를 다음과 같이 표시할 수 있습니다.어린이용 수확기, 이는 init
모든 자손에 대해 고아 프로세스를 채택하는 역할을 맡을 수 있게 합니다.
Linux에서는 PR_SET_CHILD_SUBREAPER
prctl()
.
따라서 다음과 같이 시작할 수 있습니다 de-session
(Linux의 값은 여기에 하드코딩되어 있습니다 PR_SET_CHILD_SUBREAPER
).
perl -e 'require "syscall.ph";
syscall(&SYS_prctl,36,1) >= 0 or die "cannot set subreaper: $!";
exec("de-session");'
그러나 de-session
생성된 적이 없는 프로세스로부터 SIGCHLD 신호를 받으면 혼란스러울 수 있습니다. 귀하의 프로세스 init
는 이러한 문제를 처리하도록 설계되었지만 귀하의 것이 아닐 수도 있으므로 상속하고 싶지 않은 프로세스의 종료를 결코 인정하지 않기 de-session
때문에 좀비 군대가 생길 수 있습니다 .de-session
답변2
사실, 불과 1년 전에 저는 TrueOS(이전의 PC-BSD)를 사용하여 이 작업을 수행했습니다.
일반 TrueOS
기본 TrueOS에서 pcdm
서비스는 그래픽 사용자 인터페이스를 실행합니다.
- Mewburn 시스템은 수명 주기가 짧은
rc
이 스크립트를 실행합니다 ./usr/local/etc/rc.d/pcdm
PCDMd
Spawn이라는 무한 루프와 다소 복잡한 쉘 스크립트는xinit
이라는 프로그램을 실행하도록 지시합니다PCDM-session
.PCDM-session
/tmp
로 생성되는 데스크탑 선택기 및 로그인 프로그램입니다/usr/local/share/PCDM/pcdm-session
.dbus-daemon
또한 통신할 데스크탑 버스에 대한 정보가 전달되지 않으면 슈퍼유저로 실행되는 것이 사이드 스트립되고 고아가 됩니다./usr/local/share/PCDM/pcdm-session
이전에 작성된 스크립트에 대한 링크입니다.sh /tmp/PCDM-session.blah
- 셸 스크립트는 모든 항목을 차례로 실행합니다
$HOME/.xprofile
. 여기서 모든 항목이 분기되고 선택한 데스크톱에 대한 세션이 실행됩니다gpg-agent
(로그인한 사용자로 실행되고 다른 프로세스가 분리됨).dbus-launch
dbus-daemon
이로 인해 분기된 모든 항목 $HOME/.xprofile
(모든 항목 실행에서 /usr/local/share/pcbsd/xstartup/
)과 데스크톱 세션 프로세스에서 시작되고 나중에 분기 및 종료 부모(예: 음, thunderbird
)를 통해 고아가 된 항목 모두에 대해 매우 지저분한 프로세스 트리가 생성됩니다. 모든 D-Bus 브로커도 그다지 좋지 않습니다. 많은 경우 프로세스 #1을 상위 프로세스 ID로 사용합니다. 이름을 지정하는 것도 일을 더 쉽게 만드는 데 도움이 되지 않습니다. pcdm
전화 PCDMd
전화 PCDM-session
전화 pcdm-session
전화.PCDM-session.blah
(나는 이것이 불필요하게 복잡하다는 것을 TrueOS 사람들에게 알리려고 노력하고 있습니다.PCDM-session
, 특히 위의 설명에서 생략한 프로그램의 완전히 불필요한 숨겨진 추가, 손상된 서비스 관리자입니다 . )
local-reaper
그리고 userenv
nosh 도구 세트에서
존재하다Nosh 도구 세트이라는 작은 체인 로딩 유틸리티가 있습니다 local-reaper
. 유일한 임무는 자신을 다음으로 표시(또는 표시 해제)하는 것입니다.대리 사신그런 다음 동일한 프로세스에서 다른 프로그램 이미지를 체인로드합니다.
Linux와 관련된 것은 없습니다.하위 수확기 메커니즘은 여러 운영 체제에서 사용할 수 있습니다.. Linux 및 FreeBSD/TrueOS/DragonFlySBD에서 실행되며 고정된 시스템 호출 번호나 이와 유사한 것이 없습니다. ☺
nosh 도구 세트에도 userenv
도구 가 있습니다 setuidgid
. 이것들이 실제로 해냈어모든 것TrueOS pcdm-session
프로그램은 DBUS_SESSION_BUS_ADDRESS
사용자별 데스크탑 버스 에이전트를 가리키도록 변수를 설정하는 것을 포함하여 이 작업을 수행합니다. 전체 TrueOS pcdm-session
프로그램은 실제로 다음으로 대체될 수 있습니다.
#!/bin/sh - 실행>>"$5" 2>&1 chown -v -h -- "$1" "${XAUTHORITY}" 구현하다\ 로컬 리퍼 true\ setuidgid --"$1" 추가\ usenv --set-path --set-other --set-tools --set-timezone --set-locale --set-xdg \ 부우 "$4"
활용local-reaper
이를 사용하려면 다음 세 가지 조건을 만족하는 프로세스를 찾아야 합니다.
- 이는 고아 프로세스의 간접적인 상위 프로세스여야 합니다.
- 그들은 오래 살아야 합니다.
- 그들은 예상하지 못했던 갑자기 자식 프로세스를 획득하는 데 적응할 수 있어야 합니다.
모든 프로세스가 적합한 것은 아닙니다. 실제로 PCDM-session
프로세스가 하위 리퍼로 적합한지 진단하는 동안 잘못된 프로세스 ID를 기다리고 있던 TrueOS 프로그램에서 버그를 발견했습니다 .PCDM-session
(나는 또한 TrueOS 사람들에게 이 오류에 대해 말했습니다. 그것은 실제로캐릭터입력 오류. )
다행스럽게도 쉘 프로그램은 거의 항상예사신이 되기에 적합하며, 이 나무에는 여러 가지 껍질 과정이 있습니다. 알고 보니 이것도 사실이다 xinit
.
향상된 프로세스 트리
그럼 무슨 일이 일어날까요?지금예;
- 나는 적절한 서비스 관리자의 지휘 하에 문제를 관리합니다. 서버 관리자 프로세스는그 자체리퍼 부관.
- Service Management는 상당히 짧은 쉘 스크립트를 생성하여 프로세스를 하위 리퍼로
local-reaper true xinit …
만듭니다 .xinit
xinit
실행하라는 지시를 받으면 쉘 인터프리터가 해석하게 됩니다.local-reaper true helper-script
도움말 스크립트세 번째 부사신.- 도움말 스크립트달리다
dbus-launch --exit-with-session PCDM-session
. 계속 실행되고 쉘 인터프리터를 실행하며PCDM-session
프로세스가 완료될 때까지 기다립니다.dbus-launch
격리된 두 개의 보조 프로세스를 분할합니다. PCDM-session
대리자가 될 수 없습니다. 동작은 변경되지 않았습니다./tmp
임의의 숫자 쉘 스크립트를 병렬로 작성합니다/usr/local/share/PCDM/pcdm-session
. 그러나 데스크탑 버스측 처리의 언번들링이 완료되었습니다.- 수정된 버전은
/usr/local/share/PCDM/pcdm-session
자신을 하위 리퍼로 표시하고 이전에 작성된 스크립트에 대한 링크를 제공합니다.sh /tmp/PCDM-session.blah
- 쉘 스크립트는 여전히 의 모든 것을 실행하므로
$HOME/.xprofile
의 모든 것을 실행/usr/local/share/pcbsd/xstartup/
하고 마지막으로 선택한 데스크탑의 세션을 실행하지만 직접 실행되며 더 이상 통과하지 않습니다dbus-launch
. 계속 실행되어 셸 인터프리터를 실행하고 데스크톱 세션 프로세스가 완료될 때까지 기다립니다.
효과는 다음과 같습니다.
- 분기된 모든 스크립트는
/usr/local/share/pcbsd/xstartup/
실행 중인 프로세스의 상위 항목으로 다시 지정됩니다.sh /tmp/PCDM-session.blah
- fork-and-exit-parent를 통해 데스크톱 세션 프로세스의 손자로서 실행되는 것과 같은 데스크톱 애플리케이션은
thunderbird
실행 중인 프로세스의 상위 항목으로 변경됩니다.sh /tmp/PCDM-session.blah
- 분기되고 분리된 보조 프로세스는 다시 상위 프로세스
dbus-launch
가 됩니다 .helper-script
dbus-daemon
모든 것이 올바른 서비스 관리 하에 사용자 수준 서비스로 프로세스 트리의 다른 부분에서 실행되는 사용자별 데스크톱 버스 에이전트를 가리키기 때문에 사용자 측 프로세스에서 분기되는 일이 없습니다 .- 다시 양육하는 것 외에는 아무것도 없습니다
xinit
. 하위 수확기로 만들 필요는 없다는 것이 밝혀졌습니다.
프로세스 트리는 프로세스 #1에서 시작하며 다음과 같습니다.
/sbin/시스템 관리자-- |-- cyclolog --최대 파일 크기 262144 --최대 총 크기 1048576. (시스템 관리자) `-- 서비스 관리자(시스템 관리자) … |-- 사용자별 관리자 |-- cyclolog --최대 파일 크기 262144 --최대 총 크기 1048576. `--서비스 관리자 |-- 사이클로그 JdeBP/소켓 서버/ |-- 사이클로그 JdeBP/dbus-servers/ |-- dbus-daemon --config-file ./per-user.conf --nofork --address=unix:path=/run/user/JdeBP//bus … |-- /bin/sh - ./helper 실행 `-- xinit /bin/exec local-reaper true ./helper 세션 -- :0 -auth -retro |-- X :0 -auth -retro (Xorg) `-- /bin/sh - ./helper 세션 |--PCDM-세션-한 번 `--PCDM-세션-한 번 | | `-- sh /tmp/PCDM-session.ca1015 |-- /usr/local/bin/gpg-agent … | `--scdaemon --다중 서버 |-- /usr/local/bin/lxsession -s LXDE |-- 오픈박스 --구성 파일... |-- lxpanel --프로필 LXDE |-- pcmanfm --desktop --profile LXDE | `-- xscreensaver - 스플래시 없음 |-- /usr/local/bin/python2.7 /usr/local/share/system-config-printer/applet.py |-- 인명 구조 트레이 |-- /usr/local/bin/pc-systemupdartray |-- 시대정신 데이터 센터 |-- 컴퓨터 믹서 |-- PC 설치 트레이 |-- /usr/local/libexec/menu-cache/menu-cached … |``——썬더버드 |-- dbus-launch --exit-with-session PCDM-세션-한 번 `-- /usr/local/bin/dbus-daemon --fork … --session