11.3Ssalo$NetBSD: NOTES,v 1.3 2006/04/18 11:40:26 salo Exp $ 21.2Scgd 31.1SpkPOSIX and init: 41.1Spk-------------- 51.1Spk 61.1SpkPOSIX.1 does not define 'init' but it mentions it in a few places. 71.1Spk 81.1SpkB.2.2.2, p205 line 873: 91.1Spk 101.1Spk This is part of the extensive 'job control' glossary entry. 111.1Spk This specific reference says that 'init' must by default provide 121.1Spk protection from job control signals to jobs it starts -- 131.1Spk it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN. 141.1Spk 151.1SpkB.2.2.2, p206 line 889: 161.1Spk 171.1Spk Here is a reference to 'vhangup'. It says, 'POSIX.1 does 181.1Spk not specify how controlling terminal access is affected by 191.1Spk a user logging out (that is, by a controlling process 201.1Spk terminating).' vhangup() is recognized as one way to handle 211.1Spk the problem. I'm not clear what happens in Reno; I have 221.1Spk the impression that when the controlling process terminates, 231.1Spk references to the controlling terminal are converted to 241.1Spk references to a 'dead' vnode. I don't know whether vhangup() 251.1Spk is required. 261.1Spk 271.1SpkB.2.2.2, p206 line 921: 281.1Spk 291.1Spk Orphaned process groups bear indirectly on this issue. A 301.1Spk session leader's process group is considered to be orphaned; 311.1Spk that is, it's immune to job control signals from the terminal. 321.1Spk 331.1SpkB.2.2.2, p233 line 2055: 341.1Spk 351.1Spk 'Historically, the implementation-dependent process that 361.1Spk inherits children whose parents have terminated without 371.1Spk waiting on them is called "init" and has a process ID of 1.' 381.1Spk 391.1Spk It goes on to note that it used to be the case that 'init' 401.1Spk was responsible for sending SIGHUP to the foreground process 411.1Spk group of a tty whose controlling process has exited, using 421.1Spk vhangup(). It is now the responsibility of the kernel to 431.1Spk do this when the controlling process calls _exit(). The 441.1Spk kernel is also responsible for sending SIGCONT to stopped 451.1Spk process groups that become orphaned. This is like old BSD 461.1Spk but entire process groups are signaled instead of individual 471.1Spk processes. 481.1Spk 491.1Spk In general it appears that the kernel now automatically 501.1Spk takes care of orphans, relieving 'init' of any responsibility. 511.1Spk Specifics are listed on the _exit() page (p50). 521.1Spk 531.1SpkOn setsid(): 541.1Spk----------- 551.1Spk 561.1SpkIt appears that neither getty nor login call setsid(), so init must 571.1Spkdo this -- seems reasonable. B.4.3.2 p 248 implies that this is the 581.1Spkway that 'init' should work; it says that setsid() should be called 591.1Spkafter forking. 601.1Spk 611.1SpkProcess group leaders cannot call setsid() -- another reason to 621.1Spkfork! Of course setsid() causes the current process to become a 631.1Spkprocess group leader, so we can only call setsid() once. Note that 641.1Spkthe controlling terminal acquires the session leader's process 651.1Spkgroup when opened. 661.1Spk 671.1SpkControlling terminals: 681.1Spk--------------------- 691.1Spk 701.1SpkB.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to 711.1Spkallocate a controlling terminal. This is normally done by a system 721.1Spkutility (such as 'getty') and is considered ... outside the scope 731.1Spkof POSIX.1.' It goes on to say that historically the first open() 741.1Spkof a tty in a session sets the controlling terminal. P130 has the 751.1Spkfull details; nothing particularly surprising. 761.1Spk 771.1SpkThe glossary p12 describes a 'controlling process' as the first 781.1Spkprocess in a session that acquires a controlling terminal. Access 791.1Spkto the terminal from the session is revoked if the controlling 801.1Spkprocess exits (see p50, in the discussion of process termination). 811.1Spk 821.1SpkDesign notes: 831.1Spk------------ 841.1Spk 851.1Spkyour generic finite state machine 861.1Spkwe are fascist about which signals we elect to receive, 871.1Spk even signals purportedly generated by hardware 881.1Spkhandle fatal errors gracefully if possible (we reboot if we goof!!) 891.1Spk if we get a segmentation fault etc., print a message on the console 901.1Spk and spin for a while before rebooting 911.1Spk (this at least decreases the amount of paper consumed :-) 921.1Spkapply hysteresis to rapidly exiting gettys 931.1Spkcheck wait status of children we reap 941.1Spk don't wait for stopped children 951.1Spkdon't use SIGCHILD, it's too expensive 961.1Spk but it may close windows and avoid races, sigh 971.1Spklook for EINTR in case we need to change state 981.1Spkinit is responsible for utmp and wtmp maintenance (ick) 991.1Spk maybe now we can consider replacements? maintain them in parallel 1001.1Spk init only removes utmp and closes out wtmp entries... 1011.1Spk 1021.1Spknecessary states and state transitions (gleaned from the man page): 1031.1Spk 1: single user shell (with password checking?); on exit, go to 2 1041.3Ssalo 2: run rc script, on exit 0 check if init.root sysctl != "/", if it 1051.3Ssalo differs then fork + chroot into the value of init.root and run 1061.3Ssalo /etc/rc inside the chroot: on exit 0, go to 3; on exit N (error), 1071.3Ssalo go to 1 (applies also to /etc/rc when init.root == "/") 1081.3Ssalo 3: read ttys file: on completion, go to 4. If we did chroot in 1091.3Ssalo state 2, we chroot after forking each getty to the same dir 1101.3Ssalo (init.root is not re-read) 1111.1Spk 4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5; 1121.1Spk on SIGTSTP, go to 6 1131.1Spk 5: clean up mode (re-read ttys file, killing off controlling processes 1141.1Spk on lines that are now 'off', starting them on lines newly 'on') 1151.1Spk on completion, go to 4 1161.1Spk 6: boring mode (no new sessions); signals as in 4 1171.1Spk 7: death: send SIGHUP to all controlling processes, reap for 30 seconds, 1181.1Spk then go to 1 (warn if not all processes died, i.e. wait blocks) 1191.1SpkGiven the -s flag, we start at state 1; otherwise state 2 120