Merge illumos-gate
[unleashed.git] / usr / src / cmd / init / init.c
blob8f261b64c5551af2617dad11dacc15d9942ed35b
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2013 Gary Mills
25 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
42 * init(8) is the general process spawning program. Its primary job is to
43 * start and restart svc.startd for smf(5). For backwards-compatibility it also
44 * spawns and respawns processes according to /etc/inittab and the current
45 * run-level. It reads /etc/default/inittab for general configuration.
47 * To change run-levels the system administrator runs init from the command
48 * line with a level name. init signals svc.startd via libscf and directs the
49 * zone's init (pid 1 in the global zone) what to do by sending it a signal;
50 * these signal numbers are commonly refered to in the code as 'states'. Valid
51 * run-levels are [sS0123456]. Additionally, init can be given directives
52 * [qQabc], which indicate actions to be taken pertaining to /etc/inittab.
54 * When init processes inittab entries, it finds processes that are to be
55 * spawned at various run-levels. inittab contains the set of the levels for
56 * which each inittab entry is valid.
58 * State File and Restartability
59 * Premature exit by init(8) is handled as a special case by the kernel:
60 * init(8) will be immediately re-executed, retaining its original PID. (PID
61 * 1 in the global zone.) To track the processes it has previously spawned,
62 * as well as other mutable state, init(8) regularly updates a state file
63 * such that its subsequent invocations have knowledge of its various
64 * dependent processes and duties.
66 * Process Contracts
67 * We start svc.startd(8) in a contract and transfer inherited contracts when
68 * restarting it. Everything else is started using the legacy contract
69 * template, and the created contracts are abandoned when they become empty.
71 * utmpx Entry Handling
72 * Because init(8) no longer governs the startup process, its knowledge of
73 * when utmpx becomes writable is indirect. However, spawned processes
74 * expect to be constructed with valid utmpx entries. As a result, attempts
75 * to write normal entries will be retried until successful.
77 * Maintenance Mode
78 * In certain failure scenarios, init(8) will enter a maintenance mode, in
79 * which it invokes sulogin(8) to allow the operator an opportunity to
80 * repair the system. Normally, this operation is performed as a
81 * fork(2)-exec(2)-waitpid(3C) sequence with the parent waiting for repair or
82 * diagnosis to be completed. In the cases that fork(2) requests themselves
83 * fail, init(8) will directly execute sulogin(8), and allow the kernel to
84 * restart init(8) on exit from the operator session.
86 * One scenario where init(8) enters its maintenance mode is when
87 * svc.startd(8) begins to fail rapidly, defined as when the average time
88 * between recent failures drops below a given threshold.
91 #include <sys/contract/process.h>
92 #include <sys/ctfs.h>
93 #include <sys/stat.h>
94 #include <sys/statvfs.h>
95 #include <sys/stropts.h>
96 #include <sys/systeminfo.h>
97 #include <sys/time.h>
98 #include <sys/termios.h>
99 #include <sys/tty.h>
100 #include <sys/types.h>
101 #include <sys/utsname.h>
103 #include <security/pam_appl.h>
105 #include <assert.h>
106 #include <ctype.h>
107 #include <dirent.h>
108 #include <errno.h>
109 #include <fcntl.h>
110 #include <libcontract.h>
111 #include <libcontract_priv.h>
112 #include <libintl.h>
113 #include <libscf.h>
114 #include <libscf_priv.h>
115 #include <poll.h>
116 #include <procfs.h>
117 #include <signal.h>
118 #include <stdarg.h>
119 #include <stdio.h>
120 #include <stdio_ext.h>
121 #include <stdlib.h>
122 #include <string.h>
123 #include <strings.h>
124 #include <syslog.h>
125 #include <time.h>
126 #include <ulimit.h>
127 #include <unistd.h>
128 #include <utmpx.h>
129 #include <wait.h>
130 #include <zone.h>
131 #include <ucontext.h>
133 #undef sleep
135 #define fioctl(p, sptr, cmd) ioctl(fileno(p), sptr, cmd)
136 #define min(a, b) (((a) < (b)) ? (a) : (b))
138 #define TRUE 1
139 #define FALSE 0
140 #define FAILURE -1
142 #define UT_USER_SZ 32 /* Size of a utmpx ut_user field */
143 #define UT_LINE_SZ 32 /* Size of a utmpx ut_line field */
146 * SLEEPTIME The number of seconds "init" sleeps between wakeups if
147 * nothing else requires this "init" wakeup.
149 #define SLEEPTIME (5 * 60)
152 * MAXCMDL The maximum length of a command string in inittab.
154 #define MAXCMDL 512
157 * EXEC The length of the prefix string added to all comamnds
158 * found in inittab.
160 #define EXEC (sizeof ("exec ") - 1)
163 * TWARN The amount of time between warning signal, SIGTERM,
164 * and the fatal kill signal, SIGKILL.
166 #define TWARN 5
168 #define id_eq(x, y) ((x[0] == y[0] && x[1] == y[1] && x[2] == y[2] &&\
169 x[3] == y[3]) ? TRUE : FALSE)
172 * The kernel's default umask is 022 these days; since some processes inherit
173 * their umask from init, init will set it from CMASK in /etc/default/init.
174 * init gets the default umask from the kernel, it sets it to 022 whenever
175 * it wants to create a file and reverts to CMASK afterwards.
178 static int cmask;
181 * The following definitions, concluding with the 'lvls' array, provide a
182 * common mapping between level-name (like 'S'), signal number (state),
183 * run-level mask, and specific properties associated with a run-level.
184 * This array should be accessed using the routines lvlname_to_state(),
185 * lvlname_to_mask(), state_to_mask(), and state_to_flags().
189 * Correspondence of signals to init actions.
191 #define LVLQ SIGHUP
192 #define LVL0 SIGINT
193 #define LVL1 SIGQUIT
194 #define LVL2 SIGILL
195 #define LVL3 SIGTRAP
196 #define LVL4 SIGIOT
197 #define LVL5 SIGEMT
198 #define LVL6 SIGFPE
199 #define SINGLE_USER SIGBUS
200 #define LVLa SIGSEGV
201 #define LVLb SIGSYS
202 #define LVLc SIGPIPE
205 * Bit Mask for each level. Used to determine legal levels.
207 #define MASK0 0x0001
208 #define MASK1 0x0002
209 #define MASK2 0x0004
210 #define MASK3 0x0008
211 #define MASK4 0x0010
212 #define MASK5 0x0020
213 #define MASK6 0x0040
214 #define MASKSU 0x0080
215 #define MASKa 0x0100
216 #define MASKb 0x0200
217 #define MASKc 0x0400
219 #define MASK_NUMERIC (MASK0 | MASK1 | MASK2 | MASK3 | MASK4 | MASK5 | MASK6)
220 #define MASK_abc (MASKa | MASKb | MASKc)
223 * Flags to indicate properties of various states.
225 #define LSEL_RUNLEVEL 0x0001 /* runlevels you can transition to */
227 typedef struct lvl {
228 int lvl_state;
229 int lvl_mask;
230 char lvl_name;
231 int lvl_flags;
232 } lvl_t;
234 static lvl_t lvls[] = {
235 { LVLQ, 0, 'Q', 0 },
236 { LVLQ, 0, 'q', 0 },
237 { LVL0, MASK0, '0', LSEL_RUNLEVEL },
238 { LVL1, MASK1, '1', LSEL_RUNLEVEL },
239 { LVL2, MASK2, '2', LSEL_RUNLEVEL },
240 { LVL3, MASK3, '3', LSEL_RUNLEVEL },
241 { LVL4, MASK4, '4', LSEL_RUNLEVEL },
242 { LVL5, MASK5, '5', LSEL_RUNLEVEL },
243 { LVL6, MASK6, '6', LSEL_RUNLEVEL },
244 { SINGLE_USER, MASKSU, 'S', LSEL_RUNLEVEL },
245 { SINGLE_USER, MASKSU, 's', LSEL_RUNLEVEL },
246 { LVLa, MASKa, 'a', 0 },
247 { LVLb, MASKb, 'b', 0 },
248 { LVLc, MASKc, 'c', 0 }
251 #define LVL_NELEMS (sizeof (lvls) / sizeof (lvl_t))
254 * Legal action field values.
256 #define OFF 0 /* Kill process if on, else ignore */
257 #define RESPAWN 1 /* Continuously restart process when it dies */
258 #define ONDEMAND RESPAWN /* Respawn for a, b, c type processes */
259 #define ONCE 2 /* Start process, do not respawn when dead */
260 #define WAIT 3 /* Perform once and wait to complete */
261 #define BOOT 4 /* Start at boot time only */
262 #define BOOTWAIT 5 /* Start at boot time and wait to complete */
263 #define POWERFAIL 6 /* Start on powerfail */
264 #define POWERWAIT 7 /* Start and wait for complete on powerfail */
265 #define INITDEFAULT 8 /* Default level "init" should start at */
266 #define SYSINIT 9 /* Actions performed before init speaks */
268 #define M_OFF 0001
269 #define M_RESPAWN 0002
270 #define M_ONDEMAND M_RESPAWN
271 #define M_ONCE 0004
272 #define M_WAIT 0010
273 #define M_BOOT 0020
274 #define M_BOOTWAIT 0040
275 #define M_PF 0100
276 #define M_PWAIT 0200
277 #define M_INITDEFAULT 0400
278 #define M_SYSINIT 01000
280 /* States for the inittab parser in getcmd(). */
281 #define ID 1
282 #define LEVELS 2
283 #define ACTION 3
284 #define COMMAND 4
285 #define COMMENT 5
288 * inittab entry id constants
290 #define INITTAB_ENTRY_ID_SIZE 4
291 #define INITTAB_ENTRY_ID_STR_FORMAT "%.4s" /* if INITTAB_ENTRY_ID_SIZE */
292 /* changes, this should */
293 /* change accordingly */
296 * Init can be in any of three main states, "normal" mode where it is
297 * processing entries for the lines file in a normal fashion, "boot" mode,
298 * where it is only interested in the boot actions, and "powerfail" mode,
299 * where it is only interested in powerfail related actions. The following
300 * masks declare the legal actions for each mode.
302 #define NORMAL_MODES (M_OFF | M_RESPAWN | M_ONCE | M_WAIT)
303 #define BOOT_MODES (M_BOOT | M_BOOTWAIT)
304 #define PF_MODES (M_PF | M_PWAIT)
306 struct PROC_TABLE {
307 char p_id[INITTAB_ENTRY_ID_SIZE]; /* Four letter unique id of */
308 /* process */
309 pid_t p_pid; /* Process id */
310 short p_count; /* How many respawns of this command in */
311 /* the current series */
312 long p_time; /* Start time for a series of respawns */
313 short p_flags;
314 short p_exit; /* Exit status of a process which died */
318 * Flags for the "p_flags" word of a PROC_TABLE entry:
320 * OCCUPIED This slot in init's proc table is in use.
322 * LIVING Process is alive.
324 * NOCLEANUP efork() is not allowed to cleanup this entry even
325 * if process is dead.
327 * NAMED This process has a name, i.e. came from inittab.
329 * DEMANDREQUEST Process started by a "telinit [abc]" command. Processes
330 * formed this way are respawnable and immune to level
331 * changes as long as their entry exists in inittab.
333 * TOUCHED Flag used by remv() to determine whether it has looked
334 * at an entry while checking for processes to be killed.
336 * WARNED Flag used by remv() to mark processes that have been
337 * sent the SIGTERM signal. If they don't die in 5
338 * seconds, they are sent the SIGKILL signal.
340 * KILLED Flag used by remv() to mark procs that have been sent
341 * the SIGTERM and SIGKILL signals.
343 * PF_MASK Bitwise or of legal flags, for sanity checking.
345 #define OCCUPIED 01
346 #define LIVING 02
347 #define NOCLEANUP 04
348 #define NAMED 010
349 #define DEMANDREQUEST 020
350 #define TOUCHED 040
351 #define WARNED 0100
352 #define KILLED 0200
353 #define PF_MASK 0377
356 * Respawn limits for processes that are to be respawned:
358 * SPAWN_INTERVAL The number of seconds over which "init" will try to
359 * respawn a process SPAWN_LIMIT times before it gets mad.
361 * SPAWN_LIMIT The number of respawns "init" will attempt in
362 * SPAWN_INTERVAL seconds before it generates an
363 * error message and inhibits further tries for
364 * INHIBIT seconds.
366 * INHIBIT The number of seconds "init" ignores an entry it had
367 * trouble spawning unless a "telinit Q" is received.
370 #define SPAWN_INTERVAL (2*60)
371 #define SPAWN_LIMIT 10
372 #define INHIBIT (5*60)
375 * The maximum number of decimal digits for an id_t. (ceil(log10 (max_id)))
377 #define ID_MAX_STR_LEN 10
379 #define NULLPROC ((struct PROC_TABLE *)(0))
380 #define NO_ROOM ((struct PROC_TABLE *)(FAILURE))
382 struct CMD_LINE {
383 char c_id[INITTAB_ENTRY_ID_SIZE]; /* Four letter unique id of */
384 /* process to be affected by */
385 /* action */
386 short c_levels; /* Mask of legal levels for process */
387 short c_action; /* Mask for type of action required */
388 char *c_command; /* Pointer to init command */
391 struct pidrec {
392 int pd_type; /* Command type */
393 pid_t pd_pid; /* pid to add or remove */
397 * pd_type's
399 #define ADDPID 1
400 #define REMPID 2
402 static struct pidlist {
403 pid_t pl_pid; /* pid to watch for */
404 int pl_dflag; /* Flag indicating SIGCLD from this pid */
405 short pl_exit; /* Exit status of proc */
406 struct pidlist *pl_next; /* Next in list */
407 } *Plhead, *Plfree;
410 * The following structure contains a set of modes for /dev/syscon
411 * and should match the default contents of /etc/ioctl.syscon.
413 static struct termios dflt_termios = {
414 .c_iflag = BRKINT|ICRNL|IXON|IMAXBEL,
415 .c_oflag = OPOST|ONLCR|TAB3,
416 .c_cflag = CS8|CREAD|B9600,
417 .c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN,
418 .c_cc = { CINTR, CQUIT, CERASE, CKILL, CEOF, 0, 0, 0,
419 CSTART, CSTOP, CSWTCH, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT,
420 CSTATUS, CERASE2, 0
424 static struct termios stored_syscon_termios;
425 static int write_ioctl = 0; /* Rewrite /etc/ioctl.syscon */
427 static union WAKEUP {
428 struct WAKEFLAGS {
429 unsigned w_usersignal : 1; /* User sent signal to "init" */
430 unsigned w_childdeath : 1; /* An "init" child died */
431 unsigned w_powerhit : 1; /* OS experienced powerfail */
432 } w_flags;
433 int w_mask;
434 } wakeup;
437 struct init_state {
438 int ist_runlevel;
439 int ist_num_proc;
440 int ist_utmpx_ok;
441 struct PROC_TABLE ist_proc_table[1];
444 #define cur_state (g_state->ist_runlevel)
445 #define num_proc (g_state->ist_num_proc)
446 #define proc_table (g_state->ist_proc_table)
447 #define utmpx_ok (g_state->ist_utmpx_ok)
449 /* Contract cookies. */
450 #define ORDINARY_COOKIE 0
451 #define STARTD_COOKIE 1
454 #ifndef NDEBUG
455 #define bad_error(func, err) { \
456 (void) fprintf(stderr, "%s:%d: %s() failed with unexpected " \
457 "error %d. Aborting.\n", __FILE__, __LINE__, (func), (err)); \
458 abort(); \
460 #else
461 #define bad_error(func, err) abort()
462 #endif
466 * Useful file and device names.
468 static char *CONSOLE = "/dev/console"; /* Real system console */
469 static char *INITPIPE_DIR = "/var/run";
470 static char *INITPIPE = "/var/run/initpipe";
472 #define INIT_STATE_DIR "/etc/svc/volatile"
473 static const char * const init_state_file = INIT_STATE_DIR "/init.state";
474 static const char * const init_next_state_file =
475 INIT_STATE_DIR "/init-next.state";
477 static const int init_num_proc = 20; /* Initial size of process table. */
479 static char *UTMPX = UTMPX_FILE; /* Snapshot record file */
480 static char *WTMPX = WTMPX_FILE; /* Long term record file */
481 static char *INITTAB = "/etc/inittab"; /* Script file for "init" */
482 static char *SYSTTY = "/dev/systty"; /* System Console */
483 static char *SYSCON = "/dev/syscon"; /* Virtual System console */
484 static char *IOCTLSYSCON = "/etc/ioctl.syscon"; /* Last syscon modes */
485 static char *ENVFILE = "/etc/default/init"; /* Default env. */
486 static char *SU = "/etc/sulogin"; /* Super-user program for single user */
487 static char *SH = "/bin/sh"; /* Standard shell */
490 * Default Path. /sbin is included in path only during sysinit phase
492 #define DEF_PATH "PATH=/usr/sbin:/usr/bin"
493 #define INIT_PATH "PATH=/sbin:/usr/sbin:/usr/bin"
495 static int prior_state;
496 static int prev_state; /* State "init" was in last time it woke */
497 static int new_state; /* State user wants "init" to go to. */
498 static int lvlq_received; /* Explicit request to examine state */
499 static int op_modes = BOOT_MODES; /* Current state of "init" */
500 static int Gchild = 0; /* Flag to indicate "godchild" died, set in */
501 /* childeath() and cleared in cleanaux() */
502 static int Pfd = -1; /* fd to receive pids thru */
503 static unsigned int spawncnt, pausecnt;
504 static int rsflag; /* Set if a respawn has taken place */
505 static volatile int time_up; /* Flag set to TRUE by the alarm interrupt */
506 /* routine each time an alarm interrupt */
507 /* takes place. */
508 static int sflg = 0; /* Set if we were booted -s to single user */
509 static int rflg = 0; /* Set if booted -r, reconfigure devices */
510 static int bflg = 0; /* Set if booted -b, don't run rc scripts */
511 static pid_t init_pid; /* PID of "one true" init for current zone */
513 static struct init_state *g_state = NULL;
514 static size_t g_state_sz;
515 static int booting = 1; /* Set while we're booting. */
518 * Array for default global environment.
520 #define MAXENVENT 24 /* Max number of default env variables + 1 */
521 /* init can use three itself, so this leaves */
522 /* 20 for the administrator in ENVFILE. */
523 static char *glob_envp[MAXENVENT]; /* Array of environment strings */
524 static int glob_envn; /* Number of environment strings */
527 static struct pollfd poll_fds[1];
528 static int poll_nfds = 0; /* poll_fds is uninitialized */
531 * Contracts constants
533 #define SVC_INIT_PREFIX "init:/"
534 #define SVC_AUX_SIZE (INITTAB_ENTRY_ID_SIZE + 1)
535 #define SVC_FMRI_SIZE (sizeof (SVC_INIT_PREFIX) + INITTAB_ENTRY_ID_SIZE)
537 static int legacy_tmpl = -1; /* fd for legacy contract template */
538 static int startd_tmpl = -1; /* fd for svc.startd's template */
539 static char startd_svc_aux[SVC_AUX_SIZE];
541 static char startd_cline[256] = ""; /* svc.startd's command line */
542 static int do_restart_startd = 1; /* Whether to restart svc.startd. */
543 static char *smf_options = NULL; /* Options to give to startd. */
544 static int smf_debug = 0; /* Messages for debugging smf(5) */
545 static time_t init_boot_time; /* Substitute for kernel boot time. */
547 #define NSTARTD_FAILURE_TIMES 3 /* trigger after 3 failures */
548 #define STARTD_FAILURE_RATE_NS 5000000000LL /* 1 failure/5 seconds */
550 static hrtime_t startd_failure_time[NSTARTD_FAILURE_TIMES];
551 static uint_t startd_failure_index;
554 static char *prog_name(char *);
555 static int state_to_mask(int);
556 static int lvlname_to_mask(char, int *);
557 static void lscf_set_runlevel(char);
558 static int state_to_flags(int);
559 static char state_to_name(int);
560 static int lvlname_to_state(char);
561 static int getcmd(struct CMD_LINE *, char *);
562 static int realcon();
563 static int spawn_processes();
564 static int get_ioctl_syscon();
565 static int account(short, struct PROC_TABLE *, char *);
566 static void alarmclk();
567 static void childeath(int);
568 static void cleanaux();
569 static void clearent(pid_t, short);
570 static void console(boolean_t, char *, ...);
571 static void init_signals(void);
572 static void setup_pipe();
573 static void killproc(pid_t);
574 static void init_env();
575 static void boot_init();
576 static void powerfail();
577 static void remv();
578 static void write_ioctl_syscon();
579 static void spawn(struct PROC_TABLE *, struct CMD_LINE *);
580 static void setimer(int);
581 static void siglvl(int, siginfo_t *, ucontext_t *);
582 static void sigpoll(int);
583 static void enter_maintenance(void);
584 static void timer(int);
585 static void userinit(int, char **);
586 static void notify_pam_dead(struct utmpx *);
587 static long waitproc(struct PROC_TABLE *);
588 static struct PROC_TABLE *efork(int, struct PROC_TABLE *, int);
589 static struct PROC_TABLE *findpslot(struct CMD_LINE *);
590 static void increase_proc_table_size();
591 static void st_init();
592 static void st_write();
593 static void contracts_init();
594 static void contract_event(struct pollfd *);
595 static int startd_run(const char *, int, ctid_t);
596 static void startd_record_failure();
597 static int startd_failure_rate_critical();
598 static void update_boot_archive(int new_state);
601 main(int argc, char *argv[])
603 int chg_lvl_flag = FALSE, print_banner = FALSE;
604 int c;
605 char *msg;
607 /* Get a timestamp for use as boot time, if needed. */
608 (void) time(&init_boot_time);
610 /* Get the default umask */
611 cmask = umask(022);
612 (void) umask(cmask);
614 /* Parse the arguments to init. Check for single user */
615 opterr = 0;
616 while ((c = getopt(argc, argv, "brsm:")) != EOF) {
617 switch (c) {
618 case 'b':
619 rflg = 0;
620 bflg = 1;
621 if (!sflg)
622 sflg++;
623 break;
624 case 'r':
625 bflg = 0;
626 rflg++;
627 break;
628 case 's':
629 if (!bflg)
630 sflg++;
631 break;
632 case 'm':
633 smf_options = optarg;
634 smf_debug = (strstr(smf_options, "debug") != NULL);
635 break;
640 * Determine if we are the main init, or a user invoked init, whose job
641 * it is to inform init to change levels or perform some other action.
643 if (zone_getattr(getzoneid(), ZONE_ATTR_INITPID, &init_pid,
644 sizeof (init_pid)) != sizeof (init_pid)) {
645 (void) fprintf(stderr, "could not get pid for init\n");
646 return (1);
650 * If this PID is not the same as the "true" init for the zone, then we
651 * must be in 'user' mode.
653 if (getpid() != init_pid) {
654 userinit(argc, argv);
657 if (getzoneid() != GLOBAL_ZONEID) {
658 print_banner = TRUE;
662 * Initialize state (and set "booting").
664 st_init();
666 if (booting && print_banner) {
667 struct utsname un;
668 char buf[BUFSIZ], *isa;
669 long ret;
670 int bits = 32;
673 * We want to print the boot banner as soon as
674 * possible. In the global zone, the kernel does it,
675 * but we do not have that luxury in non-global zones,
676 * so we will print it here.
678 (void) uname(&un);
679 ret = sysinfo(SI_ISALIST, buf, sizeof (buf));
680 if (ret != -1L && ret <= sizeof (buf)) {
681 for (isa = strtok(buf, " "); isa;
682 isa = strtok(NULL, " ")) {
683 if (strcmp(isa, "sparcv9") == 0 ||
684 strcmp(isa, "amd64") == 0) {
685 bits = 64;
686 break;
691 console(B_FALSE,
692 "\n\n%s Release %s Version %s %d-bit\r\n",
693 un.sysname, un.release, un.version, bits);
694 console(B_FALSE,
695 "Copyright (c) 1983, 2010, Oracle and/or its affiliates."
696 " All rights reserved.\r\n");
700 * Get the ioctl settings for /dev/syscon from /etc/ioctl.syscon
701 * so that it can be brought up in the state it was in when the
702 * system went down; or set to defaults if ioctl.syscon isn't
703 * valid.
705 * This needs to be done even if we're restarting so reset_modes()
706 * will work in case we need to go down to single user mode.
708 write_ioctl = get_ioctl_syscon();
711 * Set up all signals to be caught or ignored as appropriate.
713 init_signals();
715 /* Load glob_envp from ENVFILE. */
716 init_env();
718 contracts_init();
720 if (!booting) {
721 /* cur_state should have been read in. */
723 op_modes = NORMAL_MODES;
725 /* Rewrite the ioctl file if it was bad. */
726 if (write_ioctl)
727 write_ioctl_syscon();
728 } else {
730 * It's fine to boot up with state as zero, because
731 * startd will later tell us the real state.
733 cur_state = 0;
734 op_modes = BOOT_MODES;
736 boot_init();
739 prev_state = prior_state = cur_state;
741 setup_pipe();
744 * Here is the beginning of the main process loop.
746 for (;;) {
747 if (lvlq_received) {
748 setup_pipe();
749 lvlq_received = B_FALSE;
753 * Clean up any accounting records for dead "godchildren".
755 if (Gchild)
756 cleanaux();
759 * If in "normal" mode, check all living processes and initiate
760 * kill sequence on those that should not be there anymore.
762 if (op_modes == NORMAL_MODES && cur_state != LVLa &&
763 cur_state != LVLb && cur_state != LVLc)
764 remv();
767 * If a change in run levels is the reason we awoke, now do
768 * the accounting to report the change in the utmp file.
769 * Also report the change on the system console.
771 if (chg_lvl_flag) {
772 chg_lvl_flag = FALSE;
774 if (state_to_flags(cur_state) & LSEL_RUNLEVEL) {
775 char rl = state_to_name(cur_state);
777 if (rl != -1)
778 lscf_set_runlevel(rl);
783 * Scan the inittab file and spawn and respawn processes that
784 * should be alive in the current state. If inittab does not
785 * exist default to single user mode.
787 if (spawn_processes() == FAILURE) {
788 prior_state = prev_state;
789 cur_state = SINGLE_USER;
792 /* If any respawns occurred, take note. */
793 if (rsflag) {
794 rsflag = 0;
795 spawncnt++;
799 * If a powerfail signal was received during the last
800 * sequence, set mode to powerfail. When spawn_processes() is
801 * entered the first thing it does is to check "powerhit". If
802 * it is in PF_MODES then it clears "powerhit" and does
803 * a powerfail sequence. If it is not in PF_MODES, then it
804 * puts itself in PF_MODES and then clears "powerhit". Should
805 * "powerhit" get set again while spawn_processes() is working
806 * on a powerfail sequence, the following code will see that
807 * spawn_processes() tries to execute the powerfail sequence
808 * again. This guarantees that the powerfail sequence will be
809 * successfully completed before further processing takes
810 * place.
812 if (wakeup.w_flags.w_powerhit) {
813 op_modes = PF_MODES;
815 * Make sure that cur_state != prev_state so that
816 * ONCE and WAIT types work.
818 prev_state = 0;
819 } else if (op_modes != NORMAL_MODES) {
821 * If spawn_processes() was not just called while in
822 * normal mode, we set the mode to normal and it will
823 * be called again to check normal modes. If we have
824 * just finished a powerfail sequence with prev_state
825 * equal to zero, we set prev_state equal to cur_state
826 * before the next pass through.
828 if (op_modes == PF_MODES)
829 prev_state = cur_state;
830 op_modes = NORMAL_MODES;
831 } else if (cur_state == LVLa || cur_state == LVLb ||
832 cur_state == LVLc) {
834 * If it was a change of levels that awakened us and the
835 * new level is one of the demand levels then reset
836 * cur_state to the previous state and do another scan
837 * to take care of the usual respawn actions.
839 cur_state = prior_state;
840 prior_state = prev_state;
841 prev_state = cur_state;
842 } else {
843 prev_state = cur_state;
845 if (wakeup.w_mask == 0) {
846 int ret;
849 * "init" is finished with all actions for
850 * the current wakeup.
852 ret = poll(poll_fds, poll_nfds,
853 SLEEPTIME * MILLISEC);
854 pausecnt++;
855 if (ret > 0)
856 contract_event(&poll_fds[0]);
857 else if (ret < 0 && errno != EINTR)
858 console(B_TRUE, "poll() error: %s\n",
859 strerror(errno));
862 if (wakeup.w_flags.w_usersignal) {
864 * Install the new level. This could be a real
865 * change in levels or a telinit [Q|a|b|c] or
866 * just a telinit to the same level at which
867 * we are running.
869 if (new_state != cur_state) {
870 if (new_state == LVLa ||
871 new_state == LVLb ||
872 new_state == LVLc) {
873 prev_state = prior_state;
874 prior_state = cur_state;
875 cur_state = new_state;
876 } else {
877 prev_state = cur_state;
878 if (cur_state >= 0)
879 prior_state = cur_state;
880 cur_state = new_state;
881 chg_lvl_flag = TRUE;
885 new_state = 0;
888 if (wakeup.w_flags.w_powerhit)
889 op_modes = PF_MODES;
892 * Clear all wakeup reasons.
894 wakeup.w_mask = 0;
898 /*NOTREACHED*/
901 static void
902 update_boot_archive(int new_state)
904 if (new_state != LVL0 && new_state != LVL5 && new_state != LVL6)
905 return;
907 if (getzoneid() != GLOBAL_ZONEID)
908 return;
910 (void) system("/sbin/bootadm -a update_all");
914 * void enter_maintenance()
915 * A simple invocation of sulogin(8), with no baggage, in the case that we
916 * are unable to activate svc.startd(8). We fork; the child runs sulogin;
917 * we wait for it to exit.
919 static void
920 enter_maintenance()
922 struct PROC_TABLE *su_process;
924 console(B_FALSE, "Requesting maintenance mode\n"
925 "(See /lib/svc/share/README for additional information.)\n");
926 (void) sighold(SIGCLD);
927 while ((su_process = efork(M_OFF, NULLPROC, NOCLEANUP)) == NO_ROOM)
928 (void) pause();
929 (void) sigrelse(SIGCLD);
930 if (su_process == NULLPROC) {
931 int fd;
933 (void) fclose(stdin);
934 (void) fclose(stdout);
935 (void) fclose(stderr);
936 closefrom(0);
938 fd = open(SYSCON, O_RDWR | O_NOCTTY);
939 if (fd >= 0) {
940 (void) dup2(fd, 1);
941 (void) dup2(fd, 2);
942 } else {
944 * Need to issue an error message somewhere.
946 syslog(LOG_CRIT, "init[%d]: cannot open %s; %s\n",
947 getpid(), SYSCON, strerror(errno));
951 * Execute the "su" program.
953 (void) execle(SU, SU, "-", (char *)0, glob_envp);
954 console(B_TRUE, "execle of %s failed: %s\n", SU,
955 strerror(errno));
956 timer(5);
957 exit(1);
961 * If we are the parent, wait around for the child to die
962 * or for "init" to be signaled to change levels.
964 while (waitproc(su_process) == FAILURE) {
966 * All other reasons for waking are ignored when in
967 * single-user mode. The only child we are interested
968 * in is being waited for explicitly by waitproc().
970 wakeup.w_mask = 0;
975 * remv() scans through "proc_table" and performs cleanup. If
976 * there is a process in the table, which shouldn't be here at
977 * the current run level, then remv() kills the process.
979 static void
980 remv()
982 struct PROC_TABLE *process;
983 struct CMD_LINE cmd;
984 char cmd_string[MAXCMDL];
985 int change_level;
987 change_level = (cur_state != prev_state ? TRUE : FALSE);
990 * Clear the TOUCHED flag on all entries so that when we have
991 * finished scanning inittab, we will be able to tell if we
992 * have any processes for which there is no entry in inittab.
994 for (process = proc_table;
995 (process < proc_table + num_proc); process++) {
996 process->p_flags &= ~TOUCHED;
1000 * Scan all inittab entries.
1002 while (getcmd(&cmd, &cmd_string[0]) == TRUE) {
1003 /* Scan for process which goes with this entry in inittab. */
1004 for (process = proc_table;
1005 (process < proc_table + num_proc); process++) {
1006 if ((process->p_flags & OCCUPIED) == 0 ||
1007 !id_eq(process->p_id, cmd.c_id))
1008 continue;
1011 * This slot contains the process we are looking for.
1015 * Is the cur_state SINGLE_USER or is this process
1016 * marked as "off" or was this proc started by some
1017 * mechanism other than LVL{a|b|c} and the current level
1018 * does not support this process?
1020 if (cur_state == SINGLE_USER ||
1021 cmd.c_action == M_OFF ||
1022 ((cmd.c_levels & state_to_mask(cur_state)) == 0 &&
1023 (process->p_flags & DEMANDREQUEST) == 0)) {
1024 if (process->p_flags & LIVING) {
1026 * Touch this entry so we know we have
1027 * treated it. Note that procs which
1028 * are already dead at this point and
1029 * should not be restarted are left
1030 * untouched. This causes their slot to
1031 * be freed later after dead accounting
1032 * is done.
1034 process->p_flags |= TOUCHED;
1036 if ((process->p_flags & KILLED) == 0) {
1037 if (change_level) {
1038 process->p_flags
1039 |= WARNED;
1040 (void) kill(
1041 process->p_pid,
1042 SIGTERM);
1043 } else {
1045 * Fork a killing proc
1046 * so "init" can
1047 * continue without
1048 * having to pause for
1049 * TWARN seconds.
1051 killproc(
1052 process->p_pid);
1054 process->p_flags |= KILLED;
1057 } else {
1059 * Process can exist at current level. If it is
1060 * still alive or a DEMANDREQUEST we touch it so
1061 * it will be left alone. Otherwise we leave it
1062 * untouched so it will be accounted for and
1063 * cleaned up later in remv(). Dead
1064 * DEMANDREQUESTs will be accounted but not
1065 * freed.
1067 if (process->p_flags &
1068 (LIVING|NOCLEANUP|DEMANDREQUEST))
1069 process->p_flags |= TOUCHED;
1072 break;
1076 st_write();
1079 * If this was a change of levels call, scan through the
1080 * process table for processes that were warned to die. If any
1081 * are found that haven't left yet, sleep for TWARN seconds and
1082 * then send final terminations to any that haven't died yet.
1084 if (change_level) {
1087 * Set the alarm for TWARN seconds on the assumption
1088 * that there will be some that need to be waited for.
1089 * This won't harm anything except we are guaranteed to
1090 * wakeup in TWARN seconds whether we need to or not.
1092 setimer(TWARN);
1095 * Scan for processes which should be dying. We hope they
1096 * will die without having to be sent a SIGKILL signal.
1098 for (process = proc_table;
1099 (process < proc_table + num_proc); process++) {
1101 * If this process should die, hasn't yet, and the
1102 * TWARN time hasn't expired yet, wait for process
1103 * to die or for timer to expire.
1105 while (time_up == FALSE &&
1106 (process->p_flags & (WARNED|LIVING|OCCUPIED)) ==
1107 (WARNED|LIVING|OCCUPIED))
1108 (void) pause();
1110 if (time_up == TRUE)
1111 break;
1115 * If we reached the end of the table without the timer
1116 * expiring, then there are no procs which will have to be
1117 * sent the SIGKILL signal. If the timer has expired, then
1118 * it is necessary to scan the table again and send signals
1119 * to all processes which aren't going away nicely.
1121 if (time_up == TRUE) {
1122 for (process = proc_table;
1123 (process < proc_table + num_proc); process++) {
1124 if ((process->p_flags &
1125 (WARNED|LIVING|OCCUPIED)) ==
1126 (WARNED|LIVING|OCCUPIED))
1127 (void) kill(process->p_pid, SIGKILL);
1130 setimer(0);
1134 * Rescan the proc_table for two kinds of entry, those marked LIVING,
1135 * NAMED, which don't have an entry in inittab (haven't been TOUCHED
1136 * by the above scanning), and haven't been sent kill signals, and
1137 * those entries marked not LIVING, NAMED. The former procs are killed.
1138 * The latter have DEAD_PROCESS accounting done and the slot cleared.
1140 for (process = proc_table;
1141 (process < proc_table + num_proc); process++) {
1142 if ((process->p_flags & (LIVING|NAMED|TOUCHED|KILLED|OCCUPIED))
1143 == (LIVING|NAMED|OCCUPIED)) {
1144 killproc(process->p_pid);
1145 process->p_flags |= KILLED;
1146 } else if ((process->p_flags & (LIVING|NAMED|OCCUPIED)) ==
1147 (NAMED|OCCUPIED)) {
1148 (void) account(DEAD_PROCESS, process, NULL);
1150 * If this named proc hasn't been TOUCHED, then free the
1151 * space. It has either died of it's own accord, but
1152 * isn't respawnable or it was killed because it
1153 * shouldn't exist at this level.
1155 if ((process->p_flags & TOUCHED) == 0)
1156 process->p_flags = 0;
1160 st_write();
1164 * Extract the svc.startd command line and whether to restart it from its
1165 * inittab entry.
1167 /*ARGSUSED*/
1168 static void
1169 process_startd_line(struct CMD_LINE *cmd, char *cmd_string)
1171 size_t sz;
1173 /* Save the command line. */
1174 if (sflg || rflg) {
1175 /* Also append -r or -s. */
1176 (void) strlcpy(startd_cline, cmd_string, sizeof (startd_cline));
1177 (void) strlcat(startd_cline, " -", sizeof (startd_cline));
1178 if (sflg)
1179 sz = strlcat(startd_cline, "s", sizeof (startd_cline));
1180 if (rflg)
1181 sz = strlcat(startd_cline, "r", sizeof (startd_cline));
1182 } else {
1183 sz = strlcpy(startd_cline, cmd_string, sizeof (startd_cline));
1186 if (sz >= sizeof (startd_cline)) {
1187 console(B_TRUE,
1188 "svc.startd command line too long. Ignoring.\n");
1189 startd_cline[0] = '\0';
1190 return;
1195 * spawn_processes() scans inittab for entries which should be run at this
1196 * mode. Processes which should be running but are not, are started.
1198 static int
1199 spawn_processes()
1201 struct PROC_TABLE *pp;
1202 struct CMD_LINE cmd;
1203 char cmd_string[MAXCMDL];
1204 short lvl_mask;
1205 int status;
1208 * First check the "powerhit" flag. If it is set, make sure the modes
1209 * are PF_MODES and clear the "powerhit" flag. Avoid the possible race
1210 * on the "powerhit" flag by disallowing a new powerfail interrupt
1211 * between the test of the powerhit flag and the clearing of it.
1213 if (wakeup.w_flags.w_powerhit) {
1214 wakeup.w_flags.w_powerhit = 0;
1215 op_modes = PF_MODES;
1217 lvl_mask = state_to_mask(cur_state);
1220 * Scan through all the entries in inittab.
1222 while ((status = getcmd(&cmd, &cmd_string[0])) == TRUE) {
1223 if (id_eq(cmd.c_id, "smf")) {
1224 process_startd_line(&cmd, cmd_string);
1225 continue;
1228 retry_for_proc_slot:
1231 * Find out if there is a process slot for this entry already.
1233 if ((pp = findpslot(&cmd)) == NULLPROC) {
1235 * we've run out of proc table entries
1236 * increase proc_table.
1238 increase_proc_table_size();
1241 * Retry now as we have an empty proc slot.
1242 * In case increase_proc_table_size() fails,
1243 * we will keep retrying.
1245 goto retry_for_proc_slot;
1249 * If there is an entry, and it is marked as DEMANDREQUEST,
1250 * one of the levels a, b, or c is in its levels mask, and
1251 * the action field is ONDEMAND and ONDEMAND is a permissable
1252 * mode, and the process is dead, then respawn it.
1254 if (((pp->p_flags & (LIVING|DEMANDREQUEST)) == DEMANDREQUEST) &&
1255 (cmd.c_levels & MASK_abc) &&
1256 (cmd.c_action & op_modes) == M_ONDEMAND) {
1257 spawn(pp, &cmd);
1258 continue;
1262 * If the action is not an action we are interested in,
1263 * skip the entry.
1265 if ((cmd.c_action & op_modes) == 0 || pp->p_flags & LIVING ||
1266 (cmd.c_levels & lvl_mask) == 0)
1267 continue;
1270 * If the modes are the normal modes (ONCE, WAIT, RESPAWN, OFF,
1271 * ONDEMAND) and the action field is either OFF or the action
1272 * field is ONCE or WAIT and the current level is the same as
1273 * the last level, then skip this entry. ONCE and WAIT only
1274 * get run when the level changes.
1276 if (op_modes == NORMAL_MODES &&
1277 (cmd.c_action == M_OFF ||
1278 (cmd.c_action & (M_ONCE|M_WAIT)) &&
1279 cur_state == prev_state))
1280 continue;
1283 * At this point we are interested in performing the action for
1284 * this entry. Actions fall into two categories, spinning off
1285 * a process and not waiting, and spinning off a process and
1286 * waiting for it to die. If the action is ONCE, RESPAWN,
1287 * ONDEMAND, POWERFAIL, or BOOT we don't wait for the process
1288 * to die, for all other actions we do wait.
1290 if (cmd.c_action & (M_ONCE | M_RESPAWN | M_PF | M_BOOT)) {
1291 spawn(pp, &cmd);
1293 } else {
1294 spawn(pp, &cmd);
1295 while (waitproc(pp) == FAILURE)
1297 (void) account(DEAD_PROCESS, pp, NULL);
1298 pp->p_flags = 0;
1301 return (status);
1305 * spawn() spawns a shell, inserts the information about the process
1306 * process into the proc_table, and does the startup accounting.
1308 static void
1309 spawn(struct PROC_TABLE *process, struct CMD_LINE *cmd)
1311 int i;
1312 int modes, maxfiles;
1313 time_t now;
1314 struct PROC_TABLE tmproc, *oprocess;
1317 * The modes to be sent to efork() are 0 unless we are
1318 * spawning a LVLa, LVLb, or LVLc entry or we will be
1319 * waiting for the death of the child before continuing.
1321 modes = NAMED;
1322 if (process->p_flags & DEMANDREQUEST || cur_state == LVLa ||
1323 cur_state == LVLb || cur_state == LVLc)
1324 modes |= DEMANDREQUEST;
1325 if ((cmd->c_action & (M_SYSINIT | M_WAIT | M_BOOTWAIT | M_PWAIT)) != 0)
1326 modes |= NOCLEANUP;
1329 * If this is a respawnable process, check the threshold
1330 * information to avoid excessive respawns.
1332 if (cmd->c_action & M_RESPAWN) {
1334 * Add NOCLEANUP to all respawnable commands so that the
1335 * information about the frequency of respawns isn't lost.
1337 modes |= NOCLEANUP;
1338 (void) time(&now);
1341 * If no time is assigned, then this is the first time
1342 * this command is being processed in this series. Assign
1343 * the current time.
1345 if (process->p_time == 0L)
1346 process->p_time = now;
1348 if (process->p_count++ == SPAWN_LIMIT) {
1350 if ((now - process->p_time) < SPAWN_INTERVAL) {
1352 * Process is respawning too rapidly. Print
1353 * message and refuse to respawn it for now.
1355 console(B_TRUE, "Command is respawning too "
1356 "rapidly. Check for possible errors.\n"
1357 "id:%4s \"%s\"\n",
1358 &cmd->c_id[0], &cmd->c_command[EXEC]);
1359 return;
1361 process->p_time = now;
1362 process->p_count = 0;
1364 } else if (process->p_count > SPAWN_LIMIT) {
1366 * If process has been respawning too rapidly and
1367 * the inhibit time limit hasn't expired yet, we
1368 * refuse to respawn.
1370 if (now - process->p_time < SPAWN_INTERVAL + INHIBIT)
1371 return;
1372 process->p_time = now;
1373 process->p_count = 0;
1375 rsflag = TRUE;
1379 * Spawn a child process to execute this command.
1381 (void) sighold(SIGCLD);
1382 oprocess = process;
1383 while ((process = efork(cmd->c_action, oprocess, modes)) == NO_ROOM)
1384 (void) pause();
1386 if (process == NULLPROC) {
1389 * We are the child. We must make sure we get a different
1390 * file pointer for our references to utmpx. Otherwise our
1391 * seeks and reads will compete with those of the parent.
1393 endutxent();
1396 * Perform the accounting for the beginning of a process.
1397 * Note that all processes are initially "INIT_PROCESS"es.
1399 tmproc.p_id[0] = cmd->c_id[0];
1400 tmproc.p_id[1] = cmd->c_id[1];
1401 tmproc.p_id[2] = cmd->c_id[2];
1402 tmproc.p_id[3] = cmd->c_id[3];
1403 tmproc.p_pid = getpid();
1404 tmproc.p_exit = 0;
1405 (void) account(INIT_PROCESS, &tmproc,
1406 prog_name(&cmd->c_command[EXEC]));
1407 maxfiles = ulimit(UL_GDESLIM, 0);
1408 for (i = 0; i < maxfiles; i++)
1409 (void) fcntl(i, F_SETFD, FD_CLOEXEC);
1412 * Now exec a shell with the -c option and the command
1413 * from inittab.
1415 (void) execle(SH, "INITSH", "-c", cmd->c_command, (char *)0,
1416 glob_envp);
1417 console(B_TRUE, "Command\n\"%s\"\n failed to execute. errno "
1418 "= %d (exec of shell failed)\n", cmd->c_command, errno);
1421 * Don't come back so quickly that "init" doesn't have a
1422 * chance to finish putting this child in "proc_table".
1424 timer(20);
1425 exit(1);
1430 * We are the parent. Insert the necessary
1431 * information in the proc_table.
1433 process->p_id[0] = cmd->c_id[0];
1434 process->p_id[1] = cmd->c_id[1];
1435 process->p_id[2] = cmd->c_id[2];
1436 process->p_id[3] = cmd->c_id[3];
1438 st_write();
1440 (void) sigrelse(SIGCLD);
1444 * findpslot() finds the old slot in the process table for the
1445 * command with the same id, or it finds an empty slot.
1447 static struct PROC_TABLE *
1448 findpslot(struct CMD_LINE *cmd)
1450 struct PROC_TABLE *process;
1451 struct PROC_TABLE *empty = NULLPROC;
1453 for (process = proc_table;
1454 (process < proc_table + num_proc); process++) {
1455 if (process->p_flags & OCCUPIED &&
1456 id_eq(process->p_id, cmd->c_id))
1457 break;
1460 * If the entry is totally empty and "empty" is still 0,
1461 * remember where this hole is and make sure the slot is
1462 * zeroed out.
1464 if (empty == NULLPROC && (process->p_flags & OCCUPIED) == 0) {
1465 empty = process;
1466 process->p_id[0] = '\0';
1467 process->p_id[1] = '\0';
1468 process->p_id[2] = '\0';
1469 process->p_id[3] = '\0';
1470 process->p_pid = 0;
1471 process->p_time = 0L;
1472 process->p_count = 0;
1473 process->p_flags = 0;
1474 process->p_exit = 0;
1479 * If there is no entry for this slot, then there should be an
1480 * empty slot. If there is no empty slot, then we've run out
1481 * of proc_table space. If the latter is true, empty will be
1482 * NULL and the caller will have to complain.
1484 if (process == (proc_table + num_proc))
1485 process = empty;
1487 return (process);
1491 * getcmd() parses lines from inittab. Each time it finds a command line
1492 * it will return TRUE as well as fill the passed CMD_LINE structure and
1493 * the shell command string. When the end of inittab is reached, FALSE
1494 * is returned inittab is automatically opened if it is not currently open
1495 * and is closed when the end of the file is reached.
1497 static FILE *fp_inittab = NULL;
1499 static int
1500 getcmd(struct CMD_LINE *cmd, char *shcmd)
1502 char *ptr;
1503 int c, lastc, state;
1504 char *ptr1;
1505 int answer, i, proceed;
1506 struct stat sbuf;
1507 static char *actions[] = {
1508 "off", "respawn", "ondemand", "once", "wait", "boot",
1509 "bootwait", "powerfail", "powerwait", "initdefault",
1510 "sysinit",
1512 static short act_masks[] = {
1513 M_OFF, M_RESPAWN, M_ONDEMAND, M_ONCE, M_WAIT, M_BOOT,
1514 M_BOOTWAIT, M_PF, M_PWAIT, M_INITDEFAULT, M_SYSINIT,
1517 * Only these actions will be allowed for entries which
1518 * are specified for single-user mode.
1520 short su_acts = M_INITDEFAULT | M_PF | M_PWAIT | M_WAIT;
1522 if (fp_inittab == NULL) {
1524 * Before attempting to open inittab we stat it to make
1525 * sure it currently exists and is not empty. We try
1526 * several times because someone may have temporarily
1527 * unlinked or truncated the file.
1529 for (i = 0; i < 3; i++) {
1530 if (stat(INITTAB, &sbuf) == -1) {
1531 if (i == 2) {
1532 console(B_TRUE,
1533 "Cannot stat %s, errno: %d\n",
1534 INITTAB, errno);
1535 return (FAILURE);
1536 } else {
1537 timer(3);
1539 } else if (sbuf.st_size < 10) {
1540 if (i == 2) {
1541 console(B_TRUE,
1542 "%s truncated or corrupted\n",
1543 INITTAB);
1544 return (FAILURE);
1545 } else {
1546 timer(3);
1548 } else {
1549 break;
1554 * If unable to open inittab, print error message and
1555 * return FAILURE to caller.
1557 if ((fp_inittab = fopen(INITTAB, "r")) == NULL) {
1558 console(B_TRUE, "Cannot open %s errno: %d\n", INITTAB,
1559 errno);
1560 return (FAILURE);
1565 * Keep getting commands from inittab until you find a
1566 * good one or run out of file.
1568 for (answer = FALSE; answer == FALSE; ) {
1570 * Zero out the cmd itself before trying next line.
1572 bzero(cmd, sizeof (struct CMD_LINE));
1575 * Read in lines of inittab, parsing at colons, until a line is
1576 * read in which doesn't end with a backslash. Do not start if
1577 * the first character read is an EOF. Note that this means
1578 * that lines which don't end in a newline are still processed,
1579 * since the "for" will terminate normally once started,
1580 * regardless of whether line terminates with a newline or EOF.
1582 state = FAILURE;
1583 if ((c = fgetc(fp_inittab)) == EOF) {
1584 answer = FALSE;
1585 (void) fclose(fp_inittab);
1586 fp_inittab = NULL;
1587 break;
1590 for (proceed = TRUE, ptr = shcmd, state = ID, lastc = '\0';
1591 proceed && c != EOF;
1592 lastc = c, c = fgetc(fp_inittab)) {
1593 /* If we're not in the FAILURE state and haven't */
1594 /* yet reached the shell command field, process */
1595 /* the line, otherwise just look for a real end */
1596 /* of line. */
1597 if (state != FAILURE && state != COMMAND) {
1599 * Squeeze out spaces and tabs.
1601 if (c == ' ' || c == '\t')
1602 continue;
1605 * Ignore characters in a comment, except for the \n.
1607 if (state == COMMENT) {
1608 if (c == '\n') {
1609 lastc = ' ';
1610 break;
1611 } else {
1612 continue;
1617 * Detect comments (lines whose first non-whitespace
1618 * character is '#') by checking that we're at the
1619 * beginning of a line, have seen a '#', and haven't
1620 * yet accumulated any characters.
1622 if (state == ID && c == '#' && ptr == shcmd) {
1623 state = COMMENT;
1624 continue;
1628 * If the character is a ':', then check the
1629 * previous field for correctness and advance
1630 * to the next field.
1632 if (c == ':') {
1633 switch (state) {
1635 case ID :
1637 * Check to see that there are only
1638 * 1 to 4 characters for the id.
1640 if ((i = ptr - shcmd) < 1 || i > 4) {
1641 state = FAILURE;
1642 } else {
1643 bcopy(shcmd, &cmd->c_id[0], i);
1644 ptr = shcmd;
1645 state = LEVELS;
1647 break;
1649 case LEVELS :
1651 * Build a mask for all the levels for
1652 * which this command will be legal.
1654 for (cmd->c_levels = 0, ptr1 = shcmd;
1655 ptr1 < ptr; ptr1++) {
1656 int mask;
1657 if (lvlname_to_mask(*ptr1,
1658 &mask) == -1) {
1659 state = FAILURE;
1660 break;
1662 cmd->c_levels |= mask;
1664 if (state != FAILURE) {
1665 state = ACTION;
1666 ptr = shcmd; /* Reset the buffer */
1668 break;
1670 case ACTION :
1672 * Null terminate the string in shcmd buffer and
1673 * then try to match against legal actions. If
1674 * the field is of length 0, then the default of
1675 * "RESPAWN" is used if the id is numeric,
1676 * otherwise the default is "OFF".
1678 if (ptr == shcmd) {
1679 if (isdigit(cmd->c_id[0]) &&
1680 (cmd->c_id[1] == '\0' ||
1681 isdigit(cmd->c_id[1])) &&
1682 (cmd->c_id[2] == '\0' ||
1683 isdigit(cmd->c_id[2])) &&
1684 (cmd->c_id[3] == '\0' ||
1685 isdigit(cmd->c_id[3])))
1686 cmd->c_action = M_RESPAWN;
1687 else
1688 cmd->c_action = M_OFF;
1689 } else {
1690 for (cmd->c_action = 0, i = 0,
1691 *ptr = '\0';
1693 sizeof (actions)/sizeof (char *);
1694 i++) {
1695 if (strcmp(shcmd, actions[i]) == 0) {
1696 if ((cmd->c_levels & MASKSU) &&
1697 !(act_masks[i] & su_acts))
1698 cmd->c_action = 0;
1699 else
1700 cmd->c_action =
1701 act_masks[i];
1702 break;
1708 * If the action didn't match any legal action,
1709 * set state to FAILURE.
1711 if (cmd->c_action == 0) {
1712 state = FAILURE;
1713 } else {
1714 state = COMMAND;
1715 (void) strcpy(shcmd, "exec ");
1717 ptr = shcmd + EXEC;
1718 break;
1720 continue;
1724 /* If the character is a '\n', then this is the end of a */
1725 /* line. If the '\n' wasn't preceded by a backslash, */
1726 /* it is also the end of an inittab command. If it was */
1727 /* preceded by a backslash then the next line is a */
1728 /* continuation. Note that the continuation '\n' falls */
1729 /* through and is treated like other characters and is */
1730 /* stored in the shell command line. */
1731 if (c == '\n' && lastc != '\\') {
1732 proceed = FALSE;
1733 *ptr = '\0';
1734 break;
1737 /* For all other characters just stuff them into the */
1738 /* command as long as there aren't too many of them. */
1739 /* Make sure there is room for a terminating '\0' also. */
1740 if (ptr >= shcmd + MAXCMDL - 1)
1741 state = FAILURE;
1742 else
1743 *ptr++ = (char)c;
1745 /* If the character we just stored was a quoted */
1746 /* backslash, then change "c" to '\0', so that this */
1747 /* backslash will not cause a subsequent '\n' to appear */
1748 /* quoted. In otherwords '\' '\' '\n' is the real end */
1749 /* of a command, while '\' '\n' is a continuation. */
1750 if (c == '\\' && lastc == '\\')
1751 c = '\0';
1755 * Make sure all the fields are properly specified
1756 * for a good command line.
1758 if (state == COMMAND) {
1759 answer = TRUE;
1760 cmd->c_command = shcmd;
1763 * If no default level was supplied, insert
1764 * all numerical levels.
1766 if (cmd->c_levels == 0)
1767 cmd->c_levels = MASK_NUMERIC;
1770 * If no action has been supplied, declare this
1771 * entry to be OFF.
1773 if (cmd->c_action == 0)
1774 cmd->c_action = M_OFF;
1777 * If no shell command has been supplied, make sure
1778 * there is a null string in the command field.
1780 if (ptr == shcmd + EXEC)
1781 *shcmd = '\0';
1782 } else
1783 answer = FALSE;
1786 * If we have reached the end of inittab, then close it
1787 * and quit trying to find a good command line.
1789 if (c == EOF) {
1790 (void) fclose(fp_inittab);
1791 fp_inittab = NULL;
1792 break;
1795 return (answer);
1799 * lvlname_to_state(): convert the character name of a state to its level
1800 * (its corresponding signal number).
1802 static int
1803 lvlname_to_state(char name)
1805 int i;
1806 for (i = 0; i < LVL_NELEMS; i++) {
1807 if (lvls[i].lvl_name == name)
1808 return (lvls[i].lvl_state);
1810 return (-1);
1814 * state_to_name(): convert the level to the character name.
1816 static char
1817 state_to_name(int state)
1819 int i;
1820 for (i = 0; i < LVL_NELEMS; i++) {
1821 if (lvls[i].lvl_state == state)
1822 return (lvls[i].lvl_name);
1824 return (-1);
1828 * state_to_mask(): return the mask corresponding to a signal number
1830 static int
1831 state_to_mask(int state)
1833 int i;
1834 for (i = 0; i < LVL_NELEMS; i++) {
1835 if (lvls[i].lvl_state == state)
1836 return (lvls[i].lvl_mask);
1838 return (0); /* return 0, since that represents an empty mask */
1842 * lvlname_to_mask(): return the mask corresponding to a levels character name
1844 static int
1845 lvlname_to_mask(char name, int *mask)
1847 int i;
1848 for (i = 0; i < LVL_NELEMS; i++) {
1849 if (lvls[i].lvl_name == name) {
1850 *mask = lvls[i].lvl_mask;
1851 return (0);
1854 return (-1);
1858 * state_to_flags(): return the flags corresponding to a runlevel. These
1859 * indicate properties of that runlevel.
1861 static int
1862 state_to_flags(int state)
1864 int i;
1865 for (i = 0; i < LVL_NELEMS; i++) {
1866 if (lvls[i].lvl_state == state)
1867 return (lvls[i].lvl_flags);
1869 return (0);
1873 * killproc() creates a child which kills the process specified by pid.
1875 void
1876 killproc(pid_t pid)
1878 struct PROC_TABLE *process;
1880 (void) sighold(SIGCLD);
1881 while ((process = efork(M_OFF, NULLPROC, 0)) == NO_ROOM)
1882 (void) pause();
1883 (void) sigrelse(SIGCLD);
1885 if (process == NULLPROC) {
1887 * efork() sets all signal handlers to the default, so reset
1888 * the ALRM handler to make timer() work as expected.
1890 (void) sigset(SIGALRM, alarmclk);
1893 * We are the child. Try to terminate the process nicely
1894 * first using SIGTERM and if it refuses to die in TWARN
1895 * seconds kill it with SIGKILL.
1897 (void) kill(pid, SIGTERM);
1898 (void) timer(TWARN);
1899 (void) kill(pid, SIGKILL);
1900 (void) exit(0);
1905 * Set up the default environment for all procs to be forked from init.
1906 * Read the values from the /etc/default/init file, except for PATH. If
1907 * there's not enough room in the environment array, the environment
1908 * lines that don't fit are silently discarded.
1910 void
1911 init_env()
1913 char line[MAXCMDL];
1914 FILE *fp;
1915 int inquotes, length, wslength;
1916 char *tokp, *cp1, *cp2;
1918 glob_envp[0] = malloc((unsigned)(strlen(DEF_PATH)+2));
1919 (void) strcpy(glob_envp[0], DEF_PATH);
1920 glob_envn = 1;
1922 if (rflg) {
1923 glob_envp[1] =
1924 malloc((unsigned)(strlen("_DVFS_RECONFIG=YES")+2));
1925 (void) strcpy(glob_envp[1], "_DVFS_RECONFIG=YES");
1926 ++glob_envn;
1927 } else if (bflg == 1) {
1928 glob_envp[1] =
1929 malloc((unsigned)(strlen("RB_NOBOOTRC=YES")+2));
1930 (void) strcpy(glob_envp[1], "RB_NOBOOTRC=YES");
1931 ++glob_envn;
1934 if ((fp = fopen(ENVFILE, "r")) == NULL) {
1935 console(B_TRUE,
1936 "Cannot open %s. Environment not initialized.\n",
1937 ENVFILE);
1938 } else {
1939 while (fgets(line, MAXCMDL - 1, fp) != NULL &&
1940 glob_envn < MAXENVENT - 2) {
1942 * Toss newline
1944 length = strlen(line);
1945 if (line[length - 1] == '\n')
1946 line[length - 1] = '\0';
1949 * Ignore blank or comment lines.
1951 if (line[0] == '#' || line[0] == '\0' ||
1952 (wslength = strspn(line, " \t\n")) ==
1953 strlen(line) ||
1954 strchr(line, '#') == line + wslength)
1955 continue;
1958 * First make a pass through the line and change
1959 * any non-quoted semi-colons to blanks so they
1960 * will be treated as token separators below.
1962 inquotes = 0;
1963 for (cp1 = line; *cp1 != '\0'; cp1++) {
1964 if (*cp1 == '"') {
1965 if (inquotes == 0)
1966 inquotes = 1;
1967 else
1968 inquotes = 0;
1969 } else if (*cp1 == ';') {
1970 if (inquotes == 0)
1971 *cp1 = ' ';
1976 * Tokens within the line are separated by blanks
1977 * and tabs. For each token in the line which
1978 * contains a '=' we strip out any quotes and then
1979 * stick the token in the environment array.
1981 if ((tokp = strtok(line, " \t")) == NULL)
1982 continue;
1983 do {
1984 if (strchr(tokp, '=') == NULL)
1985 continue;
1986 length = strlen(tokp);
1987 while ((cp1 = strpbrk(tokp, "\"\'")) != NULL) {
1988 for (cp2 = cp1;
1989 cp2 < &tokp[length]; cp2++)
1990 *cp2 = *(cp2 + 1);
1991 length--;
1994 if (strncmp(tokp, "CMASK=",
1995 sizeof ("CMASK=") - 1) == 0) {
1996 long t;
1998 /* We know there's an = */
1999 t = strtol(strchr(tokp, '=') + 1, NULL,
2002 /* Sanity */
2003 if (t <= 077 && t >= 0)
2004 cmask = (int)t;
2005 (void) umask(cmask);
2006 continue;
2008 glob_envp[glob_envn] =
2009 malloc((unsigned)(length + 1));
2010 (void) strcpy(glob_envp[glob_envn], tokp);
2011 if (++glob_envn >= MAXENVENT - 1)
2012 break;
2013 } while ((tokp = strtok(NULL, " \t")) != NULL);
2017 * Append a null pointer to the environment array
2018 * to mark its end.
2020 glob_envp[glob_envn] = NULL;
2021 (void) fclose(fp);
2026 * boot_init(): Do initialization things that should be done at boot.
2028 void
2029 boot_init()
2031 int i;
2032 struct PROC_TABLE *process, *oprocess;
2033 struct CMD_LINE cmd;
2034 char line[MAXCMDL];
2035 char svc_aux[SVC_AUX_SIZE];
2036 char init_svc_fmri[SVC_FMRI_SIZE];
2037 char *old_path;
2038 int maxfiles;
2040 /* Use INIT_PATH for sysinit cmds */
2041 old_path = glob_envp[0];
2042 glob_envp[0] = malloc((unsigned)(strlen(INIT_PATH)+2));
2043 (void) strcpy(glob_envp[0], INIT_PATH);
2046 * Scan inittab(4) and process the special svc.startd entry, initdefault
2047 * and sysinit entries.
2049 while (getcmd(&cmd, &line[0]) == TRUE) {
2050 if (startd_tmpl >= 0 && id_eq(cmd.c_id, "smf")) {
2051 process_startd_line(&cmd, line);
2052 (void) snprintf(startd_svc_aux, SVC_AUX_SIZE,
2053 INITTAB_ENTRY_ID_STR_FORMAT, cmd.c_id);
2054 } else if (cmd.c_action == M_INITDEFAULT) {
2056 * initdefault is no longer meaningful, as the SMF
2057 * milestone controls what (legacy) run level we
2058 * boot to.
2060 console(B_TRUE,
2061 "Ignoring legacy \"initdefault\" entry.\n");
2062 } else if (cmd.c_action == M_SYSINIT) {
2064 * Execute the "sysinit" entry and wait for it to
2065 * complete. No bookkeeping is performed on these
2066 * entries because we avoid writing to the file system
2067 * until after there has been an chance to check it.
2069 if (process = findpslot(&cmd)) {
2070 (void) sighold(SIGCLD);
2071 (void) snprintf(svc_aux, SVC_AUX_SIZE,
2072 INITTAB_ENTRY_ID_STR_FORMAT, cmd.c_id);
2073 (void) snprintf(init_svc_fmri, SVC_FMRI_SIZE,
2074 SVC_INIT_PREFIX INITTAB_ENTRY_ID_STR_FORMAT,
2075 cmd.c_id);
2076 if (legacy_tmpl >= 0) {
2077 (void) ct_pr_tmpl_set_svc_fmri(
2078 legacy_tmpl, init_svc_fmri);
2079 (void) ct_pr_tmpl_set_svc_aux(
2080 legacy_tmpl, svc_aux);
2083 for (oprocess = process;
2084 (process = efork(M_OFF, oprocess,
2085 (NAMED|NOCLEANUP))) == NO_ROOM;
2086 /* CSTYLED */)
2088 (void) sigrelse(SIGCLD);
2090 if (process == NULLPROC) {
2091 maxfiles = ulimit(UL_GDESLIM, 0);
2093 for (i = 0; i < maxfiles; i++)
2094 (void) fcntl(i, F_SETFD,
2095 FD_CLOEXEC);
2096 (void) execle(SH, "INITSH", "-c",
2097 cmd.c_command,
2098 (char *)0, glob_envp);
2099 console(B_TRUE,
2100 "Command\n\"%s\"\n failed to execute. errno = %d (exec of shell failed)\n",
2101 cmd.c_command, errno);
2102 exit(1);
2103 } else
2104 while (waitproc(process) == FAILURE)
2106 process->p_flags = 0;
2107 st_write();
2112 /* Restore the path. */
2113 free(glob_envp[0]);
2114 glob_envp[0] = old_path;
2117 * This will enable st_write() to complain about init_state_file.
2119 booting = 0;
2122 * If the /etc/ioctl.syscon didn't exist or had invalid contents write
2123 * out a correct version.
2125 if (write_ioctl)
2126 write_ioctl_syscon();
2129 * Start svc.startd(8), which does most of the work.
2131 if (startd_cline[0] != '\0' && startd_tmpl >= 0) {
2132 /* Start svc.startd. */
2133 if (startd_run(startd_cline, startd_tmpl, 0) == -1)
2134 cur_state = SINGLE_USER;
2135 } else {
2136 console(B_TRUE, "Absent svc.startd entry or bad "
2137 "contract template. Not starting svc.startd.\n");
2138 enter_maintenance();
2143 * init_signals(): Initialize all signals to either be caught or ignored.
2145 void
2146 init_signals(void)
2148 struct sigaction act;
2149 int i;
2152 * Start by ignoring all signals, then selectively re-enable some.
2153 * The SIG_IGN disposition will only affect asynchronous signals:
2154 * any signal that we trigger synchronously that doesn't end up
2155 * being handled by siglvl() will be forcibly delivered by the kernel.
2157 for (i = SIGHUP; i <= SIGRTMAX; i++)
2158 (void) sigset(i, SIG_IGN);
2161 * Handle all level-changing signals using siglvl() and set sa_mask so
2162 * that all level-changing signals are blocked while in siglvl().
2164 act.sa_handler = siglvl;
2165 act.sa_flags = SA_SIGINFO;
2166 (void) sigemptyset(&act.sa_mask);
2168 (void) sigaddset(&act.sa_mask, LVLQ);
2169 (void) sigaddset(&act.sa_mask, LVL0);
2170 (void) sigaddset(&act.sa_mask, LVL1);
2171 (void) sigaddset(&act.sa_mask, LVL2);
2172 (void) sigaddset(&act.sa_mask, LVL3);
2173 (void) sigaddset(&act.sa_mask, LVL4);
2174 (void) sigaddset(&act.sa_mask, LVL5);
2175 (void) sigaddset(&act.sa_mask, LVL6);
2176 (void) sigaddset(&act.sa_mask, SINGLE_USER);
2177 (void) sigaddset(&act.sa_mask, LVLa);
2178 (void) sigaddset(&act.sa_mask, LVLb);
2179 (void) sigaddset(&act.sa_mask, LVLc);
2181 (void) sigaction(LVLQ, &act, NULL);
2182 (void) sigaction(LVL0, &act, NULL);
2183 (void) sigaction(LVL1, &act, NULL);
2184 (void) sigaction(LVL2, &act, NULL);
2185 (void) sigaction(LVL3, &act, NULL);
2186 (void) sigaction(LVL4, &act, NULL);
2187 (void) sigaction(LVL5, &act, NULL);
2188 (void) sigaction(LVL6, &act, NULL);
2189 (void) sigaction(SINGLE_USER, &act, NULL);
2190 (void) sigaction(LVLa, &act, NULL);
2191 (void) sigaction(LVLb, &act, NULL);
2192 (void) sigaction(LVLc, &act, NULL);
2194 (void) sigset(SIGALRM, alarmclk);
2195 alarmclk();
2197 (void) sigset(SIGCLD, childeath);
2198 (void) sigset(SIGPWR, powerfail);
2202 * Set up pipe for "godchildren". If the file exists and is a pipe just open
2203 * it. Else, if the file system is r/w create it. Otherwise, defer its
2204 * creation and open until after /var/run has been mounted. This function is
2205 * only called on startup and when explicitly requested via LVLQ.
2207 void
2208 setup_pipe()
2210 struct stat stat_buf;
2211 struct statvfs statvfs_buf;
2212 struct sigaction act;
2215 * Always close the previous pipe descriptor as the mounted filesystems
2216 * may have changed.
2218 if (Pfd >= 0)
2219 (void) close(Pfd);
2221 if ((stat(INITPIPE, &stat_buf) == 0) &&
2222 ((stat_buf.st_mode & (S_IFMT|S_IRUSR)) == (S_IFIFO|S_IRUSR)))
2223 Pfd = open(INITPIPE, O_RDWR | O_NDELAY);
2224 else
2225 if ((statvfs(INITPIPE_DIR, &statvfs_buf) == 0) &&
2226 ((statvfs_buf.f_flag & ST_RDONLY) == 0)) {
2227 (void) unlink(INITPIPE);
2228 (void) mknod(INITPIPE, S_IFIFO | 0600, 0);
2229 Pfd = open(INITPIPE, O_RDWR | O_NDELAY);
2232 if (Pfd >= 0) {
2233 (void) ioctl(Pfd, I_SETSIG, S_INPUT);
2235 * Read pipe in message discard mode.
2237 (void) ioctl(Pfd, I_SRDOPT, RMSGD);
2239 act.sa_handler = sigpoll;
2240 act.sa_flags = 0;
2241 (void) sigemptyset(&act.sa_mask);
2242 (void) sigaddset(&act.sa_mask, SIGCLD);
2243 (void) sigaction(SIGPOLL, &act, NULL);
2248 * siglvl - handle an asynchronous signal from init(8) telling us that we
2249 * should change the current run level. We set new_state accordingly.
2251 void
2252 siglvl(int sig, siginfo_t *sip, ucontext_t *ucp)
2254 struct PROC_TABLE *process;
2255 struct sigaction act;
2258 * If the signal was from the kernel (rather than init(8)) then init
2259 * itself tripped the signal. That is, we might have a bug and tripped
2260 * a real SIGSEGV instead of receiving it as an alias for SIGLVLa. In
2261 * such a case we reset the disposition to SIG_DFL, block all signals
2262 * in uc_mask but the current one, and return to the interrupted ucp
2263 * to effect an appropriate death. The kernel will then restart us.
2265 * The one exception to SI_FROMKERNEL() is SIGFPE (a.k.a. LVL6), which
2266 * the kernel can send us when it wants to effect an orderly reboot.
2267 * For this case we must also verify si_code is zero, rather than a
2268 * code such as FPE_INTDIV which a bug might have triggered.
2270 if (sip != NULL && SI_FROMKERNEL(sip) &&
2271 (sig != SIGFPE || sip->si_code == 0)) {
2273 (void) sigemptyset(&act.sa_mask);
2274 act.sa_handler = SIG_DFL;
2275 act.sa_flags = 0;
2276 (void) sigaction(sig, &act, NULL);
2278 (void) sigfillset(&ucp->uc_sigmask);
2279 (void) sigdelset(&ucp->uc_sigmask, sig);
2280 ucp->uc_flags |= UC_SIGMASK;
2282 (void) setcontext(ucp);
2286 * If the signal received is a LVLQ signal, do not really
2287 * change levels, just restate the current level. If the
2288 * signal is not a LVLQ, set the new level to the signal
2289 * received.
2291 if (sig == LVLQ) {
2292 new_state = cur_state;
2293 lvlq_received = B_TRUE;
2294 } else {
2295 new_state = sig;
2299 * Clear all times and repeat counts in the process table
2300 * since either the level is changing or the user has editted
2301 * the inittab file and wants us to look at it again.
2302 * If the user has fixed a typo, we don't want residual timing
2303 * data preventing the fixed command line from executing.
2305 for (process = proc_table;
2306 (process < proc_table + num_proc); process++) {
2307 process->p_time = 0L;
2308 process->p_count = 0;
2312 * Set the flag to indicate that a "user signal" was received.
2314 wakeup.w_flags.w_usersignal = 1;
2319 * alarmclk
2321 static void
2322 alarmclk()
2324 time_up = TRUE;
2328 * childeath_single():
2330 * This used to be the SIGCLD handler and it was set with signal()
2331 * (as opposed to sigset()). When a child exited we'd come to the
2332 * handler, wait for the child, and reenable the handler with
2333 * signal() just before returning. The implementation of signal()
2334 * checks with waitid() for waitable children and sends a SIGCLD
2335 * if there are some. If children are exiting faster than the
2336 * handler can run we keep sending signals and the handler never
2337 * gets to return and eventually the stack runs out and init dies.
2338 * To prevent that we set the handler with sigset() so the handler
2339 * doesn't need to be reset, and in childeath() (see below) we
2340 * call childeath_single() as long as there are children to be
2341 * waited for. If a child exits while init is in the handler a
2342 * SIGCLD will be pending and delivered on return from the handler.
2343 * If the child was already waited for the handler will have nothing
2344 * to do and return, otherwise the child will be waited for.
2346 static void
2347 childeath_single(pid_t pid, int status)
2349 struct PROC_TABLE *process;
2350 struct pidlist *pp;
2353 * Scan the process table to see if we are interested in this process.
2355 for (process = proc_table;
2356 (process < proc_table + num_proc); process++) {
2357 if ((process->p_flags & (LIVING|OCCUPIED)) ==
2358 (LIVING|OCCUPIED) && process->p_pid == pid) {
2361 * Mark this process as having died and store the exit
2362 * status. Also set the wakeup flag for a dead child
2363 * and break out of the loop.
2365 process->p_flags &= ~LIVING;
2366 process->p_exit = (short)status;
2367 wakeup.w_flags.w_childdeath = 1;
2369 return;
2374 * No process was found above, look through auxiliary list.
2376 (void) sighold(SIGPOLL);
2377 pp = Plhead;
2378 while (pp) {
2379 if (pid > pp->pl_pid) {
2381 * Keep on looking.
2383 pp = pp->pl_next;
2384 continue;
2385 } else if (pid < pp->pl_pid) {
2387 * Not in the list.
2389 break;
2390 } else {
2392 * This is a dead "godchild".
2394 pp->pl_dflag = 1;
2395 pp->pl_exit = (short)status;
2396 wakeup.w_flags.w_childdeath = 1;
2397 Gchild = 1; /* Notice to call cleanaux(). */
2398 break;
2402 (void) sigrelse(SIGPOLL);
2405 /* ARGSUSED */
2406 static void
2407 childeath(int signo)
2409 pid_t pid;
2410 int status;
2412 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2413 childeath_single(pid, status);
2416 static void
2417 powerfail()
2419 (void) nice(-19);
2420 wakeup.w_flags.w_powerhit = 1;
2424 * efork() forks a child and the parent inserts the process in its table
2425 * of processes that are directly a result of forks that it has performed.
2426 * The child just changes the "global" with the process id for this process
2427 * to it's new value.
2428 * If efork() is called with a pointer into the proc_table it uses that slot,
2429 * otherwise it searches for a free slot. Regardless of how it was called,
2430 * it returns the pointer to the proc_table entry
2432 * The SIGCLD signal is blocked (held) before calling efork()
2433 * and is unblocked (released) after efork() returns.
2435 * Ideally, this should be rewritten to use modern signal semantics.
2437 static struct PROC_TABLE *
2438 efork(int action, struct PROC_TABLE *process, int modes)
2440 pid_t childpid;
2441 struct PROC_TABLE *proc;
2442 int i;
2444 * Freshen up the proc_table, removing any entries for dead processes
2445 * that don't have NOCLEANUP set. Perform the necessary accounting.
2447 for (proc = proc_table; (proc < proc_table + num_proc); proc++) {
2448 if ((proc->p_flags & (OCCUPIED|LIVING|NOCLEANUP)) ==
2449 (OCCUPIED)) {
2451 * Is this a named process?
2452 * If so, do the necessary bookkeeping.
2454 if (proc->p_flags & NAMED)
2455 (void) account(DEAD_PROCESS, proc, NULL);
2458 * Free this entry for new usage.
2460 proc->p_flags = 0;
2464 while ((childpid = fork()) == FAILURE) {
2466 * Shorten the alarm timer in case someone else's child dies
2467 * and free up a slot in the process table.
2469 setimer(5);
2472 * Wait for some children to die. Since efork()
2473 * is always called with SIGCLD blocked, unblock
2474 * it here so that child death signals can come in.
2476 (void) sigrelse(SIGCLD);
2477 (void) pause();
2478 (void) sighold(SIGCLD);
2479 setimer(0);
2482 if (childpid != 0) {
2484 if (process == NULLPROC) {
2486 * No proc table pointer specified so search
2487 * for a free slot.
2489 for (process = proc_table; process->p_flags != 0 &&
2490 (process < proc_table + num_proc); process++)
2493 if (process == (proc_table + num_proc)) {
2494 int old_proc_table_size = num_proc;
2496 /* Increase the process table size */
2497 increase_proc_table_size();
2498 if (old_proc_table_size == num_proc) {
2499 /* didn't grow: memory failure */
2500 return (NO_ROOM);
2501 } else {
2502 process =
2503 proc_table + old_proc_table_size;
2507 process->p_time = 0L;
2508 process->p_count = 0;
2510 process->p_id[0] = '\0';
2511 process->p_id[1] = '\0';
2512 process->p_id[2] = '\0';
2513 process->p_id[3] = '\0';
2514 process->p_pid = childpid;
2515 process->p_flags = (LIVING | OCCUPIED | modes);
2516 process->p_exit = 0;
2518 st_write();
2519 } else {
2520 if ((action & (M_WAIT | M_BOOTWAIT)) == 0)
2521 (void) setpgrp();
2523 process = NULLPROC;
2526 * Reset all signals to the system defaults.
2528 for (i = SIGHUP; i <= SIGRTMAX; i++)
2529 (void) sigset(i, SIG_DFL);
2532 * POSIX B.2.2.2 advises that init should set SIGTTOU,
2533 * SIGTTIN, and SIGTSTP to SIG_IGN.
2535 * Make sure that SIGXCPU and SIGXFSZ also remain ignored,
2536 * for backward compatibility.
2538 (void) sigset(SIGTTIN, SIG_IGN);
2539 (void) sigset(SIGTTOU, SIG_IGN);
2540 (void) sigset(SIGTSTP, SIG_IGN);
2541 (void) sigset(SIGXCPU, SIG_IGN);
2542 (void) sigset(SIGXFSZ, SIG_IGN);
2544 return (process);
2549 * waitproc() waits for a specified process to die. For this function to
2550 * work, the specified process must already in the proc_table. waitproc()
2551 * returns the exit status of the specified process when it dies.
2553 static long
2554 waitproc(struct PROC_TABLE *process)
2556 int answer;
2557 sigset_t oldmask, newmask, zeromask;
2559 (void) sigemptyset(&zeromask);
2560 (void) sigemptyset(&newmask);
2562 (void) sigaddset(&newmask, SIGCLD);
2564 /* Block SIGCLD and save the current signal mask */
2565 if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
2566 perror("SIG_BLOCK error");
2569 * Wait around until the process dies.
2571 if (process->p_flags & LIVING)
2572 (void) sigsuspend(&zeromask);
2574 /* Reset signal mask to unblock SIGCLD */
2575 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
2576 perror("SIG_SETMASK error");
2578 if (process->p_flags & LIVING)
2579 return (FAILURE);
2582 * Make sure to only return 16 bits so that answer will always
2583 * be positive whenever the process of interest really died.
2585 answer = (process->p_exit & 0xffff);
2588 * Free the slot in the proc_table.
2590 process->p_flags = 0;
2591 return (answer);
2595 * notify_pam_dead(): calls into the PAM framework to close the given session.
2597 static void
2598 notify_pam_dead(struct utmpx *up)
2600 pam_handle_t *pamh;
2601 char user[sizeof (up->ut_user) + 1];
2602 char ttyn[sizeof (up->ut_line) + 1];
2603 char host[sizeof (up->ut_host) + 1];
2606 * PAM does not take care of updating utmpx/wtmpx.
2608 (void) snprintf(user, sizeof (user), "%s", up->ut_user);
2609 (void) snprintf(ttyn, sizeof (ttyn), "%s", up->ut_line);
2610 (void) snprintf(host, sizeof (host), "%s", up->ut_host);
2612 if (pam_start("init", user, NULL, &pamh) == PAM_SUCCESS) {
2613 (void) pam_set_item(pamh, PAM_TTY, ttyn);
2614 (void) pam_set_item(pamh, PAM_RHOST, host);
2615 (void) pam_close_session(pamh, 0);
2616 (void) pam_end(pamh, PAM_SUCCESS);
2621 * Check you can access utmpx (As / may be read-only and
2622 * /var may not be mounted yet).
2624 static int
2625 access_utmpx(void)
2627 do {
2628 utmpx_ok = (access(UTMPX, R_OK|W_OK) == 0);
2629 } while (!utmpx_ok && errno == EINTR);
2631 return (utmpx_ok);
2635 * account() updates entries in utmpx and appends new entries to the end of
2636 * wtmpx (assuming they exist). The program argument indicates the name of
2637 * program if INIT_PROCESS, otherwise should be NULL.
2639 * account() only blocks for INIT_PROCESS requests.
2641 * Returns non-zero if write failed.
2643 static int
2644 account(short state, struct PROC_TABLE *process, char *program)
2646 struct utmpx utmpbuf, *u, *oldu;
2647 int tmplen;
2648 char fail_buf[UT_LINE_SZ];
2649 sigset_t block, unblock;
2651 if (!utmpx_ok && !access_utmpx()) {
2652 return (-1);
2656 * Set up the prototype for the utmp structure we want to write.
2658 u = &utmpbuf;
2659 (void) memset(u, 0, sizeof (struct utmpx));
2662 * Fill in the various fields of the utmp structure.
2664 u->ut_id[0] = process->p_id[0];
2665 u->ut_id[1] = process->p_id[1];
2666 u->ut_id[2] = process->p_id[2];
2667 u->ut_id[3] = process->p_id[3];
2668 u->ut_pid = process->p_pid;
2671 * Fill the "ut_exit" structure.
2673 u->ut_exit.e_termination = WTERMSIG(process->p_exit);
2674 u->ut_exit.e_exit = WEXITSTATUS(process->p_exit);
2675 u->ut_type = state;
2677 (void) time(&u->ut_tv.tv_sec);
2680 * Block signals for utmp update.
2682 (void) sigfillset(&block);
2683 (void) sigprocmask(SIG_BLOCK, &block, &unblock);
2686 * See if there already is such an entry in the "utmpx" file.
2688 setutxent(); /* Start at beginning of utmpx file. */
2690 if ((oldu = getutxid(u)) != NULL) {
2692 * Copy in the old "user", "line" and "host" fields
2693 * to our new structure.
2695 bcopy(oldu->ut_user, u->ut_user, sizeof (u->ut_user));
2696 bcopy(oldu->ut_line, u->ut_line, sizeof (u->ut_line));
2697 bcopy(oldu->ut_host, u->ut_host, sizeof (u->ut_host));
2698 u->ut_syslen = (tmplen = strlen(u->ut_host)) ?
2699 min(tmplen + 1, sizeof (u->ut_host)) : 0;
2701 if (oldu->ut_type == USER_PROCESS && state == DEAD_PROCESS) {
2702 notify_pam_dead(oldu);
2707 * Perform special accounting. Insert the special string into the
2708 * ut_line array. For INIT_PROCESSes put in the name of the
2709 * program in the "ut_user" field.
2711 switch (state) {
2712 case INIT_PROCESS:
2713 (void) strncpy(u->ut_user, program, sizeof (u->ut_user));
2714 (void) strcpy(fail_buf, "INIT_PROCESS");
2715 break;
2717 default:
2718 (void) strlcpy(fail_buf, u->ut_id, sizeof (u->ut_id) + 1);
2719 break;
2723 * Write out the updated entry to utmpx file.
2725 if (pututxline(u) == NULL) {
2726 console(B_TRUE, "Failed write of utmpx entry: \"%s\": %s\n",
2727 fail_buf, strerror(errno));
2728 endutxent();
2729 (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2730 return (-1);
2734 * If we're able to write to utmpx, then attempt to add to the
2735 * end of the wtmpx file.
2737 updwtmpx(WTMPX, u);
2739 endutxent();
2741 (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2743 return (0);
2746 static void
2747 clearent(pid_t pid, short status)
2749 struct utmpx *up;
2750 sigset_t block, unblock;
2753 * Block signals for utmp update.
2755 (void) sigfillset(&block);
2756 (void) sigprocmask(SIG_BLOCK, &block, &unblock);
2759 * No error checking for now.
2762 setutxent();
2763 while (up = getutxent()) {
2764 if (up->ut_pid == pid) {
2765 if (up->ut_type == DEAD_PROCESS) {
2767 * Cleaned up elsewhere.
2769 continue;
2772 notify_pam_dead(up);
2774 up->ut_type = DEAD_PROCESS;
2775 up->ut_exit.e_termination = WTERMSIG(status);
2776 up->ut_exit.e_exit = WEXITSTATUS(status);
2777 (void) time(&up->ut_tv.tv_sec);
2779 (void) pututxline(up);
2781 * Now attempt to add to the end of the
2782 * wtmp and wtmpx files. Do not create
2783 * if they don't already exist.
2785 updwtmpx(WTMPX, up);
2787 break;
2791 endutxent();
2792 (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2796 * prog_name() searches for the word or unix path name and
2797 * returns a pointer to the last element of the pathname.
2799 static char *
2800 prog_name(char *string)
2802 char *ptr, *ptr2;
2803 static char word[UT_USER_SZ + 1];
2806 * Search for the first word skipping leading spaces and tabs.
2808 while (*string == ' ' || *string == '\t')
2809 string++;
2812 * If the first non-space non-tab character is not one allowed in
2813 * a word, return a pointer to a null string, otherwise parse the
2814 * pathname.
2816 if (*string != '.' && *string != '/' && *string != '_' &&
2817 (*string < 'a' || *string > 'z') &&
2818 (*string < 'A' || * string > 'Z') &&
2819 (*string < '0' || *string > '9'))
2820 return ("");
2823 * Parse the pathname looking forward for '/', ' ', '\t', '\n' or
2824 * '\0'. Each time a '/' is found, move "ptr" to one past the
2825 * '/', thus when a ' ', '\t', '\n', or '\0' is found, "ptr" will
2826 * point to the last element of the pathname.
2828 for (ptr = string; *string != ' ' && *string != '\t' &&
2829 *string != '\n' && *string != '\0'; string++) {
2830 if (*string == '/')
2831 ptr = string+1;
2835 * Copy out up to the size of the "ut_user" array into "word",
2836 * null terminate it and return a pointer to it.
2838 for (ptr2 = &word[0]; ptr2 < &word[UT_USER_SZ] &&
2839 ptr < string; /* CSTYLED */)
2840 *ptr2++ = *ptr++;
2842 *ptr2 = '\0';
2843 return (&word[0]);
2848 * realcon() returns a nonzero value if there is a character device
2849 * associated with SYSCON that has the same device number as CONSOLE.
2851 static int
2852 realcon()
2854 struct stat sconbuf, conbuf;
2856 if (stat(SYSCON, &sconbuf) != -1 &&
2857 stat(CONSOLE, &conbuf) != -1 &&
2858 S_ISCHR(sconbuf.st_mode) &&
2859 S_ISCHR(conbuf.st_mode) &&
2860 sconbuf.st_rdev == conbuf.st_rdev) {
2861 return (1);
2862 } else {
2863 return (0);
2869 * get_ioctl_syscon() retrieves the SYSCON settings from the IOCTLSYSCON file.
2870 * Returns true if the IOCTLSYSCON file needs to be written (with
2871 * write_ioctl_syscon() below)
2873 static int
2874 get_ioctl_syscon()
2876 FILE *fp;
2877 unsigned int iflags, oflags, cflags, lflags, ldisc, cc[18];
2878 int i, valid_format = 0;
2881 * Read in the previous modes for SYSCON from IOCTLSYSCON.
2883 if ((fp = fopen(IOCTLSYSCON, "r")) == NULL) {
2884 stored_syscon_termios = dflt_termios;
2885 console(B_TRUE,
2886 "warning:%s does not exist, default settings assumed\n",
2887 IOCTLSYSCON);
2888 } else {
2890 i = fscanf(fp,
2891 "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
2892 &iflags, &oflags, &cflags, &lflags,
2893 &cc[0], &cc[1], &cc[2], &cc[3], &cc[4], &cc[5], &cc[6],
2894 &cc[7], &cc[8], &cc[9], &cc[10], &cc[11], &cc[12], &cc[13],
2895 &cc[14], &cc[15], &cc[16], &cc[17]);
2897 if (i == 22) {
2898 stored_syscon_termios.c_iflag = iflags;
2899 stored_syscon_termios.c_oflag = oflags;
2900 stored_syscon_termios.c_cflag = cflags;
2901 stored_syscon_termios.c_lflag = lflags;
2902 for (i = 0; i < 18; i++)
2903 stored_syscon_termios.c_cc[i] = (char)cc[i];
2904 valid_format = 1;
2905 } else if (i == 13) {
2906 rewind(fp);
2907 i = fscanf(fp, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
2908 &iflags, &oflags, &cflags, &lflags, &ldisc, &cc[0], &cc[1],
2909 &cc[2], &cc[3], &cc[4], &cc[5], &cc[6], &cc[7]);
2912 * If the file is formatted properly, use the values to
2913 * initialize the console terminal condition.
2915 stored_syscon_termios.c_iflag = (ushort_t)iflags;
2916 stored_syscon_termios.c_oflag = (ushort_t)oflags;
2917 stored_syscon_termios.c_cflag = (ushort_t)cflags;
2918 stored_syscon_termios.c_lflag = (ushort_t)lflags;
2919 for (i = 0; i < 8; i++)
2920 stored_syscon_termios.c_cc[i] = (char)cc[i];
2921 valid_format = 1;
2923 (void) fclose(fp);
2925 /* If the file is badly formatted, use the default settings. */
2926 if (!valid_format)
2927 stored_syscon_termios = dflt_termios;
2930 /* If the file had a bad format, rewrite it later. */
2931 return (!valid_format);
2935 static void
2936 write_ioctl_syscon()
2938 FILE *fp;
2939 int i;
2941 (void) unlink(SYSCON);
2942 (void) link(SYSTTY, SYSCON);
2943 (void) umask(022);
2944 fp = fopen(IOCTLSYSCON, "w");
2946 (void) fprintf(fp, "%x:%x:%x:%x:0", stored_syscon_termios.c_iflag,
2947 stored_syscon_termios.c_oflag, stored_syscon_termios.c_cflag,
2948 stored_syscon_termios.c_lflag);
2949 for (i = 0; i < 8; ++i)
2950 (void) fprintf(fp, ":%x", stored_syscon_termios.c_cc[i]);
2951 (void) putc('\n', fp);
2953 (void) fflush(fp);
2954 (void) fsync(fileno(fp));
2955 (void) fclose(fp);
2956 (void) umask(cmask);
2961 * void console(boolean_t, char *, ...)
2962 * Outputs the requested message to the system console. Note that the number
2963 * of arguments passed to console() should be determined by the print format.
2965 * The "prefix" parameter indicates whether or not "INIT: " should precede the
2966 * message.
2968 * To make sure we write to the console in a sane fashion, we use the modes
2969 * we keep in stored_syscon_termios (which we read out of /etc/ioctl.syscon).
2970 * Afterwards we restore whatever modes were already there.
2972 /* PRINTFLIKE2 */
2973 static void
2974 console(boolean_t prefix, char *format, ...)
2976 char outbuf[BUFSIZ];
2977 va_list args;
2978 int fd, getret;
2979 struct termios old_syscon_termios;
2980 FILE *f;
2983 * We open SYSCON anew each time in case it has changed (see
2984 * userinit()).
2986 if ((fd = open(SYSCON, O_RDWR | O_NOCTTY)) < 0 ||
2987 (f = fdopen(fd, "r+")) == NULL) {
2988 if (prefix)
2989 syslog(LOG_WARNING, "INIT: ");
2990 va_start(args, format);
2991 vsyslog(LOG_WARNING, format, args);
2992 va_end(args);
2993 if (fd >= 0)
2994 (void) close(fd);
2995 return;
2997 setbuf(f, &outbuf[0]);
2999 getret = tcgetattr(fd, &old_syscon_termios);
3000 old_syscon_termios.c_cflag &= ~HUPCL;
3001 if (realcon())
3002 /* Don't overwrite cflag of real console. */
3003 stored_syscon_termios.c_cflag = old_syscon_termios.c_cflag;
3005 stored_syscon_termios.c_cflag &= ~HUPCL;
3007 (void) tcsetattr(fd, TCSANOW, &stored_syscon_termios);
3009 if (prefix)
3010 (void) fprintf(f, "\nINIT: ");
3011 va_start(args, format);
3012 (void) vfprintf(f, format, args);
3013 va_end(args);
3015 if (getret == 0)
3016 (void) tcsetattr(fd, TCSADRAIN, &old_syscon_termios);
3018 (void) fclose(f);
3022 * timer() is a substitute for sleep() which uses alarm() and pause().
3024 static void
3025 timer(int waitime)
3027 setimer(waitime);
3028 while (time_up == FALSE)
3029 (void) pause();
3032 static void
3033 setimer(int timelimit)
3035 alarmclk();
3036 (void) alarm(timelimit);
3037 time_up = (timelimit ? FALSE : TRUE);
3041 * Fails with
3042 * ENOMEM - out of memory
3043 * ECONNABORTED - repository connection broken
3044 * EPERM - permission denied
3045 * EACCES - backend access denied
3046 * EROFS - backend readonly
3048 static int
3049 get_or_add_startd(scf_instance_t *inst)
3051 scf_handle_t *h;
3052 scf_scope_t *scope = NULL;
3053 scf_service_t *svc = NULL;
3054 int ret = 0;
3056 h = scf_instance_handle(inst);
3058 if (scf_handle_decode_fmri(h, SCF_SERVICE_STARTD, NULL, NULL, inst,
3059 NULL, NULL, SCF_DECODE_FMRI_EXACT) == 0)
3060 return (0);
3062 switch (scf_error()) {
3063 case SCF_ERROR_CONNECTION_BROKEN:
3064 return (ECONNABORTED);
3066 case SCF_ERROR_NOT_FOUND:
3067 break;
3069 case SCF_ERROR_HANDLE_MISMATCH:
3070 case SCF_ERROR_INVALID_ARGUMENT:
3071 case SCF_ERROR_CONSTRAINT_VIOLATED:
3072 default:
3073 bad_error("scf_handle_decode_fmri", scf_error());
3076 /* Make sure we're right, since we're adding piece-by-piece. */
3077 assert(strcmp(SCF_SERVICE_STARTD,
3078 "svc:/system/svc/restarter:default") == 0);
3080 if ((scope = scf_scope_create(h)) == NULL ||
3081 (svc = scf_service_create(h)) == NULL) {
3082 ret = ENOMEM;
3083 goto out;
3086 get_scope:
3087 if (scf_handle_get_scope(h, SCF_SCOPE_LOCAL, scope) != 0) {
3088 switch (scf_error()) {
3089 case SCF_ERROR_CONNECTION_BROKEN:
3090 ret = ECONNABORTED;
3091 goto out;
3093 case SCF_ERROR_NOT_FOUND:
3094 (void) fputs(gettext(
3095 "smf(5) repository missing local scope.\n"),
3096 stderr);
3097 exit(1);
3098 /* NOTREACHED */
3100 case SCF_ERROR_HANDLE_MISMATCH:
3101 case SCF_ERROR_INVALID_ARGUMENT:
3102 default:
3103 bad_error("scf_handle_get_scope", scf_error());
3107 get_svc:
3108 if (scf_scope_get_service(scope, "system/svc/restarter", svc) != 0) {
3109 switch (scf_error()) {
3110 case SCF_ERROR_CONNECTION_BROKEN:
3111 ret = ECONNABORTED;
3112 goto out;
3114 case SCF_ERROR_DELETED:
3115 goto get_scope;
3117 case SCF_ERROR_NOT_FOUND:
3118 break;
3120 case SCF_ERROR_HANDLE_MISMATCH:
3121 case SCF_ERROR_INVALID_ARGUMENT:
3122 case SCF_ERROR_NOT_SET:
3123 default:
3124 bad_error("scf_scope_get_service", scf_error());
3127 add_svc:
3128 if (scf_scope_add_service(scope, "system/svc/restarter", svc) !=
3129 0) {
3130 switch (scf_error()) {
3131 case SCF_ERROR_CONNECTION_BROKEN:
3132 ret = ECONNABORTED;
3133 goto out;
3135 case SCF_ERROR_EXISTS:
3136 goto get_svc;
3138 case SCF_ERROR_PERMISSION_DENIED:
3139 ret = EPERM;
3140 goto out;
3142 case SCF_ERROR_BACKEND_ACCESS:
3143 ret = EACCES;
3144 goto out;
3146 case SCF_ERROR_BACKEND_READONLY:
3147 ret = EROFS;
3148 goto out;
3150 case SCF_ERROR_HANDLE_MISMATCH:
3151 case SCF_ERROR_INVALID_ARGUMENT:
3152 case SCF_ERROR_NOT_SET:
3153 default:
3154 bad_error("scf_scope_add_service", scf_error());
3159 get_inst:
3160 if (scf_service_get_instance(svc, "default", inst) != 0) {
3161 switch (scf_error()) {
3162 case SCF_ERROR_CONNECTION_BROKEN:
3163 ret = ECONNABORTED;
3164 goto out;
3166 case SCF_ERROR_DELETED:
3167 goto add_svc;
3169 case SCF_ERROR_NOT_FOUND:
3170 break;
3172 case SCF_ERROR_HANDLE_MISMATCH:
3173 case SCF_ERROR_INVALID_ARGUMENT:
3174 case SCF_ERROR_NOT_SET:
3175 default:
3176 bad_error("scf_service_get_instance", scf_error());
3179 if (scf_service_add_instance(svc, "default", inst) !=
3180 0) {
3181 switch (scf_error()) {
3182 case SCF_ERROR_CONNECTION_BROKEN:
3183 ret = ECONNABORTED;
3184 goto out;
3186 case SCF_ERROR_DELETED:
3187 goto add_svc;
3189 case SCF_ERROR_EXISTS:
3190 goto get_inst;
3192 case SCF_ERROR_PERMISSION_DENIED:
3193 ret = EPERM;
3194 goto out;
3196 case SCF_ERROR_BACKEND_ACCESS:
3197 ret = EACCES;
3198 goto out;
3200 case SCF_ERROR_BACKEND_READONLY:
3201 ret = EROFS;
3202 goto out;
3204 case SCF_ERROR_HANDLE_MISMATCH:
3205 case SCF_ERROR_INVALID_ARGUMENT:
3206 case SCF_ERROR_NOT_SET:
3207 default:
3208 bad_error("scf_service_add_instance",
3209 scf_error());
3214 ret = 0;
3216 out:
3217 scf_service_destroy(svc);
3218 scf_scope_destroy(scope);
3219 return (ret);
3223 * Fails with
3224 * ECONNABORTED - repository connection broken
3225 * ECANCELED - the transaction's property group was deleted
3227 static int
3228 transaction_add_set(scf_transaction_t *tx, scf_transaction_entry_t *ent,
3229 const char *pname, scf_type_t type)
3231 change_type:
3232 if (scf_transaction_property_change_type(tx, ent, pname, type) == 0)
3233 return (0);
3235 switch (scf_error()) {
3236 case SCF_ERROR_CONNECTION_BROKEN:
3237 return (ECONNABORTED);
3239 case SCF_ERROR_DELETED:
3240 return (ECANCELED);
3242 case SCF_ERROR_NOT_FOUND:
3243 goto new;
3245 case SCF_ERROR_HANDLE_MISMATCH:
3246 case SCF_ERROR_INVALID_ARGUMENT:
3247 case SCF_ERROR_NOT_BOUND:
3248 case SCF_ERROR_NOT_SET:
3249 default:
3250 bad_error("scf_transaction_property_change_type", scf_error());
3253 new:
3254 if (scf_transaction_property_new(tx, ent, pname, type) == 0)
3255 return (0);
3257 switch (scf_error()) {
3258 case SCF_ERROR_CONNECTION_BROKEN:
3259 return (ECONNABORTED);
3261 case SCF_ERROR_DELETED:
3262 return (ECANCELED);
3264 case SCF_ERROR_EXISTS:
3265 goto change_type;
3267 case SCF_ERROR_HANDLE_MISMATCH:
3268 case SCF_ERROR_INVALID_ARGUMENT:
3269 case SCF_ERROR_NOT_BOUND:
3270 case SCF_ERROR_NOT_SET:
3271 default:
3272 bad_error("scf_transaction_property_new", scf_error());
3273 /* NOTREACHED */
3277 static void
3278 scferr(void)
3280 switch (scf_error()) {
3281 case SCF_ERROR_NO_MEMORY:
3282 console(B_TRUE, gettext("Out of memory.\n"));
3283 break;
3285 case SCF_ERROR_CONNECTION_BROKEN:
3286 console(B_TRUE, gettext(
3287 "Connection to smf(5) repository server broken.\n"));
3288 break;
3290 case SCF_ERROR_NO_RESOURCES:
3291 console(B_TRUE, gettext(
3292 "smf(5) repository server is out of memory.\n"));
3293 break;
3295 case SCF_ERROR_PERMISSION_DENIED:
3296 console(B_TRUE, gettext("Insufficient privileges.\n"));
3297 break;
3299 default:
3300 console(B_TRUE, gettext("libscf error: %s\n"),
3301 scf_strerror(scf_error()));
3305 static void
3306 lscf_set_runlevel(char rl)
3308 scf_handle_t *h;
3309 scf_instance_t *inst = NULL;
3310 scf_propertygroup_t *pg = NULL;
3311 scf_transaction_t *tx = NULL;
3312 scf_transaction_entry_t *ent = NULL;
3313 scf_value_t *val = NULL;
3314 char buf[2];
3315 int r;
3317 h = scf_handle_create(SCF_VERSION);
3318 if (h == NULL) {
3319 scferr();
3320 return;
3323 if (scf_handle_bind(h) != 0) {
3324 switch (scf_error()) {
3325 case SCF_ERROR_NO_SERVER:
3326 console(B_TRUE,
3327 gettext("smf(5) repository server not running.\n"));
3328 goto bail;
3330 default:
3331 scferr();
3332 goto bail;
3336 if ((inst = scf_instance_create(h)) == NULL ||
3337 (pg = scf_pg_create(h)) == NULL ||
3338 (val = scf_value_create(h)) == NULL ||
3339 (tx = scf_transaction_create(h)) == NULL ||
3340 (ent = scf_entry_create(h)) == NULL) {
3341 scferr();
3342 goto bail;
3345 get_inst:
3346 r = get_or_add_startd(inst);
3347 switch (r) {
3348 case 0:
3349 break;
3351 case ENOMEM:
3352 case ECONNABORTED:
3353 case EPERM:
3354 case EACCES:
3355 case EROFS:
3356 scferr();
3357 goto bail;
3358 default:
3359 bad_error("get_or_add_startd", r);
3362 get_pg:
3363 if (scf_instance_get_pg(inst, SCF_PG_OPTIONS_OVR, pg) != 0) {
3364 switch (scf_error()) {
3365 case SCF_ERROR_CONNECTION_BROKEN:
3366 scferr();
3367 goto bail;
3369 case SCF_ERROR_DELETED:
3370 goto get_inst;
3372 case SCF_ERROR_NOT_FOUND:
3373 break;
3375 case SCF_ERROR_HANDLE_MISMATCH:
3376 case SCF_ERROR_INVALID_ARGUMENT:
3377 case SCF_ERROR_NOT_SET:
3378 default:
3379 bad_error("scf_instance_get_pg", scf_error());
3382 add_pg:
3383 if (scf_instance_add_pg(inst, SCF_PG_OPTIONS_OVR,
3384 SCF_PG_OPTIONS_OVR_TYPE, SCF_PG_OPTIONS_OVR_FLAGS, pg) !=
3385 0) {
3386 switch (scf_error()) {
3387 case SCF_ERROR_CONNECTION_BROKEN:
3388 case SCF_ERROR_PERMISSION_DENIED:
3389 case SCF_ERROR_BACKEND_ACCESS:
3390 scferr();
3391 goto bail;
3393 case SCF_ERROR_DELETED:
3394 goto get_inst;
3396 case SCF_ERROR_EXISTS:
3397 goto get_pg;
3399 case SCF_ERROR_HANDLE_MISMATCH:
3400 case SCF_ERROR_INVALID_ARGUMENT:
3401 case SCF_ERROR_NOT_SET:
3402 default:
3403 bad_error("scf_instance_add_pg", scf_error());
3408 buf[0] = rl;
3409 buf[1] = '\0';
3410 r = scf_value_set_astring(val, buf);
3411 assert(r == 0);
3413 for (;;) {
3414 if (scf_transaction_start(tx, pg) != 0) {
3415 switch (scf_error()) {
3416 case SCF_ERROR_CONNECTION_BROKEN:
3417 case SCF_ERROR_PERMISSION_DENIED:
3418 case SCF_ERROR_BACKEND_ACCESS:
3419 scferr();
3420 goto bail;
3422 case SCF_ERROR_DELETED:
3423 goto add_pg;
3425 case SCF_ERROR_HANDLE_MISMATCH:
3426 case SCF_ERROR_NOT_BOUND:
3427 case SCF_ERROR_IN_USE:
3428 case SCF_ERROR_NOT_SET:
3429 default:
3430 bad_error("scf_transaction_start", scf_error());
3434 r = transaction_add_set(tx, ent, "runlevel", SCF_TYPE_ASTRING);
3435 switch (r) {
3436 case 0:
3437 break;
3439 case ECONNABORTED:
3440 scferr();
3441 goto bail;
3443 case ECANCELED:
3444 scf_transaction_reset(tx);
3445 goto add_pg;
3447 default:
3448 bad_error("transaction_add_set", r);
3451 r = scf_entry_add_value(ent, val);
3452 assert(r == 0);
3454 r = scf_transaction_commit(tx);
3455 if (r == 1)
3456 break;
3458 if (r != 0) {
3459 switch (scf_error()) {
3460 case SCF_ERROR_CONNECTION_BROKEN:
3461 case SCF_ERROR_PERMISSION_DENIED:
3462 case SCF_ERROR_BACKEND_ACCESS:
3463 case SCF_ERROR_BACKEND_READONLY:
3464 scferr();
3465 goto bail;
3467 case SCF_ERROR_DELETED:
3468 scf_transaction_reset(tx);
3469 goto add_pg;
3471 case SCF_ERROR_INVALID_ARGUMENT:
3472 case SCF_ERROR_NOT_BOUND:
3473 case SCF_ERROR_NOT_SET:
3474 default:
3475 bad_error("scf_transaction_commit",
3476 scf_error());
3480 scf_transaction_reset(tx);
3481 (void) scf_pg_update(pg);
3484 bail:
3485 scf_transaction_destroy(tx);
3486 scf_entry_destroy(ent);
3487 scf_value_destroy(val);
3488 scf_pg_destroy(pg);
3489 scf_instance_destroy(inst);
3491 (void) scf_handle_unbind(h);
3492 scf_handle_destroy(h);
3496 * Function to handle requests from users to main init running as process 1.
3498 static void
3499 userinit(int argc, char **argv)
3501 FILE *fp;
3502 char *ln;
3503 int init_signal;
3504 struct stat sconbuf, conbuf;
3505 const char *usage_msg = "Usage: init [0123456SsQqabc]\n";
3508 * We are a user invoked init. Is there an argument and is it
3509 * a single character? If not, print usage message and quit.
3511 if (argc != 2 || argv[1][1] != '\0') {
3512 (void) fprintf(stderr, usage_msg);
3513 exit(0);
3516 if ((init_signal = lvlname_to_state((char)argv[1][0])) == -1) {
3517 (void) fprintf(stderr, usage_msg);
3518 exit(1);
3521 if (init_signal == SINGLE_USER) {
3523 * Make sure this process is talking to a legal tty line
3524 * and that /dev/syscon is linked to this line.
3526 ln = ttyname(0); /* Get the name of tty */
3527 if (ln == NULL) {
3528 (void) fprintf(stderr,
3529 "Standard input not a tty line\n");
3530 exit(1);
3533 if ((stat(ln, &sconbuf) != -1) &&
3534 (stat(SYSCON, &conbuf) == -1 ||
3535 sconbuf.st_rdev != conbuf.st_rdev)) {
3537 * /dev/syscon needs to change.
3538 * Unlink /dev/syscon and relink it to the current line.
3540 if (lstat(SYSCON, &conbuf) != -1 &&
3541 unlink(SYSCON) == FAILURE) {
3542 perror("Can't unlink /dev/syscon");
3543 (void) fprintf(stderr,
3544 "Run command on the system console.\n");
3545 exit(1);
3547 if (symlink(ln, SYSCON) == FAILURE) {
3548 (void) fprintf(stderr,
3549 "Can't symlink /dev/syscon to %s: %s", ln,
3550 strerror(errno));
3552 /* Try to leave a syscon */
3553 (void) link(SYSTTY, SYSCON);
3554 exit(1);
3558 * Try to leave a message on system console saying where
3559 * /dev/syscon is currently connected.
3561 if ((fp = fopen(SYSTTY, "r+")) != NULL) {
3562 (void) fprintf(fp,
3563 "\n**** SYSCON CHANGED TO %s ****\n",
3564 ln);
3565 (void) fclose(fp);
3570 update_boot_archive(init_signal);
3573 * Signal init; init will take care of telling svc.startd.
3575 if (kill(init_pid, init_signal) == FAILURE) {
3576 (void) fprintf(stderr, "Must be super-user\n");
3577 exit(1);
3580 exit(0);
3584 #define DELTA 25 /* Number of pidlist elements to allocate at a time */
3586 /* ARGSUSED */
3587 void
3588 sigpoll(int n)
3590 struct pidrec prec;
3591 struct pidrec *p = &prec;
3592 struct pidlist *plp;
3593 struct pidlist *tp, *savetp;
3594 int i;
3596 if (Pfd < 0) {
3597 return;
3600 for (;;) {
3602 * Important Note: Either read will really fail (in which case
3603 * return is all we can do) or will get EAGAIN (Pfd was opened
3604 * O_NDELAY), in which case we also want to return.
3605 * Always return from here!
3607 if (read(Pfd, p, sizeof (struct pidrec)) !=
3608 sizeof (struct pidrec)) {
3609 return;
3611 switch (p->pd_type) {
3613 case ADDPID:
3615 * New "godchild", add to list.
3617 if (Plfree == NULL) {
3618 plp = (struct pidlist *)calloc(DELTA,
3619 sizeof (struct pidlist));
3620 if (plp == NULL) {
3621 /* Can't save pid */
3622 break;
3625 * Point at 2nd record allocated, we'll use plp.
3627 tp = plp + 1;
3629 * Link them into a chain.
3631 Plfree = tp;
3632 for (i = 0; i < DELTA - 2; i++) {
3633 tp->pl_next = tp + 1;
3634 tp++;
3636 } else {
3637 plp = Plfree;
3638 Plfree = plp->pl_next;
3640 plp->pl_pid = p->pd_pid;
3641 plp->pl_dflag = 0;
3642 plp->pl_next = NULL;
3644 * Note - pid list is kept in increasing order of pids.
3646 if (Plhead == NULL) {
3647 Plhead = plp;
3648 /* Back up to read next record */
3649 break;
3650 } else {
3651 savetp = tp = Plhead;
3652 while (tp) {
3653 if (plp->pl_pid > tp->pl_pid) {
3654 savetp = tp;
3655 tp = tp->pl_next;
3656 continue;
3657 } else if (plp->pl_pid < tp->pl_pid) {
3658 if (tp == Plhead) {
3659 plp->pl_next = Plhead;
3660 Plhead = plp;
3661 } else {
3662 plp->pl_next =
3663 savetp->pl_next;
3664 savetp->pl_next = plp;
3666 break;
3667 } else {
3668 /* Already in list! */
3669 plp->pl_next = Plfree;
3670 Plfree = plp;
3671 break;
3674 if (tp == NULL) {
3675 /* Add to end of list */
3676 savetp->pl_next = plp;
3679 /* Back up to read next record. */
3680 break;
3682 case REMPID:
3684 * This one was handled by someone else,
3685 * purge it from the list.
3687 if (Plhead == NULL) {
3688 /* Back up to read next record. */
3689 break;
3691 savetp = tp = Plhead;
3692 while (tp) {
3693 if (p->pd_pid > tp->pl_pid) {
3694 /* Keep on looking. */
3695 savetp = tp;
3696 tp = tp->pl_next;
3697 continue;
3698 } else if (p->pd_pid < tp->pl_pid) {
3699 /* Not in list. */
3700 break;
3701 } else {
3702 /* Found it. */
3703 if (tp == Plhead)
3704 Plhead = tp->pl_next;
3705 else
3706 savetp->pl_next = tp->pl_next;
3707 tp->pl_next = Plfree;
3708 Plfree = tp;
3709 break;
3712 /* Back up to read next record. */
3713 break;
3714 default:
3715 console(B_TRUE, "Bad message on initpipe\n");
3716 break;
3722 static void
3723 cleanaux()
3725 struct pidlist *savep, *p;
3726 pid_t pid;
3727 short status;
3729 (void) sighold(SIGCLD);
3730 Gchild = 0; /* Note - Safe to do this here since no SIGCLDs */
3731 (void) sighold(SIGPOLL);
3732 savep = p = Plhead;
3733 while (p) {
3734 if (p->pl_dflag) {
3736 * Found an entry to delete,
3737 * remove it from list first.
3739 pid = p->pl_pid;
3740 status = p->pl_exit;
3741 if (p == Plhead) {
3742 Plhead = p->pl_next;
3743 p->pl_next = Plfree;
3744 Plfree = p;
3745 savep = p = Plhead;
3746 } else {
3747 savep->pl_next = p->pl_next;
3748 p->pl_next = Plfree;
3749 Plfree = p;
3750 p = savep->pl_next;
3752 clearent(pid, status);
3753 continue;
3755 savep = p;
3756 p = p->pl_next;
3758 (void) sigrelse(SIGPOLL);
3759 (void) sigrelse(SIGCLD);
3764 * /etc/inittab has more entries and we have run out of room in the proc_table
3765 * array. Double the size of proc_table to accomodate the extra entries.
3767 static void
3768 increase_proc_table_size()
3770 sigset_t block, unblock;
3771 void *ptr;
3772 size_t delta = num_proc * sizeof (struct PROC_TABLE);
3776 * Block signals for realloc.
3778 (void) sigfillset(&block);
3779 (void) sigprocmask(SIG_BLOCK, &block, &unblock);
3783 * On failure we just return because callers of this function check
3784 * for failure.
3787 ptr = realloc(g_state, g_state_sz + delta);
3788 while (ptr == NULL && errno == EAGAIN)
3791 if (ptr != NULL) {
3792 /* ensure that the new part is initialized to zero */
3793 bzero((caddr_t)ptr + g_state_sz, delta);
3795 g_state = ptr;
3796 g_state_sz += delta;
3797 num_proc <<= 1;
3801 /* unblock our signals before returning */
3802 (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
3808 * Sanity check g_state.
3810 static int
3811 st_sane()
3813 int i;
3814 struct PROC_TABLE *ptp;
3817 /* Note: cur_state is encoded as a signal number */
3818 if (cur_state < 1 || cur_state == 9 || cur_state > 13)
3819 return (0);
3821 /* Check num_proc */
3822 if (g_state_sz != sizeof (struct init_state) + (num_proc - 1) *
3823 sizeof (struct PROC_TABLE))
3824 return (0);
3826 /* Check proc_table */
3827 for (i = 0, ptp = proc_table; i < num_proc; ++i, ++ptp) {
3828 /* skip unoccupied entries */
3829 if (!(ptp->p_flags & OCCUPIED))
3830 continue;
3832 /* p_flags has no bits outside of PF_MASK */
3833 if (ptp->p_flags & ~(PF_MASK))
3834 return (0);
3836 /* 5 <= pid <= MAXPID */
3837 if (ptp->p_pid < 5 || ptp->p_pid > MAXPID)
3838 return (0);
3840 /* p_count >= 0 */
3841 if (ptp->p_count < 0)
3842 return (0);
3844 /* p_time >= 0 */
3845 if (ptp->p_time < 0)
3846 return (0);
3849 return (1);
3853 * Initialize our state.
3855 * If the system just booted, then init_state_file, which is located on an
3856 * everpresent tmpfs filesystem, should not exist.
3858 * If we were restarted, then init_state_file should exist, in
3859 * which case we'll read it in, sanity check it, and use it.
3861 * Note: You can't call console() until proc_table is ready.
3863 void
3864 st_init()
3866 struct stat stb;
3867 int ret, st_fd, insane = 0;
3868 size_t to_be_read;
3869 char *ptr;
3872 booting = 1;
3874 do {
3876 * If we can exclusively create the file, then we're the
3877 * initial invocation of init(8).
3879 st_fd = open(init_state_file, O_RDWR | O_CREAT | O_EXCL,
3880 S_IRUSR | S_IWUSR);
3881 } while (st_fd == -1 && errno == EINTR);
3882 if (st_fd != -1)
3883 goto new_state;
3885 booting = 0;
3887 do {
3888 st_fd = open(init_state_file, O_RDWR, S_IRUSR | S_IWUSR);
3889 } while (st_fd == -1 && errno == EINTR);
3890 if (st_fd == -1)
3891 goto new_state;
3893 /* Get the size of the file. */
3895 ret = fstat(st_fd, &stb);
3896 while (ret == -1 && errno == EINTR)
3898 if (ret == -1)
3899 goto new_state;
3902 g_state = malloc(stb.st_size);
3903 while (g_state == NULL && errno == EAGAIN)
3905 if (g_state == NULL)
3906 goto new_state;
3908 to_be_read = stb.st_size;
3909 ptr = (char *)g_state;
3910 while (to_be_read > 0) {
3911 ssize_t read_ret;
3913 read_ret = read(st_fd, ptr, to_be_read);
3914 if (read_ret < 0) {
3915 if (errno == EINTR)
3916 continue;
3918 goto new_state;
3921 to_be_read -= read_ret;
3922 ptr += read_ret;
3925 (void) close(st_fd);
3927 g_state_sz = stb.st_size;
3929 if (st_sane()) {
3930 console(B_TRUE, "Restarting.\n");
3931 return;
3934 insane = 1;
3936 new_state:
3937 if (st_fd >= 0)
3938 (void) close(st_fd);
3939 else
3940 (void) unlink(init_state_file);
3942 free(g_state);
3944 /* Something went wrong, so allocate new state. */
3945 g_state_sz = sizeof (struct init_state) +
3946 ((init_num_proc - 1) * sizeof (struct PROC_TABLE));
3948 g_state = calloc(1, g_state_sz);
3949 while (g_state == NULL && errno == EAGAIN)
3951 if (g_state == NULL) {
3952 /* Fatal error! */
3953 exit(errno);
3956 g_state->ist_runlevel = -1;
3957 num_proc = init_num_proc;
3959 if (!booting) {
3960 console(B_TRUE, "Restarting.\n");
3962 /* Overwrite the bad state file. */
3963 st_write();
3965 if (!insane) {
3966 console(B_TRUE,
3967 "Error accessing persistent state file `%s'. "
3968 "Ignored.\n", init_state_file);
3969 } else {
3970 console(B_TRUE,
3971 "Persistent state file `%s' is invalid and was "
3972 "ignored.\n", init_state_file);
3978 * Write g_state out to the state file.
3980 void
3981 st_write()
3983 static int complained = 0;
3985 int st_fd;
3986 char *cp;
3987 size_t sz;
3988 ssize_t ret;
3991 do {
3992 st_fd = open(init_next_state_file,
3993 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
3994 } while (st_fd < 0 && errno == EINTR);
3995 if (st_fd < 0)
3996 goto err;
3998 cp = (char *)g_state;
3999 sz = g_state_sz;
4000 while (sz > 0) {
4001 ret = write(st_fd, cp, sz);
4002 if (ret < 0) {
4003 if (errno == EINTR)
4004 continue;
4006 goto err;
4009 sz -= ret;
4010 cp += ret;
4013 (void) close(st_fd);
4014 st_fd = -1;
4015 if (rename(init_next_state_file, init_state_file)) {
4016 (void) unlink(init_next_state_file);
4017 goto err;
4019 complained = 0;
4021 return;
4023 err:
4024 if (st_fd >= 0)
4025 (void) close(st_fd);
4027 if (!booting && !complained) {
4029 * Only complain after the filesystem should have come up.
4030 * And only do it once so we don't loop between console()
4031 * & efork().
4033 complained = 1;
4034 if (st_fd)
4035 console(B_TRUE, "Couldn't write persistent state "
4036 "file `%s'.\n", init_state_file);
4037 else
4038 console(B_TRUE, "Couldn't move persistent state "
4039 "file `%s' to `%s'.\n", init_next_state_file,
4040 init_state_file);
4045 * Create a contract with these parameters.
4047 static int
4048 contract_make_template(uint_t info, uint_t critical, uint_t fatal,
4049 uint64_t cookie)
4051 int fd, err;
4053 char *ioctl_tset_emsg =
4054 "Couldn't set \"%s\" contract template parameter: %s.\n";
4057 fd = open64(CTFS_ROOT "/process/template", O_RDWR);
4058 while (fd < 0 && errno == EINTR)
4060 if (fd < 0) {
4061 console(B_TRUE, "Couldn't create process template: %s.\n",
4062 strerror(errno));
4063 return (-1);
4066 if (err = ct_pr_tmpl_set_param(fd, CT_PR_INHERIT | CT_PR_REGENT))
4067 console(B_TRUE, "Contract set template inherit, regent "
4068 "failed: %s.\n", strerror(err));
4071 * These errors result in a misconfigured template, which is better
4072 * than no template at all, so warn but don't abort.
4074 if (err = ct_tmpl_set_informative(fd, info))
4075 console(B_TRUE, ioctl_tset_emsg, "informative", strerror(err));
4077 if (err = ct_tmpl_set_critical(fd, critical))
4078 console(B_TRUE, ioctl_tset_emsg, "critical", strerror(err));
4080 if (err = ct_pr_tmpl_set_fatal(fd, fatal))
4081 console(B_TRUE, ioctl_tset_emsg, "fatal", strerror(err));
4083 if (err = ct_tmpl_set_cookie(fd, cookie))
4084 console(B_TRUE, ioctl_tset_emsg, "cookie", strerror(err));
4086 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
4088 return (fd);
4092 * Create the templates and open an event file descriptor. We use dup2(2) to
4093 * get these descriptors away from the stdin/stdout/stderr group.
4095 static void
4096 contracts_init()
4098 int err, fd;
4101 * Create & configure a legacy template. We only want empty events so
4102 * we know when to abandon them.
4104 legacy_tmpl = contract_make_template(0, CT_PR_EV_EMPTY, CT_PR_EV_HWERR,
4105 ORDINARY_COOKIE);
4106 if (legacy_tmpl >= 0) {
4107 err = ct_tmpl_activate(legacy_tmpl);
4108 if (err != 0) {
4109 (void) close(legacy_tmpl);
4110 legacy_tmpl = -1;
4111 console(B_TRUE,
4112 "Couldn't activate legacy template (%s); "
4113 "legacy services will be in init's contract.\n",
4114 strerror(err));
4116 } else
4117 console(B_TRUE,
4118 "Legacy services will be in init's contract.\n");
4120 if (dup2(legacy_tmpl, 255) == -1) {
4121 console(B_TRUE, "Could not duplicate legacy template: %s.\n",
4122 strerror(errno));
4123 } else {
4124 (void) close(legacy_tmpl);
4125 legacy_tmpl = 255;
4128 (void) fcntl(legacy_tmpl, F_SETFD, FD_CLOEXEC);
4130 startd_tmpl = contract_make_template(0, CT_PR_EV_EMPTY,
4131 CT_PR_EV_HWERR | CT_PR_EV_SIGNAL | CT_PR_EV_CORE, STARTD_COOKIE);
4133 if (dup2(startd_tmpl, 254) == -1) {
4134 console(B_TRUE, "Could not duplicate startd template: %s.\n",
4135 strerror(errno));
4136 } else {
4137 (void) close(startd_tmpl);
4138 startd_tmpl = 254;
4141 (void) fcntl(startd_tmpl, F_SETFD, FD_CLOEXEC);
4143 if (legacy_tmpl < 0 && startd_tmpl < 0) {
4144 /* The creation errors have already been reported. */
4145 console(B_TRUE,
4146 "Ignoring contract events. Core smf(5) services will not "
4147 "be restarted.\n");
4148 return;
4152 * Open an event endpoint.
4155 fd = open64(CTFS_ROOT "/process/pbundle", O_RDONLY);
4156 while (fd < 0 && errno == EINTR)
4158 if (fd < 0) {
4159 console(B_TRUE,
4160 "Couldn't open process pbundle: %s. Core smf(5) services "
4161 "will not be restarted.\n", strerror(errno));
4162 return;
4165 if (dup2(fd, 253) == -1) {
4166 console(B_TRUE, "Could not duplicate process bundle: %s.\n",
4167 strerror(errno));
4168 } else {
4169 (void) close(fd);
4170 fd = 253;
4173 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
4175 /* Reset in case we've been restarted. */
4176 (void) ct_event_reset(fd);
4178 poll_fds[0].fd = fd;
4179 poll_fds[0].events = POLLIN;
4180 poll_nfds = 1;
4183 static int
4184 contract_getfile(ctid_t id, const char *name, int oflag)
4186 int fd;
4189 fd = contract_open(id, "process", name, oflag);
4190 while (fd < 0 && errno == EINTR)
4193 if (fd < 0)
4194 console(B_TRUE, "Couldn't open %s for contract %ld: %s.\n",
4195 name, id, strerror(errno));
4197 return (fd);
4200 static int
4201 contract_cookie(ctid_t id, uint64_t *cp)
4203 int fd, err;
4204 ct_stathdl_t sh;
4206 fd = contract_getfile(id, "status", O_RDONLY);
4207 if (fd < 0)
4208 return (-1);
4210 err = ct_status_read(fd, CTD_COMMON, &sh);
4211 if (err != 0) {
4212 console(B_TRUE, "Couldn't read status of contract %ld: %s.\n",
4213 id, strerror(err));
4214 (void) close(fd);
4215 return (-1);
4218 (void) close(fd);
4220 *cp = ct_status_get_cookie(sh);
4222 ct_status_free(sh);
4223 return (0);
4226 static void
4227 contract_ack(ct_evthdl_t e)
4229 int fd;
4231 if (ct_event_get_flags(e) & CTE_INFO)
4232 return;
4234 fd = contract_getfile(ct_event_get_ctid(e), "ctl", O_WRONLY);
4235 if (fd < 0)
4236 return;
4238 (void) ct_ctl_ack(fd, ct_event_get_evid(e));
4239 (void) close(fd);
4243 * Process a contract event.
4245 static void
4246 contract_event(struct pollfd *poll)
4248 ct_evthdl_t e;
4249 int err;
4250 ctid_t ctid;
4252 if (!(poll->revents & POLLIN)) {
4253 if (poll->revents & POLLERR)
4254 console(B_TRUE,
4255 "Unknown poll error on my process contract "
4256 "pbundle.\n");
4257 return;
4260 err = ct_event_read(poll->fd, &e);
4261 if (err != 0) {
4262 console(B_TRUE, "Error retrieving contract event: %s.\n",
4263 strerror(err));
4264 return;
4267 ctid = ct_event_get_ctid(e);
4269 if (ct_event_get_type(e) == CT_PR_EV_EMPTY) {
4270 uint64_t cookie;
4271 int ret, abandon = 1;
4273 /* If it's svc.startd, restart it. Else, abandon. */
4274 ret = contract_cookie(ctid, &cookie);
4276 if (ret == 0) {
4277 if (cookie == STARTD_COOKIE &&
4278 do_restart_startd) {
4279 if (smf_debug)
4280 console(B_TRUE, "Restarting "
4281 "svc.startd.\n");
4284 * Account for the failure. If the failure rate
4285 * exceeds a threshold, then drop to maintenance
4286 * mode.
4288 startd_record_failure();
4289 if (startd_failure_rate_critical())
4290 enter_maintenance();
4292 if (startd_tmpl < 0)
4293 console(B_TRUE,
4294 "Restarting svc.startd in "
4295 "improper contract (bad "
4296 "template).\n");
4298 (void) startd_run(startd_cline, startd_tmpl,
4299 ctid);
4301 abandon = 0;
4305 if (abandon && (err = contract_abandon_id(ctid))) {
4306 console(B_TRUE, "Couldn't abandon contract %ld: %s.\n",
4307 ctid, strerror(err));
4311 * No need to acknowledge the event since either way the
4312 * originating contract should be abandoned.
4314 } else {
4315 console(B_TRUE,
4316 "Received contract event of unexpected type %d from "
4317 "contract %ld.\n", ct_event_get_type(e), ctid);
4319 if ((ct_event_get_flags(e) & (CTE_INFO | CTE_ACK)) == 0)
4320 /* Allow unexpected critical events to be released. */
4321 contract_ack(e);
4324 ct_event_free(e);
4328 * svc.startd(8) Management
4332 * (Re)start svc.startd(8). old_ctid should be the contract ID of the old
4333 * contract, or 0 if we're starting it for the first time. If wait is true
4334 * we'll wait for and return the exit value of the child.
4336 static int
4337 startd_run(const char *cline, int tmpl, ctid_t old_ctid)
4339 int err, i, ret, did_activate;
4340 pid_t pid;
4341 struct stat sb;
4343 if (cline[0] == '\0')
4344 return (-1);
4347 * Don't restart startd if the system is rebooting or shutting down.
4349 do {
4350 ret = stat("/etc/svc/volatile/resetting", &sb);
4351 } while (ret == -1 && errno == EINTR);
4353 if (ret == 0) {
4354 if (smf_debug)
4355 console(B_TRUE, "Quiescing for reboot.\n");
4356 (void) pause();
4357 return (-1);
4360 err = ct_pr_tmpl_set_transfer(tmpl, old_ctid);
4361 if (err == EINVAL) {
4362 console(B_TRUE, "Remake startd_tmpl; reattempt transfer.\n");
4363 tmpl = startd_tmpl = contract_make_template(0, CT_PR_EV_EMPTY,
4364 CT_PR_EV_HWERR, STARTD_COOKIE);
4366 err = ct_pr_tmpl_set_transfer(tmpl, old_ctid);
4368 if (err != 0) {
4369 console(B_TRUE,
4370 "Couldn't set transfer parameter of contract template: "
4371 "%s.\n", strerror(err));
4374 if ((err = ct_pr_tmpl_set_svc_fmri(startd_tmpl,
4375 SCF_SERVICE_STARTD)) != 0)
4376 console(B_TRUE,
4377 "Can not set svc_fmri in contract template: %s\n",
4378 strerror(err));
4379 if ((err = ct_pr_tmpl_set_svc_aux(startd_tmpl,
4380 startd_svc_aux)) != 0)
4381 console(B_TRUE,
4382 "Can not set svc_aux in contract template: %s\n",
4383 strerror(err));
4384 did_activate = !(ct_tmpl_activate(tmpl));
4385 if (!did_activate)
4386 console(B_TRUE,
4387 "Template activation failed; not starting \"%s\" in "
4388 "proper contract.\n", cline);
4390 /* Hold SIGCLD so we can wait if necessary. */
4391 (void) sighold(SIGCLD);
4393 while ((pid = fork()) < 0) {
4394 if (errno == EPERM) {
4395 console(B_TRUE, "Insufficient permission to fork.\n");
4397 /* Now that's a doozy. */
4398 exit(1);
4401 console(B_TRUE,
4402 "fork() for svc.startd failed: %s. Will retry in 1 "
4403 "second...\n", strerror(errno));
4405 (void) sleep(1);
4407 /* Eventually give up? */
4410 if (pid == 0) {
4411 /* child */
4413 /* See the comment in efork() */
4414 for (i = SIGHUP; i <= SIGRTMAX; ++i) {
4415 if (i == SIGTTOU || i == SIGTTIN || i == SIGTSTP)
4416 (void) sigset(i, SIG_IGN);
4417 else
4418 (void) sigset(i, SIG_DFL);
4421 if (smf_options != NULL) {
4422 /* Put smf_options in the environment. */
4423 glob_envp[glob_envn] =
4424 malloc(sizeof ("SMF_OPTIONS=") - 1 +
4425 strlen(smf_options) + 1);
4427 if (glob_envp[glob_envn] != NULL) {
4428 /* LINTED */
4429 (void) sprintf(glob_envp[glob_envn],
4430 "SMF_OPTIONS=%s", smf_options);
4431 glob_envp[glob_envn+1] = NULL;
4432 } else {
4433 console(B_TRUE,
4434 "Could not set SMF_OPTIONS (%s).\n",
4435 strerror(errno));
4439 if (smf_debug)
4440 console(B_TRUE, "Executing svc.startd\n");
4442 (void) execle(SH, "INITSH", "-c", cline, NULL, glob_envp);
4444 console(B_TRUE, "Could not exec \"%s\" (%s).\n", SH,
4445 strerror(errno));
4447 exit(1);
4450 /* parent */
4452 if (did_activate) {
4453 if (legacy_tmpl < 0 || ct_tmpl_activate(legacy_tmpl) != 0)
4454 (void) ct_tmpl_clear(tmpl);
4457 /* Clear the old_ctid reference so the kernel can reclaim it. */
4458 if (old_ctid != 0)
4459 (void) ct_pr_tmpl_set_transfer(tmpl, 0);
4461 (void) sigrelse(SIGCLD);
4463 return (0);
4467 * void startd_record_failure(void)
4468 * Place the current time in our circular array of svc.startd failures.
4470 void
4471 startd_record_failure()
4473 int index = startd_failure_index++ % NSTARTD_FAILURE_TIMES;
4475 startd_failure_time[index] = gethrtime();
4479 * int startd_failure_rate_critical(void)
4480 * Return true if the average failure interval is less than the permitted
4481 * interval. Implicit success if insufficient measurements for an average
4482 * exist.
4485 startd_failure_rate_critical()
4487 int n = startd_failure_index;
4488 hrtime_t avg_ns = 0;
4490 if (startd_failure_index < NSTARTD_FAILURE_TIMES)
4491 return (0);
4493 avg_ns =
4494 (startd_failure_time[(n - 1) % NSTARTD_FAILURE_TIMES] -
4495 startd_failure_time[n % NSTARTD_FAILURE_TIMES]) /
4496 NSTARTD_FAILURE_TIMES;
4498 return (avg_ns < STARTD_FAILURE_RATE_NS);