DAEMON REPARENTED / INIT --USER

来源:互联网 发布:用户行为数据建模 编辑:程序博客网 时间:2024/05/21 10:55

from: https://www.osso.nl/blog/daemon-reparented-init-user/


While I was battling an obscure Ubuntu shutdown issue — more about that later — I noticed that daemonized jobs started from my X session were not reparented to PID 1 init, but to a custom init --user, owned by me.

What? I cannot start daemon that outlive my X session?

That's right, I cannot. Check this out:

$ sh -c 'sleep 61 &'$ ps faxu | egrep 'init|sleep 61'root         1  ... /sbin/initwalter    2198  ...      \_ init --userwalter    6673  ...          |   |   \_ egrep --color=auto init|sleep 61walter    6671  ...          \_ sleep 61

Okay then. What is this black magic?

It's apparently caused by PR_SET_CHILD_SUBREAPER; available through prctl since Linux kernel 3.4. Ubuntu added that in Raring (13.04), according to Raring Upstart User Sessions, PID tracking.

Can I work around that?

Short answer: no, the PR_SET_CHILD_SUBREAPER interface allows a single process to enable or disable the feature, but not for someone else to disable it.

Long answer: yes, but only if we alter the subreaper state of the User Session init; like this:

$ sudo gdb `which init` `pgrep -xf 'init --user'` \    -batch -ex 'call prctl(36,0,0,0,0)'Password: [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".0x00007f3b7a6848c3 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:8181  ../sysdeps/unix/syscall-template.S: No such file or directory.$1 = 0$ sh -c 'sleep 61 &'$ ps faxu | egrep 'init|sleep 61'root         1  ... /sbin/initwalter    2198  ...      \_ init --userwalter    6986  ...          |   |   \_ egrep --color=auto init|sleep 61walter    6957  ...          |       \_ man 5 initwalter    6984  ... sleep 61

Hah! sleep 61 is now owned by PID 1 directly. By the way, reverting that hack is as easy as changing the second argument to prctl from 0 to 1.

So, apparently I really am barred from creating PID 1 owned daemons unless I hack init --user.

That does raise the question how initctl daemons are spawned, but that's done by asking /sbin/init to do that for us:

# netstat -lnAunix  | grep '/com/ubuntu/upstart$'unix  2      [ ACC ]     STREAM     LISTENING     8049     @/com/ubuntu/upstart# strace start cups...connect(3, {sa_family=AF_LOCAL, sun_path=@"/com/ubuntu/upstart"}, 22) = 0...cups start/running, process 6883
Yuck! Did I mention I'm glad we're moving to systemd?
0 0