1*a06e2ab3SBen Gras$NetBSD: NOTES,v 1.3 2006/04/18 11:40:26 salo Exp $ 2*a06e2ab3SBen Gras 3*a06e2ab3SBen GrasPOSIX and init: 4*a06e2ab3SBen Gras-------------- 5*a06e2ab3SBen Gras 6*a06e2ab3SBen GrasPOSIX.1 does not define 'init' but it mentions it in a few places. 7*a06e2ab3SBen Gras 8*a06e2ab3SBen GrasB.2.2.2, p205 line 873: 9*a06e2ab3SBen Gras 10*a06e2ab3SBen Gras This is part of the extensive 'job control' glossary entry. 11*a06e2ab3SBen Gras This specific reference says that 'init' must by default provide 12*a06e2ab3SBen Gras protection from job control signals to jobs it starts -- 13*a06e2ab3SBen Gras it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN. 14*a06e2ab3SBen Gras 15*a06e2ab3SBen GrasB.2.2.2, p206 line 889: 16*a06e2ab3SBen Gras 17*a06e2ab3SBen Gras Here is a reference to 'vhangup'. It says, 'POSIX.1 does 18*a06e2ab3SBen Gras not specify how controlling terminal access is affected by 19*a06e2ab3SBen Gras a user logging out (that is, by a controlling process 20*a06e2ab3SBen Gras terminating).' vhangup() is recognized as one way to handle 21*a06e2ab3SBen Gras the problem. I'm not clear what happens in Reno; I have 22*a06e2ab3SBen Gras the impression that when the controlling process terminates, 23*a06e2ab3SBen Gras references to the controlling terminal are converted to 24*a06e2ab3SBen Gras references to a 'dead' vnode. I don't know whether vhangup() 25*a06e2ab3SBen Gras is required. 26*a06e2ab3SBen Gras 27*a06e2ab3SBen GrasB.2.2.2, p206 line 921: 28*a06e2ab3SBen Gras 29*a06e2ab3SBen Gras Orphaned process groups bear indirectly on this issue. A 30*a06e2ab3SBen Gras session leader's process group is considered to be orphaned; 31*a06e2ab3SBen Gras that is, it's immune to job control signals from the terminal. 32*a06e2ab3SBen Gras 33*a06e2ab3SBen GrasB.2.2.2, p233 line 2055: 34*a06e2ab3SBen Gras 35*a06e2ab3SBen Gras 'Historically, the implementation-dependent process that 36*a06e2ab3SBen Gras inherits children whose parents have terminated without 37*a06e2ab3SBen Gras waiting on them is called "init" and has a process ID of 1.' 38*a06e2ab3SBen Gras 39*a06e2ab3SBen Gras It goes on to note that it used to be the case that 'init' 40*a06e2ab3SBen Gras was responsible for sending SIGHUP to the foreground process 41*a06e2ab3SBen Gras group of a tty whose controlling process has exited, using 42*a06e2ab3SBen Gras vhangup(). It is now the responsibility of the kernel to 43*a06e2ab3SBen Gras do this when the controlling process calls _exit(). The 44*a06e2ab3SBen Gras kernel is also responsible for sending SIGCONT to stopped 45*a06e2ab3SBen Gras process groups that become orphaned. This is like old BSD 46*a06e2ab3SBen Gras but entire process groups are signaled instead of individual 47*a06e2ab3SBen Gras processes. 48*a06e2ab3SBen Gras 49*a06e2ab3SBen Gras In general it appears that the kernel now automatically 50*a06e2ab3SBen Gras takes care of orphans, relieving 'init' of any responsibility. 51*a06e2ab3SBen Gras Specifics are listed on the _exit() page (p50). 52*a06e2ab3SBen Gras 53*a06e2ab3SBen GrasOn setsid(): 54*a06e2ab3SBen Gras----------- 55*a06e2ab3SBen Gras 56*a06e2ab3SBen GrasIt appears that neither getty nor login call setsid(), so init must 57*a06e2ab3SBen Grasdo this -- seems reasonable. B.4.3.2 p 248 implies that this is the 58*a06e2ab3SBen Grasway that 'init' should work; it says that setsid() should be called 59*a06e2ab3SBen Grasafter forking. 60*a06e2ab3SBen Gras 61*a06e2ab3SBen GrasProcess group leaders cannot call setsid() -- another reason to 62*a06e2ab3SBen Grasfork! Of course setsid() causes the current process to become a 63*a06e2ab3SBen Grasprocess group leader, so we can only call setsid() once. Note that 64*a06e2ab3SBen Grasthe controlling terminal acquires the session leader's process 65*a06e2ab3SBen Grasgroup when opened. 66*a06e2ab3SBen Gras 67*a06e2ab3SBen GrasControlling terminals: 68*a06e2ab3SBen Gras--------------------- 69*a06e2ab3SBen Gras 70*a06e2ab3SBen GrasB.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to 71*a06e2ab3SBen Grasallocate a controlling terminal. This is normally done by a system 72*a06e2ab3SBen Grasutility (such as 'getty') and is considered ... outside the scope 73*a06e2ab3SBen Grasof POSIX.1.' It goes on to say that historically the first open() 74*a06e2ab3SBen Grasof a tty in a session sets the controlling terminal. P130 has the 75*a06e2ab3SBen Grasfull details; nothing particularly surprising. 76*a06e2ab3SBen Gras 77*a06e2ab3SBen GrasThe glossary p12 describes a 'controlling process' as the first 78*a06e2ab3SBen Grasprocess in a session that acquires a controlling terminal. Access 79*a06e2ab3SBen Grasto the terminal from the session is revoked if the controlling 80*a06e2ab3SBen Grasprocess exits (see p50, in the discussion of process termination). 81*a06e2ab3SBen Gras 82*a06e2ab3SBen GrasDesign notes: 83*a06e2ab3SBen Gras------------ 84*a06e2ab3SBen Gras 85*a06e2ab3SBen Grasyour generic finite state machine 86*a06e2ab3SBen Graswe are fascist about which signals we elect to receive, 87*a06e2ab3SBen Gras even signals purportedly generated by hardware 88*a06e2ab3SBen Grashandle fatal errors gracefully if possible (we reboot if we goof!!) 89*a06e2ab3SBen Gras if we get a segmentation fault etc., print a message on the console 90*a06e2ab3SBen Gras and spin for a while before rebooting 91*a06e2ab3SBen Gras (this at least decreases the amount of paper consumed :-) 92*a06e2ab3SBen Grasapply hysteresis to rapidly exiting gettys 93*a06e2ab3SBen Grascheck wait status of children we reap 94*a06e2ab3SBen Gras don't wait for stopped children 95*a06e2ab3SBen Grasdon't use SIGCHILD, it's too expensive 96*a06e2ab3SBen Gras but it may close windows and avoid races, sigh 97*a06e2ab3SBen Graslook for EINTR in case we need to change state 98*a06e2ab3SBen Grasinit is responsible for utmp and wtmp maintenance (ick) 99*a06e2ab3SBen Gras maybe now we can consider replacements? maintain them in parallel 100*a06e2ab3SBen Gras init only removes utmp and closes out wtmp entries... 101*a06e2ab3SBen Gras 102*a06e2ab3SBen Grasnecessary states and state transitions (gleaned from the man page): 103*a06e2ab3SBen Gras 1: single user shell (with password checking?); on exit, go to 2 104*a06e2ab3SBen Gras 2: run rc script, on exit 0 check if init.root sysctl != "/", if it 105*a06e2ab3SBen Gras differs then fork + chroot into the value of init.root and run 106*a06e2ab3SBen Gras /etc/rc inside the chroot: on exit 0, go to 3; on exit N (error), 107*a06e2ab3SBen Gras go to 1 (applies also to /etc/rc when init.root == "/") 108*a06e2ab3SBen Gras 3: read ttys file: on completion, go to 4. If we did chroot in 109*a06e2ab3SBen Gras state 2, we chroot after forking each getty to the same dir 110*a06e2ab3SBen Gras (init.root is not re-read) 111*a06e2ab3SBen Gras 4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5; 112*a06e2ab3SBen Gras on SIGTSTP, go to 6 113*a06e2ab3SBen Gras 5: clean up mode (re-read ttys file, killing off controlling processes 114*a06e2ab3SBen Gras on lines that are now 'off', starting them on lines newly 'on') 115*a06e2ab3SBen Gras on completion, go to 4 116*a06e2ab3SBen Gras 6: boring mode (no new sessions); signals as in 4 117*a06e2ab3SBen Gras 7: death: send SIGHUP to all controlling processes, reap for 30 seconds, 118*a06e2ab3SBen Gras then go to 1 (warn if not all processes died, i.e. wait blocks) 119*a06e2ab3SBen GrasGiven the -s flag, we start at state 1; otherwise state 2 120