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]
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
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
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.
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.
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>
94 #include <sys/statvfs.h>
95 #include <sys/stropts.h>
96 #include <sys/systeminfo.h>
98 #include <sys/termios.h>
100 #include <sys/types.h>
101 #include <sys/utsname.h>
103 #include <security/pam_appl.h>
110 #include <libcontract.h>
111 #include <libcontract_priv.h>
114 #include <libscf_priv.h>
120 #include <stdio_ext.h>
131 #include <ucontext.h>
135 #define fioctl(p, sptr, cmd) ioctl(fileno(p), sptr, cmd)
136 #define min(a, b) (((a) < (b)) ? (a) : (b))
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.
157 * EXEC The length of the prefix string added to all comamnds
160 #define EXEC (sizeof ("exec ") - 1)
163 * TWARN The amount of time between warning signal, SIGTERM,
164 * and the fatal kill signal, SIGKILL.
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.
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.
199 #define SINGLE_USER SIGBUS
205 * Bit Mask for each level. Used to determine legal levels.
214 #define MASKSU 0x0080
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 */
234 static lvl_t lvls
[] = {
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 */
269 #define M_RESPAWN 0002
270 #define M_ONDEMAND M_RESPAWN
274 #define M_BOOTWAIT 0040
277 #define M_INITDEFAULT 0400
278 #define M_SYSINIT 01000
280 /* States for the inittab parser in getcmd(). */
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)
307 char p_id
[INITTAB_ENTRY_ID_SIZE
]; /* Four letter unique id of */
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 */
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.
349 #define DEMANDREQUEST 020
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
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))
383 char c_id
[INITTAB_ENTRY_ID_SIZE
]; /* Four letter unique id of */
384 /* process to be affected by */
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 */
392 int pd_type
; /* Command type */
393 pid_t pd_pid
; /* pid to add or remove */
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 */
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
,
424 static struct termios stored_syscon_termios
;
425 static int write_ioctl
= 0; /* Rewrite /etc/ioctl.syscon */
427 static union WAKEUP
{
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 */
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
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)); \
461 #define bad_error(func, err) abort()
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 */
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();
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
;
607 /* Get a timestamp for use as boot time, if needed. */
608 (void) time(&init_boot_time
);
610 /* Get the default umask */
614 /* Parse the arguments to init. Check for single user */
616 while ((c
= getopt(argc
, argv
, "brsm:")) != EOF
) {
633 smf_options
= optarg
;
634 smf_debug
= (strstr(smf_options
, "debug") != NULL
);
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");
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
) {
662 * Initialize state (and set "booting").
666 if (booting
&& print_banner
) {
668 char buf
[BUFSIZ
], *isa
;
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.
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) {
692 "\n\n%s Release %s Version %s %d-bit\r\n",
693 un
.sysname
, un
.release
, un
.version
, bits
);
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
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.
715 /* Load glob_envp from ENVFILE. */
721 /* cur_state should have been read in. */
723 op_modes
= NORMAL_MODES
;
725 /* Rewrite the ioctl file if it was bad. */
727 write_ioctl_syscon();
730 * It's fine to boot up with state as zero, because
731 * startd will later tell us the real state.
734 op_modes
= BOOT_MODES
;
739 prev_state
= prior_state
= cur_state
;
744 * Here is the beginning of the main process loop.
749 lvlq_received
= B_FALSE
;
753 * Clean up any accounting records for dead "godchildren".
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
)
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.
772 chg_lvl_flag
= FALSE
;
774 if (state_to_flags(cur_state
) & LSEL_RUNLEVEL
) {
775 char rl
= state_to_name(cur_state
);
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. */
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
812 if (wakeup
.w_flags
.w_powerhit
) {
815 * Make sure that cur_state != prev_state so that
816 * ONCE and WAIT types work.
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
||
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
;
843 prev_state
= cur_state
;
845 if (wakeup
.w_mask
== 0) {
849 * "init" is finished with all actions for
850 * the current wakeup.
852 ret
= poll(poll_fds
, poll_nfds
,
853 SLEEPTIME
* MILLISEC
);
856 contract_event(&poll_fds
[0]);
857 else if (ret
< 0 && errno
!= EINTR
)
858 console(B_TRUE
, "poll() error: %s\n",
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
869 if (new_state
!= cur_state
) {
870 if (new_state
== LVLa
||
873 prev_state
= prior_state
;
874 prior_state
= cur_state
;
875 cur_state
= new_state
;
877 prev_state
= cur_state
;
879 prior_state
= cur_state
;
880 cur_state
= new_state
;
888 if (wakeup
.w_flags
.w_powerhit
)
892 * Clear all wakeup reasons.
902 update_boot_archive(int new_state
)
904 if (new_state
!= LVL0
&& new_state
!= LVL5
&& new_state
!= LVL6
)
907 if (getzoneid() != GLOBAL_ZONEID
)
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.
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
)
929 (void) sigrelse(SIGCLD
);
930 if (su_process
== NULLPROC
) {
933 (void) fclose(stdin
);
934 (void) fclose(stdout
);
935 (void) fclose(stderr
);
938 fd
= open(SYSCON
, O_RDWR
| O_NOCTTY
);
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
,
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().
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.
982 struct PROC_TABLE
*process
;
984 char cmd_string
[MAXCMDL
];
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
))
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
1034 process
->p_flags
|= TOUCHED
;
1036 if ((process
->p_flags
& KILLED
) == 0) {
1045 * Fork a killing proc
1048 * having to pause for
1054 process
->p_flags
|= KILLED
;
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
1067 if (process
->p_flags
&
1068 (LIVING
|NOCLEANUP
|DEMANDREQUEST
))
1069 process
->p_flags
|= TOUCHED
;
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.
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.
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
))
1110 if (time_up
== TRUE
)
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
);
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
)) ==
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;
1164 * Extract the svc.startd command line and whether to restart it from its
1169 process_startd_line(struct CMD_LINE
*cmd
, char *cmd_string
)
1173 /* Save the command line. */
1175 /* Also append -r or -s. */
1176 (void) strlcpy(startd_cline
, cmd_string
, sizeof (startd_cline
));
1177 (void) strlcat(startd_cline
, " -", sizeof (startd_cline
));
1179 sz
= strlcat(startd_cline
, "s", sizeof (startd_cline
));
1181 sz
= strlcat(startd_cline
, "r", sizeof (startd_cline
));
1183 sz
= strlcpy(startd_cline
, cmd_string
, sizeof (startd_cline
));
1186 if (sz
>= sizeof (startd_cline
)) {
1188 "svc.startd command line too long. Ignoring.\n");
1189 startd_cline
[0] = '\0';
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.
1201 struct PROC_TABLE
*pp
;
1202 struct CMD_LINE cmd
;
1203 char cmd_string
[MAXCMDL
];
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
);
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
) {
1262 * If the action is not an action we are interested in,
1265 if ((cmd
.c_action
& op_modes
) == 0 || pp
->p_flags
& LIVING
||
1266 (cmd
.c_levels
& lvl_mask
) == 0)
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
))
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
)) {
1295 while (waitproc(pp
) == FAILURE
)
1297 (void) account(DEAD_PROCESS
, pp
, NULL
);
1305 * spawn() spawns a shell, inserts the information about the process
1306 * process into the proc_table, and does the startup accounting.
1309 spawn(struct PROC_TABLE
*process
, struct CMD_LINE
*cmd
)
1312 int modes
, maxfiles
;
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.
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)
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.
1341 * If no time is assigned, then this is the first time
1342 * this command is being processed in this series. Assign
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"
1358 &cmd
->c_id
[0], &cmd
->c_command
[EXEC
]);
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
)
1372 process
->p_time
= now
;
1373 process
->p_count
= 0;
1379 * Spawn a child process to execute this command.
1381 (void) sighold(SIGCLD
);
1383 while ((process
= efork(cmd
->c_action
, oprocess
, modes
)) == NO_ROOM
)
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.
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();
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
1415 (void) execle(SH
, "INITSH", "-c", cmd
->c_command
, (char *)0,
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".
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];
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
))
1460 * If the entry is totally empty and "empty" is still 0,
1461 * remember where this hole is and make sure the slot is
1464 if (empty
== NULLPROC
&& (process
->p_flags
& OCCUPIED
) == 0) {
1466 process
->p_id
[0] = '\0';
1467 process
->p_id
[1] = '\0';
1468 process
->p_id
[2] = '\0';
1469 process
->p_id
[3] = '\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
))
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
;
1500 getcmd(struct CMD_LINE
*cmd
, char *shcmd
)
1503 int c
, lastc
, state
;
1505 int answer
, i
, proceed
;
1507 static char *actions
[] = {
1508 "off", "respawn", "ondemand", "once", "wait", "boot",
1509 "bootwait", "powerfail", "powerwait", "initdefault",
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) {
1533 "Cannot stat %s, errno: %d\n",
1539 } else if (sbuf
.st_size
< 10) {
1542 "%s truncated or corrupted\n",
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
,
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.
1583 if ((c
= fgetc(fp_inittab
)) == EOF
) {
1585 (void) fclose(fp_inittab
);
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 */
1597 if (state
!= FAILURE
&& state
!= COMMAND
) {
1599 * Squeeze out spaces and tabs.
1601 if (c
== ' ' || c
== '\t')
1605 * Ignore characters in a comment, except for the \n.
1607 if (state
== COMMENT
) {
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
) {
1628 * If the character is a ':', then check the
1629 * previous field for correctness and advance
1630 * to the next field.
1637 * Check to see that there are only
1638 * 1 to 4 characters for the id.
1640 if ((i
= ptr
- shcmd
) < 1 || i
> 4) {
1643 bcopy(shcmd
, &cmd
->c_id
[0], i
);
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
++) {
1657 if (lvlname_to_mask(*ptr1
,
1662 cmd
->c_levels
|= mask
;
1664 if (state
!= FAILURE
) {
1666 ptr
= shcmd
; /* Reset the buffer */
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".
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
;
1688 cmd
->c_action
= M_OFF
;
1690 for (cmd
->c_action
= 0, i
= 0,
1693 sizeof (actions
)/sizeof (char *);
1695 if (strcmp(shcmd
, actions
[i
]) == 0) {
1696 if ((cmd
->c_levels
& MASKSU
) &&
1697 !(act_masks
[i
] & su_acts
))
1708 * If the action didn't match any legal action,
1709 * set state to FAILURE.
1711 if (cmd
->c_action
== 0) {
1715 (void) strcpy(shcmd
, "exec ");
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
!= '\\') {
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)
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
== '\\')
1755 * Make sure all the fields are properly specified
1756 * for a good command line.
1758 if (state
== COMMAND
) {
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
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
)
1786 * If we have reached the end of inittab, then close it
1787 * and quit trying to find a good command line.
1790 (void) fclose(fp_inittab
);
1799 * lvlname_to_state(): convert the character name of a state to its level
1800 * (its corresponding signal number).
1803 lvlname_to_state(char name
)
1806 for (i
= 0; i
< LVL_NELEMS
; i
++) {
1807 if (lvls
[i
].lvl_name
== name
)
1808 return (lvls
[i
].lvl_state
);
1814 * state_to_name(): convert the level to the character name.
1817 state_to_name(int state
)
1820 for (i
= 0; i
< LVL_NELEMS
; i
++) {
1821 if (lvls
[i
].lvl_state
== state
)
1822 return (lvls
[i
].lvl_name
);
1828 * state_to_mask(): return the mask corresponding to a signal number
1831 state_to_mask(int state
)
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
1845 lvlname_to_mask(char name
, int *mask
)
1848 for (i
= 0; i
< LVL_NELEMS
; i
++) {
1849 if (lvls
[i
].lvl_name
== name
) {
1850 *mask
= lvls
[i
].lvl_mask
;
1858 * state_to_flags(): return the flags corresponding to a runlevel. These
1859 * indicate properties of that runlevel.
1862 state_to_flags(int state
)
1865 for (i
= 0; i
< LVL_NELEMS
; i
++) {
1866 if (lvls
[i
].lvl_state
== state
)
1867 return (lvls
[i
].lvl_flags
);
1873 * killproc() creates a child which kills the process specified by pid.
1878 struct PROC_TABLE
*process
;
1880 (void) sighold(SIGCLD
);
1881 while ((process
= efork(M_OFF
, NULLPROC
, 0)) == NO_ROOM
)
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
);
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.
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
);
1924 malloc((unsigned)(strlen("_DVFS_RECONFIG=YES")+2));
1925 (void) strcpy(glob_envp
[1], "_DVFS_RECONFIG=YES");
1927 } else if (bflg
== 1) {
1929 malloc((unsigned)(strlen("RB_NOBOOTRC=YES")+2));
1930 (void) strcpy(glob_envp
[1], "RB_NOBOOTRC=YES");
1934 if ((fp
= fopen(ENVFILE
, "r")) == NULL
) {
1936 "Cannot open %s. Environment not initialized.\n",
1939 while (fgets(line
, MAXCMDL
- 1, fp
) != NULL
&&
1940 glob_envn
< MAXENVENT
- 2) {
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")) ==
1954 strchr(line
, '#') == line
+ wslength
)
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.
1963 for (cp1
= line
; *cp1
!= '\0'; cp1
++) {
1969 } else if (*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
)
1984 if (strchr(tokp
, '=') == NULL
)
1986 length
= strlen(tokp
);
1987 while ((cp1
= strpbrk(tokp
, "\"\'")) != NULL
) {
1989 cp2
< &tokp
[length
]; cp2
++)
1994 if (strncmp(tokp
, "CMASK=",
1995 sizeof ("CMASK=") - 1) == 0) {
1998 /* We know there's an = */
1999 t
= strtol(strchr(tokp
, '=') + 1, NULL
,
2003 if (t
<= 077 && t
>= 0)
2005 (void) umask(cmask
);
2008 glob_envp
[glob_envn
] =
2009 malloc((unsigned)(length
+ 1));
2010 (void) strcpy(glob_envp
[glob_envn
], tokp
);
2011 if (++glob_envn
>= MAXENVENT
- 1)
2013 } while ((tokp
= strtok(NULL
, " \t")) != NULL
);
2017 * Append a null pointer to the environment array
2020 glob_envp
[glob_envn
] = NULL
;
2026 * boot_init(): Do initialization things that should be done at boot.
2032 struct PROC_TABLE
*process
, *oprocess
;
2033 struct CMD_LINE cmd
;
2035 char svc_aux
[SVC_AUX_SIZE
];
2036 char init_svc_fmri
[SVC_FMRI_SIZE
];
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
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
,
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
;
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
,
2096 (void) execle(SH
, "INITSH", "-c",
2098 (char *)0, glob_envp
);
2100 "Command\n\"%s\"\n failed to execute. errno = %d (exec of shell failed)\n",
2101 cmd
.c_command
, errno
);
2104 while (waitproc(process
) == FAILURE
)
2106 process
->p_flags
= 0;
2112 /* Restore the path. */
2114 glob_envp
[0] = old_path
;
2117 * This will enable st_write() to complain about init_state_file.
2122 * If the /etc/ioctl.syscon didn't exist or had invalid contents write
2123 * out a correct version.
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
;
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.
2148 struct sigaction act
;
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
);
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.
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
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
);
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
);
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
;
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.
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
;
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
2292 new_state
= cur_state
;
2293 lvlq_received
= B_TRUE
;
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;
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.
2347 childeath_single(pid_t pid
, int status
)
2349 struct PROC_TABLE
*process
;
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;
2374 * No process was found above, look through auxiliary list.
2376 (void) sighold(SIGPOLL
);
2379 if (pid
> pp
->pl_pid
) {
2385 } else if (pid
< pp
->pl_pid
) {
2392 * This is a dead "godchild".
2395 pp
->pl_exit
= (short)status
;
2396 wakeup
.w_flags
.w_childdeath
= 1;
2397 Gchild
= 1; /* Notice to call cleanaux(). */
2402 (void) sigrelse(SIGPOLL
);
2407 childeath(int signo
)
2412 while ((pid
= waitpid(-1, &status
, WNOHANG
)) > 0)
2413 childeath_single(pid
, status
);
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
)
2441 struct PROC_TABLE
*proc
;
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
)) ==
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.
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.
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
);
2478 (void) sighold(SIGCLD
);
2482 if (childpid
!= 0) {
2484 if (process
== NULLPROC
) {
2486 * No proc table pointer specified so search
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 */
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;
2520 if ((action
& (M_WAIT
| M_BOOTWAIT
)) == 0)
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
);
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.
2554 waitproc(struct PROC_TABLE
*process
)
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
)
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;
2595 * notify_pam_dead(): calls into the PAM framework to close the given session.
2598 notify_pam_dead(struct utmpx
*up
)
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).
2628 utmpx_ok
= (access(UTMPX
, R_OK
|W_OK
) == 0);
2629 } while (!utmpx_ok
&& errno
== EINTR
);
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.
2644 account(short state
, struct PROC_TABLE
*process
, char *program
)
2646 struct utmpx utmpbuf
, *u
, *oldu
;
2648 char fail_buf
[UT_LINE_SZ
];
2649 sigset_t block
, unblock
;
2651 if (!utmpx_ok
&& !access_utmpx()) {
2656 * Set up the prototype for the utmp structure we want to write.
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
);
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.
2713 (void) strncpy(u
->ut_user
, program
, sizeof (u
->ut_user
));
2714 (void) strcpy(fail_buf
, "INIT_PROCESS");
2718 (void) strlcpy(fail_buf
, u
->ut_id
, sizeof (u
->ut_id
) + 1);
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
));
2729 (void) sigprocmask(SIG_SETMASK
, &unblock
, NULL
);
2734 * If we're able to write to utmpx, then attempt to add to the
2735 * end of the wtmpx file.
2741 (void) sigprocmask(SIG_SETMASK
, &unblock
, NULL
);
2747 clearent(pid_t pid
, short status
)
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.
2763 while (up
= getutxent()) {
2764 if (up
->ut_pid
== pid
) {
2765 if (up
->ut_type
== DEAD_PROCESS
) {
2767 * Cleaned up elsewhere.
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
);
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.
2800 prog_name(char *string
)
2803 static char word
[UT_USER_SZ
+ 1];
2806 * Search for the first word skipping leading spaces and tabs.
2808 while (*string
== ' ' || *string
== '\t')
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
2816 if (*string
!= '.' && *string
!= '/' && *string
!= '_' &&
2817 (*string
< 'a' || *string
> 'z') &&
2818 (*string
< 'A' || * string
> 'Z') &&
2819 (*string
< '0' || *string
> '9'))
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
++) {
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 */)
2848 * realcon() returns a nonzero value if there is a character device
2849 * associated with SYSCON that has the same device number as CONSOLE.
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
) {
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)
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
;
2886 "warning:%s does not exist, default settings assumed\n",
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]);
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
];
2905 } else if (i
== 13) {
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
];
2925 /* If the file is badly formatted, use the default settings. */
2927 stored_syscon_termios
= dflt_termios
;
2930 /* If the file had a bad format, rewrite it later. */
2931 return (!valid_format
);
2936 write_ioctl_syscon()
2941 (void) unlink(SYSCON
);
2942 (void) link(SYSTTY
, SYSCON
);
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
);
2954 (void) fsync(fileno(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
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.
2974 console(boolean_t prefix
, char *format
, ...)
2976 char outbuf
[BUFSIZ
];
2979 struct termios old_syscon_termios
;
2983 * We open SYSCON anew each time in case it has changed (see
2986 if ((fd
= open(SYSCON
, O_RDWR
| O_NOCTTY
)) < 0 ||
2987 (f
= fdopen(fd
, "r+")) == NULL
) {
2989 syslog(LOG_WARNING
, "INIT: ");
2990 va_start(args
, format
);
2991 vsyslog(LOG_WARNING
, format
, args
);
2997 setbuf(f
, &outbuf
[0]);
2999 getret
= tcgetattr(fd
, &old_syscon_termios
);
3000 old_syscon_termios
.c_cflag
&= ~HUPCL
;
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
);
3010 (void) fprintf(f
, "\nINIT: ");
3011 va_start(args
, format
);
3012 (void) vfprintf(f
, format
, args
);
3016 (void) tcsetattr(fd
, TCSADRAIN
, &old_syscon_termios
);
3022 * timer() is a substitute for sleep() which uses alarm() and pause().
3028 while (time_up
== FALSE
)
3033 setimer(int timelimit
)
3036 (void) alarm(timelimit
);
3037 time_up
= (timelimit
? FALSE
: TRUE
);
3042 * ENOMEM - out of memory
3043 * ECONNABORTED - repository connection broken
3044 * EPERM - permission denied
3045 * EACCES - backend access denied
3046 * EROFS - backend readonly
3049 get_or_add_startd(scf_instance_t
*inst
)
3052 scf_scope_t
*scope
= NULL
;
3053 scf_service_t
*svc
= NULL
;
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)
3062 switch (scf_error()) {
3063 case SCF_ERROR_CONNECTION_BROKEN
:
3064 return (ECONNABORTED
);
3066 case SCF_ERROR_NOT_FOUND
:
3069 case SCF_ERROR_HANDLE_MISMATCH
:
3070 case SCF_ERROR_INVALID_ARGUMENT
:
3071 case SCF_ERROR_CONSTRAINT_VIOLATED
:
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
) {
3087 if (scf_handle_get_scope(h
, SCF_SCOPE_LOCAL
, scope
) != 0) {
3088 switch (scf_error()) {
3089 case SCF_ERROR_CONNECTION_BROKEN
:
3093 case SCF_ERROR_NOT_FOUND
:
3094 (void) fputs(gettext(
3095 "smf(5) repository missing local scope.\n"),
3100 case SCF_ERROR_HANDLE_MISMATCH
:
3101 case SCF_ERROR_INVALID_ARGUMENT
:
3103 bad_error("scf_handle_get_scope", scf_error());
3108 if (scf_scope_get_service(scope
, "system/svc/restarter", svc
) != 0) {
3109 switch (scf_error()) {
3110 case SCF_ERROR_CONNECTION_BROKEN
:
3114 case SCF_ERROR_DELETED
:
3117 case SCF_ERROR_NOT_FOUND
:
3120 case SCF_ERROR_HANDLE_MISMATCH
:
3121 case SCF_ERROR_INVALID_ARGUMENT
:
3122 case SCF_ERROR_NOT_SET
:
3124 bad_error("scf_scope_get_service", scf_error());
3128 if (scf_scope_add_service(scope
, "system/svc/restarter", svc
) !=
3130 switch (scf_error()) {
3131 case SCF_ERROR_CONNECTION_BROKEN
:
3135 case SCF_ERROR_EXISTS
:
3138 case SCF_ERROR_PERMISSION_DENIED
:
3142 case SCF_ERROR_BACKEND_ACCESS
:
3146 case SCF_ERROR_BACKEND_READONLY
:
3150 case SCF_ERROR_HANDLE_MISMATCH
:
3151 case SCF_ERROR_INVALID_ARGUMENT
:
3152 case SCF_ERROR_NOT_SET
:
3154 bad_error("scf_scope_add_service", scf_error());
3160 if (scf_service_get_instance(svc
, "default", inst
) != 0) {
3161 switch (scf_error()) {
3162 case SCF_ERROR_CONNECTION_BROKEN
:
3166 case SCF_ERROR_DELETED
:
3169 case SCF_ERROR_NOT_FOUND
:
3172 case SCF_ERROR_HANDLE_MISMATCH
:
3173 case SCF_ERROR_INVALID_ARGUMENT
:
3174 case SCF_ERROR_NOT_SET
:
3176 bad_error("scf_service_get_instance", scf_error());
3179 if (scf_service_add_instance(svc
, "default", inst
) !=
3181 switch (scf_error()) {
3182 case SCF_ERROR_CONNECTION_BROKEN
:
3186 case SCF_ERROR_DELETED
:
3189 case SCF_ERROR_EXISTS
:
3192 case SCF_ERROR_PERMISSION_DENIED
:
3196 case SCF_ERROR_BACKEND_ACCESS
:
3200 case SCF_ERROR_BACKEND_READONLY
:
3204 case SCF_ERROR_HANDLE_MISMATCH
:
3205 case SCF_ERROR_INVALID_ARGUMENT
:
3206 case SCF_ERROR_NOT_SET
:
3208 bad_error("scf_service_add_instance",
3217 scf_service_destroy(svc
);
3218 scf_scope_destroy(scope
);
3224 * ECONNABORTED - repository connection broken
3225 * ECANCELED - the transaction's property group was deleted
3228 transaction_add_set(scf_transaction_t
*tx
, scf_transaction_entry_t
*ent
,
3229 const char *pname
, scf_type_t type
)
3232 if (scf_transaction_property_change_type(tx
, ent
, pname
, type
) == 0)
3235 switch (scf_error()) {
3236 case SCF_ERROR_CONNECTION_BROKEN
:
3237 return (ECONNABORTED
);
3239 case SCF_ERROR_DELETED
:
3242 case SCF_ERROR_NOT_FOUND
:
3245 case SCF_ERROR_HANDLE_MISMATCH
:
3246 case SCF_ERROR_INVALID_ARGUMENT
:
3247 case SCF_ERROR_NOT_BOUND
:
3248 case SCF_ERROR_NOT_SET
:
3250 bad_error("scf_transaction_property_change_type", scf_error());
3254 if (scf_transaction_property_new(tx
, ent
, pname
, type
) == 0)
3257 switch (scf_error()) {
3258 case SCF_ERROR_CONNECTION_BROKEN
:
3259 return (ECONNABORTED
);
3261 case SCF_ERROR_DELETED
:
3264 case SCF_ERROR_EXISTS
:
3267 case SCF_ERROR_HANDLE_MISMATCH
:
3268 case SCF_ERROR_INVALID_ARGUMENT
:
3269 case SCF_ERROR_NOT_BOUND
:
3270 case SCF_ERROR_NOT_SET
:
3272 bad_error("scf_transaction_property_new", scf_error());
3280 switch (scf_error()) {
3281 case SCF_ERROR_NO_MEMORY
:
3282 console(B_TRUE
, gettext("Out of memory.\n"));
3285 case SCF_ERROR_CONNECTION_BROKEN
:
3286 console(B_TRUE
, gettext(
3287 "Connection to smf(5) repository server broken.\n"));
3290 case SCF_ERROR_NO_RESOURCES
:
3291 console(B_TRUE
, gettext(
3292 "smf(5) repository server is out of memory.\n"));
3295 case SCF_ERROR_PERMISSION_DENIED
:
3296 console(B_TRUE
, gettext("Insufficient privileges.\n"));
3300 console(B_TRUE
, gettext("libscf error: %s\n"),
3301 scf_strerror(scf_error()));
3306 lscf_set_runlevel(char rl
)
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
;
3317 h
= scf_handle_create(SCF_VERSION
);
3323 if (scf_handle_bind(h
) != 0) {
3324 switch (scf_error()) {
3325 case SCF_ERROR_NO_SERVER
:
3327 gettext("smf(5) repository server not running.\n"));
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
) {
3346 r
= get_or_add_startd(inst
);
3359 bad_error("get_or_add_startd", r
);
3363 if (scf_instance_get_pg(inst
, SCF_PG_OPTIONS_OVR
, pg
) != 0) {
3364 switch (scf_error()) {
3365 case SCF_ERROR_CONNECTION_BROKEN
:
3369 case SCF_ERROR_DELETED
:
3372 case SCF_ERROR_NOT_FOUND
:
3375 case SCF_ERROR_HANDLE_MISMATCH
:
3376 case SCF_ERROR_INVALID_ARGUMENT
:
3377 case SCF_ERROR_NOT_SET
:
3379 bad_error("scf_instance_get_pg", scf_error());
3383 if (scf_instance_add_pg(inst
, SCF_PG_OPTIONS_OVR
,
3384 SCF_PG_OPTIONS_OVR_TYPE
, SCF_PG_OPTIONS_OVR_FLAGS
, pg
) !=
3386 switch (scf_error()) {
3387 case SCF_ERROR_CONNECTION_BROKEN
:
3388 case SCF_ERROR_PERMISSION_DENIED
:
3389 case SCF_ERROR_BACKEND_ACCESS
:
3393 case SCF_ERROR_DELETED
:
3396 case SCF_ERROR_EXISTS
:
3399 case SCF_ERROR_HANDLE_MISMATCH
:
3400 case SCF_ERROR_INVALID_ARGUMENT
:
3401 case SCF_ERROR_NOT_SET
:
3403 bad_error("scf_instance_add_pg", scf_error());
3410 r
= scf_value_set_astring(val
, buf
);
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
:
3422 case SCF_ERROR_DELETED
:
3425 case SCF_ERROR_HANDLE_MISMATCH
:
3426 case SCF_ERROR_NOT_BOUND
:
3427 case SCF_ERROR_IN_USE
:
3428 case SCF_ERROR_NOT_SET
:
3430 bad_error("scf_transaction_start", scf_error());
3434 r
= transaction_add_set(tx
, ent
, "runlevel", SCF_TYPE_ASTRING
);
3444 scf_transaction_reset(tx
);
3448 bad_error("transaction_add_set", r
);
3451 r
= scf_entry_add_value(ent
, val
);
3454 r
= scf_transaction_commit(tx
);
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
:
3467 case SCF_ERROR_DELETED
:
3468 scf_transaction_reset(tx
);
3471 case SCF_ERROR_INVALID_ARGUMENT
:
3472 case SCF_ERROR_NOT_BOUND
:
3473 case SCF_ERROR_NOT_SET
:
3475 bad_error("scf_transaction_commit",
3480 scf_transaction_reset(tx
);
3481 (void) scf_pg_update(pg
);
3485 scf_transaction_destroy(tx
);
3486 scf_entry_destroy(ent
);
3487 scf_value_destroy(val
);
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.
3499 userinit(int argc
, char **argv
)
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
);
3516 if ((init_signal
= lvlname_to_state((char)argv
[1][0])) == -1) {
3517 (void) fprintf(stderr
, usage_msg
);
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 */
3528 (void) fprintf(stderr
,
3529 "Standard input not a tty line\n");
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");
3547 if (symlink(ln
, SYSCON
) == FAILURE
) {
3548 (void) fprintf(stderr
,
3549 "Can't symlink /dev/syscon to %s: %s", ln
,
3552 /* Try to leave a syscon */
3553 (void) link(SYSTTY
, SYSCON
);
3558 * Try to leave a message on system console saying where
3559 * /dev/syscon is currently connected.
3561 if ((fp
= fopen(SYSTTY
, "r+")) != NULL
) {
3563 "\n**** SYSCON CHANGED TO %s ****\n",
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");
3584 #define DELTA 25 /* Number of pidlist elements to allocate at a time */
3591 struct pidrec
*p
= &prec
;
3592 struct pidlist
*plp
;
3593 struct pidlist
*tp
, *savetp
;
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
)) {
3611 switch (p
->pd_type
) {
3615 * New "godchild", add to list.
3617 if (Plfree
== NULL
) {
3618 plp
= (struct pidlist
*)calloc(DELTA
,
3619 sizeof (struct pidlist
));
3621 /* Can't save pid */
3625 * Point at 2nd record allocated, we'll use plp.
3629 * Link them into a chain.
3632 for (i
= 0; i
< DELTA
- 2; i
++) {
3633 tp
->pl_next
= tp
+ 1;
3638 Plfree
= plp
->pl_next
;
3640 plp
->pl_pid
= p
->pd_pid
;
3642 plp
->pl_next
= NULL
;
3644 * Note - pid list is kept in increasing order of pids.
3646 if (Plhead
== NULL
) {
3648 /* Back up to read next record */
3651 savetp
= tp
= Plhead
;
3653 if (plp
->pl_pid
> tp
->pl_pid
) {
3657 } else if (plp
->pl_pid
< tp
->pl_pid
) {
3659 plp
->pl_next
= Plhead
;
3664 savetp
->pl_next
= plp
;
3668 /* Already in list! */
3669 plp
->pl_next
= Plfree
;
3675 /* Add to end of list */
3676 savetp
->pl_next
= plp
;
3679 /* Back up to read next record. */
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. */
3691 savetp
= tp
= Plhead
;
3693 if (p
->pd_pid
> tp
->pl_pid
) {
3694 /* Keep on looking. */
3698 } else if (p
->pd_pid
< tp
->pl_pid
) {
3704 Plhead
= tp
->pl_next
;
3706 savetp
->pl_next
= tp
->pl_next
;
3707 tp
->pl_next
= Plfree
;
3712 /* Back up to read next record. */
3715 console(B_TRUE
, "Bad message on initpipe\n");
3725 struct pidlist
*savep
, *p
;
3729 (void) sighold(SIGCLD
);
3730 Gchild
= 0; /* Note - Safe to do this here since no SIGCLDs */
3731 (void) sighold(SIGPOLL
);
3736 * Found an entry to delete,
3737 * remove it from list first.
3740 status
= p
->pl_exit
;
3742 Plhead
= p
->pl_next
;
3743 p
->pl_next
= Plfree
;
3747 savep
->pl_next
= p
->pl_next
;
3748 p
->pl_next
= Plfree
;
3752 clearent(pid
, status
);
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.
3768 increase_proc_table_size()
3770 sigset_t block
, unblock
;
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
3787 ptr
= realloc(g_state
, g_state_sz
+ delta
);
3788 while (ptr
== NULL
&& errno
== EAGAIN
)
3792 /* ensure that the new part is initialized to zero */
3793 bzero((caddr_t
)ptr
+ g_state_sz
, delta
);
3796 g_state_sz
+= delta
;
3801 /* unblock our signals before returning */
3802 (void) sigprocmask(SIG_SETMASK
, &unblock
, NULL
);
3808 * Sanity check g_state.
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)
3821 /* Check num_proc */
3822 if (g_state_sz
!= sizeof (struct init_state
) + (num_proc
- 1) *
3823 sizeof (struct PROC_TABLE
))
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
))
3832 /* p_flags has no bits outside of PF_MASK */
3833 if (ptp
->p_flags
& ~(PF_MASK
))
3836 /* 5 <= pid <= MAXPID */
3837 if (ptp
->p_pid
< 5 || ptp
->p_pid
> MAXPID
)
3841 if (ptp
->p_count
< 0)
3845 if (ptp
->p_time
< 0)
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.
3867 int ret
, st_fd
, insane
= 0;
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
,
3881 } while (st_fd
== -1 && errno
== EINTR
);
3888 st_fd
= open(init_state_file
, O_RDWR
, S_IRUSR
| S_IWUSR
);
3889 } while (st_fd
== -1 && errno
== EINTR
);
3893 /* Get the size of the file. */
3895 ret
= fstat(st_fd
, &stb
);
3896 while (ret
== -1 && errno
== EINTR
)
3902 g_state
= malloc(stb
.st_size
);
3903 while (g_state
== NULL
&& errno
== EAGAIN
)
3905 if (g_state
== NULL
)
3908 to_be_read
= stb
.st_size
;
3909 ptr
= (char *)g_state
;
3910 while (to_be_read
> 0) {
3913 read_ret
= read(st_fd
, ptr
, to_be_read
);
3921 to_be_read
-= read_ret
;
3925 (void) close(st_fd
);
3927 g_state_sz
= stb
.st_size
;
3930 console(B_TRUE
, "Restarting.\n");
3938 (void) close(st_fd
);
3940 (void) unlink(init_state_file
);
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
) {
3956 g_state
->ist_runlevel
= -1;
3957 num_proc
= init_num_proc
;
3960 console(B_TRUE
, "Restarting.\n");
3962 /* Overwrite the bad state file. */
3967 "Error accessing persistent state file `%s'. "
3968 "Ignored.\n", init_state_file
);
3971 "Persistent state file `%s' is invalid and was "
3972 "ignored.\n", init_state_file
);
3978 * Write g_state out to the state file.
3983 static int complained
= 0;
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
);
3998 cp
= (char *)g_state
;
4001 ret
= write(st_fd
, cp
, sz
);
4013 (void) close(st_fd
);
4015 if (rename(init_next_state_file
, init_state_file
)) {
4016 (void) unlink(init_next_state_file
);
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()
4035 console(B_TRUE
, "Couldn't write persistent state "
4036 "file `%s'.\n", init_state_file
);
4038 console(B_TRUE
, "Couldn't move persistent state "
4039 "file `%s' to `%s'.\n", init_next_state_file
,
4045 * Create a contract with these parameters.
4048 contract_make_template(uint_t info
, uint_t critical
, uint_t fatal
,
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
)
4061 console(B_TRUE
, "Couldn't create process template: %s.\n",
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
);
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.
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
,
4106 if (legacy_tmpl
>= 0) {
4107 err
= ct_tmpl_activate(legacy_tmpl
);
4109 (void) close(legacy_tmpl
);
4112 "Couldn't activate legacy template (%s); "
4113 "legacy services will be in init's contract.\n",
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",
4124 (void) close(legacy_tmpl
);
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",
4137 (void) close(startd_tmpl
);
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. */
4146 "Ignoring contract events. Core smf(5) services will not "
4152 * Open an event endpoint.
4155 fd
= open64(CTFS_ROOT
"/process/pbundle", O_RDONLY
);
4156 while (fd
< 0 && errno
== EINTR
)
4160 "Couldn't open process pbundle: %s. Core smf(5) services "
4161 "will not be restarted.\n", strerror(errno
));
4165 if (dup2(fd
, 253) == -1) {
4166 console(B_TRUE
, "Could not duplicate process bundle: %s.\n",
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
;
4184 contract_getfile(ctid_t id
, const char *name
, int oflag
)
4189 fd
= contract_open(id
, "process", name
, oflag
);
4190 while (fd
< 0 && errno
== EINTR
)
4194 console(B_TRUE
, "Couldn't open %s for contract %ld: %s.\n",
4195 name
, id
, strerror(errno
));
4201 contract_cookie(ctid_t id
, uint64_t *cp
)
4206 fd
= contract_getfile(id
, "status", O_RDONLY
);
4210 err
= ct_status_read(fd
, CTD_COMMON
, &sh
);
4212 console(B_TRUE
, "Couldn't read status of contract %ld: %s.\n",
4220 *cp
= ct_status_get_cookie(sh
);
4227 contract_ack(ct_evthdl_t e
)
4231 if (ct_event_get_flags(e
) & CTE_INFO
)
4234 fd
= contract_getfile(ct_event_get_ctid(e
), "ctl", O_WRONLY
);
4238 (void) ct_ctl_ack(fd
, ct_event_get_evid(e
));
4243 * Process a contract event.
4246 contract_event(struct pollfd
*poll
)
4252 if (!(poll
->revents
& POLLIN
)) {
4253 if (poll
->revents
& POLLERR
)
4255 "Unknown poll error on my process contract "
4260 err
= ct_event_read(poll
->fd
, &e
);
4262 console(B_TRUE
, "Error retrieving contract event: %s.\n",
4267 ctid
= ct_event_get_ctid(e
);
4269 if (ct_event_get_type(e
) == CT_PR_EV_EMPTY
) {
4271 int ret
, abandon
= 1;
4273 /* If it's svc.startd, restart it. Else, abandon. */
4274 ret
= contract_cookie(ctid
, &cookie
);
4277 if (cookie
== STARTD_COOKIE
&&
4278 do_restart_startd
) {
4280 console(B_TRUE
, "Restarting "
4284 * Account for the failure. If the failure rate
4285 * exceeds a threshold, then drop to maintenance
4288 startd_record_failure();
4289 if (startd_failure_rate_critical())
4290 enter_maintenance();
4292 if (startd_tmpl
< 0)
4294 "Restarting svc.startd in "
4295 "improper contract (bad "
4298 (void) startd_run(startd_cline
, startd_tmpl
,
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.
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. */
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.
4337 startd_run(const char *cline
, int tmpl
, ctid_t old_ctid
)
4339 int err
, i
, ret
, did_activate
;
4343 if (cline
[0] == '\0')
4347 * Don't restart startd if the system is rebooting or shutting down.
4350 ret
= stat("/etc/svc/volatile/resetting", &sb
);
4351 } while (ret
== -1 && errno
== EINTR
);
4355 console(B_TRUE
, "Quiescing for reboot.\n");
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
);
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)
4377 "Can not set svc_fmri in contract template: %s\n",
4379 if ((err
= ct_pr_tmpl_set_svc_aux(startd_tmpl
,
4380 startd_svc_aux
)) != 0)
4382 "Can not set svc_aux in contract template: %s\n",
4384 did_activate
= !(ct_tmpl_activate(tmpl
));
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. */
4402 "fork() for svc.startd failed: %s. Will retry in 1 "
4403 "second...\n", strerror(errno
));
4407 /* Eventually give up? */
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
);
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
) {
4429 (void) sprintf(glob_envp
[glob_envn
],
4430 "SMF_OPTIONS=%s", smf_options
);
4431 glob_envp
[glob_envn
+1] = NULL
;
4434 "Could not set SMF_OPTIONS (%s).\n",
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
,
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. */
4459 (void) ct_pr_tmpl_set_transfer(tmpl
, 0);
4461 (void) sigrelse(SIGCLD
);
4467 * void startd_record_failure(void)
4468 * Place the current time in our circular array of svc.startd failures.
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
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
)
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
);