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