Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sbin/init/init.c
39476 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1991, 1993
5
* The Regents of the University of California. All rights reserved.
6
*
7
* This code is derived from software contributed to Berkeley by
8
* Donn Seeley at Berkeley Software Design, Inc.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include <sys/param.h>
36
#include <sys/boottrace.h>
37
#include <sys/ioctl.h>
38
#include <sys/mman.h>
39
#include <sys/mount.h>
40
#include <sys/reboot.h>
41
#include <sys/stat.h>
42
#include <sys/sysctl.h>
43
#include <sys/uio.h>
44
#include <sys/wait.h>
45
46
#include <db.h>
47
#include <err.h>
48
#include <errno.h>
49
#include <fcntl.h>
50
#include <kenv.h>
51
#include <libutil.h>
52
#include <mntopts.h>
53
#include <paths.h>
54
#include <signal.h>
55
#include <stdarg.h>
56
#include <stdbool.h>
57
#include <stdio.h>
58
#include <stdlib.h>
59
#include <string.h>
60
#include <syslog.h>
61
#include <time.h>
62
#include <ttyent.h>
63
#include <unistd.h>
64
65
#ifdef SECURE
66
#include <pwd.h>
67
#endif
68
69
#ifdef LOGIN_CAP
70
#include <login_cap.h>
71
#endif
72
73
#include "pathnames.h"
74
75
/*
76
* Sleep times; used to prevent thrashing.
77
*/
78
#define GETTY_SPACING 5 /* N secs minimum getty spacing */
79
#define GETTY_SLEEP 30 /* sleep N secs after spacing problem */
80
#define GETTY_NSPACE 3 /* max. spacing count to bring reaction */
81
#define WINDOW_WAIT 3 /* wait N secs after starting window */
82
#define STALL_TIMEOUT 30 /* wait N secs after warning */
83
#define DEATH_WATCH 10 /* wait N secs for procs to die */
84
#define DEATH_SCRIPT 120 /* wait for 2min for /etc/rc.shutdown */
85
#define RESOURCE_RC "daemon"
86
#define RESOURCE_WINDOW "default"
87
#define RESOURCE_GETTY "default"
88
#define SCRIPT_ARGV_SIZE 3 /* size of argv passed to execute_script, can be increased if needed */
89
90
static void handle(sig_t, ...);
91
static void delset(sigset_t *, ...);
92
93
static void stall(const char *, ...) __printflike(1, 2);
94
static void warning(const char *, ...) __printflike(1, 2);
95
static void emergency(const char *, ...) __printflike(1, 2);
96
static void disaster(int);
97
static void revoke_ttys(void);
98
static int runshutdown(void);
99
static char *strk(char *);
100
static void runfinal(void);
101
102
/*
103
* We really need a recursive typedef...
104
* The following at least guarantees that the return type of (*state_t)()
105
* is sufficiently wide to hold a function pointer.
106
*/
107
typedef long (*state_func_t)(void);
108
typedef state_func_t (*state_t)(void);
109
110
static state_func_t single_user(void);
111
static state_func_t runcom(void);
112
static state_func_t read_ttys(void);
113
static state_func_t multi_user(void);
114
static state_func_t clean_ttys(void);
115
static state_func_t catatonia(void);
116
static state_func_t death(void);
117
static state_func_t death_single(void);
118
static state_func_t reroot(void);
119
static state_func_t reroot_phase_two(void);
120
121
static state_func_t run_script(const char *);
122
123
static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT;
124
125
static bool Reboot = false;
126
static int howto = RB_AUTOBOOT;
127
128
static bool devfs = false;
129
static char *init_path_argv0;
130
131
static void transition(state_t);
132
static state_t requested_transition;
133
static state_t current_state = death_single;
134
135
static void execute_script(char *argv[]);
136
static void open_console(void);
137
static const char *get_shell(void);
138
static void replace_init(char *path);
139
static void write_stderr(const char *message);
140
141
typedef struct init_session {
142
pid_t se_process; /* controlling process */
143
time_t se_started; /* used to avoid thrashing */
144
int se_flags; /* status of session */
145
#define SE_SHUTDOWN 0x1 /* session won't be restarted */
146
#define SE_PRESENT 0x2 /* session is in /etc/ttys */
147
#define SE_IFEXISTS 0x4 /* session defined as "onifexists" */
148
#define SE_IFCONSOLE 0x8 /* session defined as "onifconsole" */
149
int se_nspace; /* spacing count */
150
char *se_device; /* filename of port */
151
char *se_getty; /* what to run on that port */
152
char *se_getty_argv_space; /* pre-parsed argument array space */
153
char **se_getty_argv; /* pre-parsed argument array */
154
char *se_window; /* window system (started only once) */
155
char *se_window_argv_space; /* pre-parsed argument array space */
156
char **se_window_argv; /* pre-parsed argument array */
157
char *se_type; /* default terminal type */
158
struct init_session *se_prev;
159
struct init_session *se_next;
160
} session_t;
161
162
static void free_session(session_t *);
163
static session_t *new_session(session_t *, struct ttyent *);
164
static session_t *sessions;
165
166
static char **construct_argv(char *);
167
static void start_window_system(session_t *);
168
static void collect_child(pid_t);
169
static pid_t start_getty(session_t *);
170
static void transition_handler(int);
171
static void alrm_handler(int);
172
static void setsecuritylevel(int);
173
static int getsecuritylevel(void);
174
static int setupargv(session_t *, struct ttyent *);
175
#ifdef LOGIN_CAP
176
static void setprocresources(const char *);
177
#endif
178
static bool clang;
179
180
static int start_session_db(void);
181
static void add_session(session_t *);
182
static void del_session(session_t *);
183
static session_t *find_session(pid_t);
184
static DB *session_db;
185
186
/*
187
* The mother of all processes.
188
*/
189
int
190
main(int argc, char *argv[])
191
{
192
state_t initial_transition = runcom;
193
char kenv_value[PATH_MAX];
194
int c, error;
195
struct sigaction sa;
196
sigset_t mask;
197
198
/* Dispose of random users. */
199
if (getuid() != 0)
200
errx(1, "%s", strerror(EPERM));
201
202
BOOTTRACE("init(8) starting...");
203
204
/* System V users like to reexec init. */
205
if (getpid() != 1) {
206
#ifdef COMPAT_SYSV_INIT
207
/* So give them what they want */
208
if (argc > 1) {
209
if (strlen(argv[1]) == 1) {
210
char runlevel = *argv[1];
211
int sig;
212
213
switch (runlevel) {
214
case '0': /* halt + poweroff */
215
sig = SIGUSR2;
216
break;
217
case '1': /* single-user */
218
sig = SIGTERM;
219
break;
220
case '6': /* reboot */
221
sig = SIGINT;
222
break;
223
case 'c': /* block further logins */
224
sig = SIGTSTP;
225
break;
226
case 'q': /* rescan /etc/ttys */
227
sig = SIGHUP;
228
break;
229
case 'r': /* remount root */
230
sig = SIGEMT;
231
break;
232
default:
233
goto invalid;
234
}
235
kill(1, sig);
236
_exit(0);
237
} else
238
invalid:
239
errx(1, "invalid run-level ``%s''", argv[1]);
240
} else
241
#endif
242
errx(1, "already running");
243
}
244
245
init_path_argv0 = strdup(argv[0]);
246
if (init_path_argv0 == NULL)
247
err(1, "strdup");
248
249
/*
250
* Note that this does NOT open a file...
251
* Does 'init' deserve its own facility number?
252
*/
253
openlog("init", LOG_CONS, LOG_AUTH);
254
255
/*
256
* Create an initial session.
257
*/
258
if (setsid() < 0 && (errno != EPERM || getsid(0) != 1))
259
warning("initial setsid() failed: %m");
260
261
/*
262
* Establish an initial user so that programs running
263
* single user do not freak out and die (like passwd).
264
*/
265
if (setlogin("root") < 0)
266
warning("setlogin() failed: %m");
267
268
/*
269
* This code assumes that we always get arguments through flags,
270
* never through bits set in some random machine register.
271
*/
272
while ((c = getopt(argc, argv, "dsfr")) != -1)
273
switch (c) {
274
case 'd':
275
devfs = true;
276
break;
277
case 's':
278
initial_transition = single_user;
279
break;
280
case 'f':
281
runcom_mode = FASTBOOT;
282
break;
283
case 'r':
284
initial_transition = reroot_phase_two;
285
break;
286
default:
287
warning("unrecognized flag '-%c'", c);
288
break;
289
}
290
291
if (optind != argc)
292
warning("ignoring excess arguments");
293
294
/*
295
* We catch or block signals rather than ignore them,
296
* so that they get reset on exec.
297
*/
298
handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
299
SIGXCPU, SIGXFSZ, 0);
300
handle(transition_handler, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP,
301
SIGUSR1, SIGUSR2, SIGWINCH, 0);
302
handle(alrm_handler, SIGALRM, 0);
303
sigfillset(&mask);
304
delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
305
SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP,
306
SIGALRM, SIGUSR1, SIGUSR2, SIGWINCH, 0);
307
sigprocmask(SIG_SETMASK, &mask, NULL);
308
sigemptyset(&sa.sa_mask);
309
sa.sa_flags = 0;
310
sa.sa_handler = SIG_IGN;
311
sigaction(SIGTTIN, &sa, NULL);
312
sigaction(SIGTTOU, &sa, NULL);
313
314
/*
315
* Paranoia.
316
*/
317
close(0);
318
close(1);
319
close(2);
320
321
if (kenv(KENV_GET, "init_exec", kenv_value, sizeof(kenv_value)) > 0) {
322
replace_init(kenv_value);
323
_exit(0); /* reboot */
324
}
325
326
if (kenv(KENV_GET, "init_script", kenv_value, sizeof(kenv_value)) > 0) {
327
state_func_t next_transition;
328
329
if ((next_transition = run_script(kenv_value)) != NULL)
330
initial_transition = (state_t) next_transition;
331
}
332
333
if (kenv(KENV_GET, "init_chroot", kenv_value, sizeof(kenv_value)) > 0) {
334
if (chdir(kenv_value) != 0 || chroot(".") != 0)
335
warning("Can't chroot to %s: %m", kenv_value);
336
}
337
338
/*
339
* Additional check if devfs needs to be mounted:
340
* If "/" and "/dev" have the same device number,
341
* then it hasn't been mounted yet.
342
*/
343
if (!devfs) {
344
struct stat stst;
345
dev_t root_devno;
346
347
stat("/", &stst);
348
root_devno = stst.st_dev;
349
if (stat("/dev", &stst) != 0)
350
warning("Can't stat /dev: %m");
351
else if (stst.st_dev == root_devno)
352
devfs = true;
353
}
354
355
if (devfs) {
356
struct iovec iov[4];
357
char *s;
358
int i;
359
360
char _fstype[] = "fstype";
361
char _devfs[] = "devfs";
362
char _fspath[] = "fspath";
363
char _path_dev[]= _PATH_DEV;
364
365
iov[0].iov_base = _fstype;
366
iov[0].iov_len = sizeof(_fstype);
367
iov[1].iov_base = _devfs;
368
iov[1].iov_len = sizeof(_devfs);
369
iov[2].iov_base = _fspath;
370
iov[2].iov_len = sizeof(_fspath);
371
/*
372
* Try to avoid the trailing slash in _PATH_DEV.
373
* Be *very* defensive.
374
*/
375
s = strdup(_PATH_DEV);
376
if (s != NULL) {
377
i = strlen(s);
378
if (i > 0 && s[i - 1] == '/')
379
s[i - 1] = '\0';
380
iov[3].iov_base = s;
381
iov[3].iov_len = strlen(s) + 1;
382
} else {
383
iov[3].iov_base = _path_dev;
384
iov[3].iov_len = sizeof(_path_dev);
385
}
386
nmount(iov, 4, 0);
387
if (s != NULL)
388
free(s);
389
}
390
391
if (initial_transition != reroot_phase_two) {
392
/*
393
* Unmount reroot leftovers. This runs after init(8)
394
* gets reexecuted after reroot_phase_two() is done.
395
*/
396
error = unmount(_PATH_REROOT, MNT_FORCE);
397
if (error != 0 && errno != EINVAL)
398
warning("Cannot unmount %s: %m", _PATH_REROOT);
399
}
400
401
/*
402
* Start the state machine.
403
*/
404
transition(initial_transition);
405
406
/*
407
* Should never reach here.
408
*/
409
return 1;
410
}
411
412
/*
413
* Associate a function with a signal handler.
414
*/
415
static void
416
handle(sig_t handler, ...)
417
{
418
int sig;
419
struct sigaction sa;
420
sigset_t mask_everything;
421
va_list ap;
422
va_start(ap, handler);
423
424
sa.sa_handler = handler;
425
sigfillset(&mask_everything);
426
427
while ((sig = va_arg(ap, int)) != 0) {
428
sa.sa_mask = mask_everything;
429
/* XXX SA_RESTART? */
430
sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
431
sigaction(sig, &sa, NULL);
432
}
433
va_end(ap);
434
}
435
436
/*
437
* Delete a set of signals from a mask.
438
*/
439
static void
440
delset(sigset_t *maskp, ...)
441
{
442
int sig;
443
va_list ap;
444
va_start(ap, maskp);
445
446
while ((sig = va_arg(ap, int)) != 0)
447
sigdelset(maskp, sig);
448
va_end(ap);
449
}
450
451
/*
452
* Log a message and sleep for a while (to give someone an opportunity
453
* to read it and to save log or hardcopy output if the problem is chronic).
454
* NB: should send a message to the session logger to avoid blocking.
455
*/
456
static void
457
stall(const char *message, ...)
458
{
459
va_list ap;
460
va_start(ap, message);
461
462
vsyslog(LOG_ALERT, message, ap);
463
va_end(ap);
464
sleep(STALL_TIMEOUT);
465
}
466
467
/*
468
* Like stall(), but doesn't sleep.
469
* If cpp had variadic macros, the two functions could be #defines for another.
470
* NB: should send a message to the session logger to avoid blocking.
471
*/
472
static void
473
warning(const char *message, ...)
474
{
475
va_list ap;
476
va_start(ap, message);
477
478
vsyslog(LOG_ALERT, message, ap);
479
va_end(ap);
480
}
481
482
/*
483
* Log an emergency message.
484
* NB: should send a message to the session logger to avoid blocking.
485
*/
486
static void
487
emergency(const char *message, ...)
488
{
489
va_list ap;
490
va_start(ap, message);
491
492
vsyslog(LOG_EMERG, message, ap);
493
va_end(ap);
494
}
495
496
/*
497
* Catch an unexpected signal.
498
*/
499
static void
500
disaster(int sig)
501
{
502
503
emergency("fatal signal: %s",
504
(unsigned)sig < NSIG ? sys_siglist[sig] : "unknown signal");
505
506
sleep(STALL_TIMEOUT);
507
_exit(sig); /* reboot */
508
}
509
510
/*
511
* Get the security level of the kernel.
512
*/
513
static int
514
getsecuritylevel(void)
515
{
516
#ifdef KERN_SECURELVL
517
int name[2], curlevel;
518
size_t len;
519
520
name[0] = CTL_KERN;
521
name[1] = KERN_SECURELVL;
522
len = sizeof curlevel;
523
if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
524
emergency("cannot get kernel security level: %m");
525
return (-1);
526
}
527
return (curlevel);
528
#else
529
return (-1);
530
#endif
531
}
532
533
/*
534
* Set the security level of the kernel.
535
*/
536
static void
537
setsecuritylevel(int newlevel)
538
{
539
#ifdef KERN_SECURELVL
540
int name[2], curlevel;
541
542
curlevel = getsecuritylevel();
543
if (newlevel == curlevel)
544
return;
545
name[0] = CTL_KERN;
546
name[1] = KERN_SECURELVL;
547
if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
548
emergency(
549
"cannot change kernel security level from %d to %d: %m",
550
curlevel, newlevel);
551
return;
552
}
553
#ifdef SECURE
554
warning("kernel security level changed from %d to %d",
555
curlevel, newlevel);
556
#endif
557
#endif
558
}
559
560
/*
561
* Change states in the finite state machine.
562
* The initial state is passed as an argument.
563
*/
564
static void
565
transition(state_t s)
566
{
567
568
current_state = s;
569
for (;;)
570
current_state = (state_t) (*current_state)();
571
}
572
573
/*
574
* Start a session and allocate a controlling terminal.
575
* Only called by children of init after forking.
576
*/
577
static void
578
open_console(void)
579
{
580
int fd;
581
582
/*
583
* Try to open /dev/console. Open the device with O_NONBLOCK to
584
* prevent potential blocking on a carrier.
585
*/
586
revoke(_PATH_CONSOLE);
587
if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) {
588
(void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
589
if (login_tty(fd) == 0)
590
return;
591
close(fd);
592
}
593
594
/* No luck. Log output to file if possible. */
595
if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
596
stall("cannot open null device.");
597
_exit(1);
598
}
599
if (fd != STDIN_FILENO) {
600
dup2(fd, STDIN_FILENO);
601
close(fd);
602
}
603
fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644);
604
if (fd == -1)
605
dup2(STDIN_FILENO, STDOUT_FILENO);
606
else if (fd != STDOUT_FILENO) {
607
dup2(fd, STDOUT_FILENO);
608
close(fd);
609
}
610
dup2(STDOUT_FILENO, STDERR_FILENO);
611
}
612
613
static const char *
614
get_shell(void)
615
{
616
static char kenv_value[PATH_MAX];
617
618
if (kenv(KENV_GET, "init_shell", kenv_value, sizeof(kenv_value)) > 0)
619
return kenv_value;
620
else
621
return _PATH_BSHELL;
622
}
623
624
static void
625
write_stderr(const char *message)
626
{
627
628
write(STDERR_FILENO, message, strlen(message));
629
}
630
631
static int
632
read_file(const char *path, void **bufp, size_t *bufsizep)
633
{
634
struct stat sb;
635
size_t bufsize;
636
void *buf;
637
ssize_t nbytes;
638
int error, fd;
639
640
fd = open(path, O_RDONLY);
641
if (fd < 0) {
642
emergency("%s: %m", path);
643
return (-1);
644
}
645
646
error = fstat(fd, &sb);
647
if (error != 0) {
648
emergency("fstat: %m");
649
close(fd);
650
return (error);
651
}
652
653
bufsize = sb.st_size;
654
buf = malloc(bufsize);
655
if (buf == NULL) {
656
emergency("malloc: %m");
657
close(fd);
658
return (error);
659
}
660
661
nbytes = read(fd, buf, bufsize);
662
if (nbytes != (ssize_t)bufsize) {
663
emergency("read: %m");
664
close(fd);
665
free(buf);
666
return (error);
667
}
668
669
error = close(fd);
670
if (error != 0) {
671
emergency("close: %m");
672
free(buf);
673
return (error);
674
}
675
676
*bufp = buf;
677
*bufsizep = bufsize;
678
679
return (0);
680
}
681
682
static int
683
create_file(const char *path, const void *buf, size_t bufsize)
684
{
685
ssize_t nbytes;
686
int error, fd;
687
688
fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0700);
689
if (fd < 0) {
690
emergency("%s: %m", path);
691
return (-1);
692
}
693
694
nbytes = write(fd, buf, bufsize);
695
if (nbytes != (ssize_t)bufsize) {
696
emergency("write: %m");
697
close(fd);
698
return (-1);
699
}
700
701
error = close(fd);
702
if (error != 0) {
703
emergency("close: %m");
704
return (-1);
705
}
706
707
return (0);
708
}
709
710
static int
711
mount_tmpfs(const char *fspath)
712
{
713
struct iovec *iov;
714
char errmsg[255];
715
int error, iovlen;
716
717
iov = NULL;
718
iovlen = 0;
719
memset(errmsg, 0, sizeof(errmsg));
720
build_iovec(&iov, &iovlen, "fstype",
721
__DECONST(void *, "tmpfs"), (size_t)-1);
722
build_iovec(&iov, &iovlen, "fspath",
723
__DECONST(void *, fspath), (size_t)-1);
724
build_iovec(&iov, &iovlen, "errmsg",
725
errmsg, sizeof(errmsg));
726
727
error = nmount(iov, iovlen, 0);
728
if (error != 0) {
729
if (*errmsg != '\0') {
730
emergency("cannot mount tmpfs on %s: %s: %m",
731
fspath, errmsg);
732
} else {
733
emergency("cannot mount tmpfs on %s: %m",
734
fspath);
735
}
736
return (error);
737
}
738
return (0);
739
}
740
741
static state_func_t
742
reroot(void)
743
{
744
void *buf;
745
size_t bufsize;
746
int error;
747
748
buf = NULL;
749
bufsize = 0;
750
751
revoke_ttys();
752
runshutdown();
753
754
/*
755
* Make sure nobody can interfere with our scheme.
756
* Ignore ESRCH, which can apparently happen when
757
* there are no processes to kill.
758
*/
759
error = kill(-1, SIGKILL);
760
if (error != 0 && errno != ESRCH) {
761
emergency("kill(2) failed: %m");
762
goto out;
763
}
764
765
/*
766
* Copy the init binary into tmpfs, so that we can unmount
767
* the old rootfs without committing suicide.
768
*/
769
error = read_file(init_path_argv0, &buf, &bufsize);
770
if (error != 0)
771
goto out;
772
error = mount_tmpfs(_PATH_REROOT);
773
if (error != 0)
774
goto out;
775
error = create_file(_PATH_REROOT_INIT, buf, bufsize);
776
if (error != 0)
777
goto out;
778
779
/*
780
* Execute the temporary init.
781
*/
782
execl(_PATH_REROOT_INIT, _PATH_REROOT_INIT, "-r", NULL);
783
emergency("cannot exec %s: %m", _PATH_REROOT_INIT);
784
785
out:
786
emergency("reroot failed; going to single user mode");
787
free(buf);
788
return (state_func_t) single_user;
789
}
790
791
static state_func_t
792
reroot_phase_two(void)
793
{
794
char init_path[PATH_MAX], *path, *path_component;
795
size_t init_path_len;
796
int nbytes, error;
797
798
/*
799
* Ask the kernel to mount the new rootfs.
800
*/
801
error = reboot(RB_REROOT);
802
if (error != 0) {
803
emergency("RB_REBOOT failed: %m");
804
goto out;
805
}
806
807
/*
808
* Figure out where the destination init(8) binary is. Note that
809
* the path could be different than what we've started with. Use
810
* the value from kenv, if set, or the one from sysctl otherwise.
811
* The latter defaults to a hardcoded value, but can be overridden
812
* by a build time option.
813
*/
814
nbytes = kenv(KENV_GET, "init_path", init_path, sizeof(init_path));
815
if (nbytes <= 0) {
816
init_path_len = sizeof(init_path);
817
error = sysctlbyname("kern.init_path",
818
init_path, &init_path_len, NULL, 0);
819
if (error != 0) {
820
emergency("failed to retrieve kern.init_path: %m");
821
goto out;
822
}
823
}
824
825
/*
826
* Repeat the init search logic from sys/kern/init_path.c
827
*/
828
path_component = init_path;
829
while ((path = strsep(&path_component, ":")) != NULL) {
830
/*
831
* Execute init(8) from the new rootfs.
832
*/
833
execl(path, path, NULL);
834
}
835
emergency("cannot exec init from %s: %m", init_path);
836
837
out:
838
emergency("reroot failed; going to single user mode");
839
return (state_func_t) single_user;
840
}
841
842
/*
843
* Bring the system up single user.
844
*/
845
static state_func_t
846
single_user(void)
847
{
848
pid_t pid, wpid;
849
int status;
850
sigset_t mask;
851
const char *shell;
852
char *argv[2];
853
struct timeval tv, tn;
854
struct passwd *pp;
855
#ifdef SECURE
856
struct ttyent *typ;
857
static const char banner[] =
858
"Enter root password, or ^D to go multi-user\n";
859
char *clear, *password;
860
#endif
861
#ifdef DEBUGSHELL
862
char altshell[128];
863
#endif
864
865
if (Reboot) {
866
/* Instead of going single user, let's reboot the machine */
867
BOOTTRACE("shutting down the system");
868
sync();
869
/* Run scripts after all processes have been terminated. */
870
runfinal();
871
if (reboot(howto) == -1) {
872
emergency("reboot(%#x) failed, %m", howto);
873
_exit(1); /* panic and reboot */
874
}
875
warning("reboot(%#x) returned", howto);
876
_exit(0); /* panic as well */
877
}
878
879
BOOTTRACE("going to single user mode");
880
shell = get_shell();
881
882
if ((pid = fork()) == 0) {
883
/*
884
* Start the single user session.
885
*/
886
open_console();
887
888
pp = getpwnam("root");
889
#ifdef SECURE
890
/*
891
* Check the root password.
892
* We don't care if the console is 'on' by default;
893
* it's the only tty that can be 'off' and 'secure'.
894
*/
895
typ = getttynam("console");
896
if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
897
pp && *pp->pw_passwd) {
898
write_stderr(banner);
899
for (;;) {
900
clear = getpass("Password:");
901
if (clear == NULL || *clear == '\0')
902
_exit(0);
903
password = crypt(clear, pp->pw_passwd);
904
explicit_bzero(clear, _PASSWORD_LEN);
905
if (password != NULL &&
906
strcmp(password, pp->pw_passwd) == 0)
907
break;
908
warning("single-user login failed\n");
909
}
910
}
911
endttyent();
912
#endif /* SECURE */
913
914
#ifdef DEBUGSHELL
915
{
916
char *cp = altshell;
917
int num;
918
919
#define SHREQUEST "Enter full pathname of shell or RETURN for "
920
write_stderr(SHREQUEST);
921
write_stderr(shell);
922
write_stderr(": ");
923
while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
924
num != 0 && *cp != '\n' && cp < &altshell[127])
925
cp++;
926
*cp = '\0';
927
if (altshell[0] != '\0')
928
shell = altshell;
929
}
930
#endif /* DEBUGSHELL */
931
932
if (pp != NULL && pp->pw_dir != NULL && *pp->pw_dir != '\0' &&
933
chdir(pp->pw_dir) == 0) {
934
setenv("HOME", pp->pw_dir, 1);
935
} else {
936
chdir("/");
937
setenv("HOME", "/", 1);
938
}
939
endpwent();
940
941
/*
942
* Unblock signals.
943
* We catch all the interesting ones,
944
* and those are reset to SIG_DFL on exec.
945
*/
946
sigemptyset(&mask);
947
sigprocmask(SIG_SETMASK, &mask, NULL);
948
949
/*
950
* Fire off a shell.
951
* If the default one doesn't work, try the Bourne shell.
952
*/
953
954
char name[] = "-sh";
955
956
argv[0] = name;
957
argv[1] = NULL;
958
execv(shell, argv);
959
emergency("can't exec %s for single user: %m", shell);
960
execv(_PATH_BSHELL, argv);
961
emergency("can't exec %s for single user: %m", _PATH_BSHELL);
962
sleep(STALL_TIMEOUT);
963
_exit(1);
964
}
965
966
if (pid == -1) {
967
/*
968
* We are seriously hosed. Do our best.
969
*/
970
emergency("can't fork single-user shell, trying again");
971
while (waitpid(-1, (int *) 0, WNOHANG) > 0)
972
continue;
973
return (state_func_t) single_user;
974
}
975
976
requested_transition = 0;
977
do {
978
if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
979
collect_child(wpid);
980
if (wpid == -1) {
981
if (errno == EINTR)
982
continue;
983
warning("wait for single-user shell failed: %m; restarting");
984
return (state_func_t) single_user;
985
}
986
if (wpid == pid && WIFSTOPPED(status)) {
987
warning("init: shell stopped, restarting\n");
988
kill(pid, SIGCONT);
989
wpid = -1;
990
}
991
} while (wpid != pid && !requested_transition);
992
993
if (requested_transition)
994
return (state_func_t) requested_transition;
995
996
if (!WIFEXITED(status)) {
997
if (WTERMSIG(status) == SIGKILL) {
998
/*
999
* reboot(8) killed shell?
1000
*/
1001
warning("single user shell terminated.");
1002
gettimeofday(&tv, NULL);
1003
tn = tv;
1004
tv.tv_sec += STALL_TIMEOUT;
1005
while (tv.tv_sec > tn.tv_sec || (tv.tv_sec ==
1006
tn.tv_sec && tv.tv_usec > tn.tv_usec)) {
1007
sleep(1);
1008
gettimeofday(&tn, NULL);
1009
}
1010
_exit(0);
1011
} else {
1012
warning("single user shell terminated, restarting");
1013
return (state_func_t) single_user;
1014
}
1015
}
1016
1017
runcom_mode = FASTBOOT;
1018
return (state_func_t) runcom;
1019
}
1020
1021
/*
1022
* Run the system startup script.
1023
*/
1024
static state_func_t
1025
runcom(void)
1026
{
1027
state_func_t next_transition;
1028
1029
BOOTTRACE("/etc/rc starting...");
1030
if ((next_transition = run_script(_PATH_RUNCOM)) != NULL)
1031
return next_transition;
1032
BOOTTRACE("/etc/rc finished");
1033
1034
runcom_mode = AUTOBOOT; /* the default */
1035
return (state_func_t) read_ttys;
1036
}
1037
1038
static void
1039
execute_script(char *argv[])
1040
{
1041
struct sigaction sa;
1042
char* sh_argv[3 + SCRIPT_ARGV_SIZE];
1043
const char *shell, *script;
1044
int error, sh_argv_len, i;
1045
1046
bzero(&sa, sizeof(sa));
1047
sigemptyset(&sa.sa_mask);
1048
sa.sa_handler = SIG_IGN;
1049
sigaction(SIGTSTP, &sa, NULL);
1050
sigaction(SIGHUP, &sa, NULL);
1051
1052
open_console();
1053
1054
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
1055
#ifdef LOGIN_CAP
1056
setprocresources(RESOURCE_RC);
1057
#endif
1058
1059
/*
1060
* Try to directly execute the script first. If it
1061
* fails, try the old method of passing the script path
1062
* to sh(1). Don't complain if it fails because of
1063
* the missing execute bit.
1064
*/
1065
script = argv[0];
1066
error = access(script, X_OK);
1067
if (error == 0) {
1068
execv(script, argv);
1069
warning("can't directly exec %s: %m", script);
1070
} else if (errno != EACCES) {
1071
warning("can't access %s: %m", script);
1072
}
1073
1074
shell = get_shell();
1075
sh_argv[0] = __DECONST(char*, shell);
1076
sh_argv_len = 1;
1077
#ifdef SECURE
1078
if (strcmp(shell, _PATH_BSHELL) == 0) {
1079
sh_argv[1] = __DECONST(char*, "-o");
1080
sh_argv[2] = __DECONST(char*, "verify");
1081
sh_argv_len = 3;
1082
}
1083
#endif
1084
for (i = 0; i != SCRIPT_ARGV_SIZE; ++i)
1085
sh_argv[i + sh_argv_len] = argv[i];
1086
execv(shell, sh_argv);
1087
stall("can't exec %s for %s: %m", shell, script);
1088
}
1089
1090
/*
1091
* Execute binary, replacing init(8) as PID 1.
1092
*/
1093
static void
1094
replace_init(char *path)
1095
{
1096
char *argv[SCRIPT_ARGV_SIZE];
1097
1098
argv[0] = path;
1099
argv[1] = NULL;
1100
1101
execute_script(argv);
1102
}
1103
1104
/*
1105
* Run a shell script.
1106
* Returns 0 on success, otherwise the next transition to enter:
1107
* - single_user if fork/execv/waitpid failed, or if the script
1108
* terminated with a signal or exit code != 0.
1109
* - death_single if a SIGTERM was delivered to init(8).
1110
*/
1111
static state_func_t
1112
run_script(const char *script)
1113
{
1114
pid_t pid, wpid;
1115
int status;
1116
char *argv[SCRIPT_ARGV_SIZE];
1117
const char *shell;
1118
1119
shell = get_shell();
1120
1121
if ((pid = fork()) == 0) {
1122
1123
char _autoboot[] = "autoboot";
1124
1125
argv[0] = __DECONST(char *, script);
1126
argv[1] = runcom_mode == AUTOBOOT ? _autoboot : NULL;
1127
argv[2] = NULL;
1128
1129
execute_script(argv);
1130
sleep(STALL_TIMEOUT);
1131
_exit(1); /* force single user mode */
1132
}
1133
1134
if (pid == -1) {
1135
emergency("can't fork for %s on %s: %m", shell, script);
1136
while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1137
continue;
1138
sleep(STALL_TIMEOUT);
1139
return (state_func_t) single_user;
1140
}
1141
1142
/*
1143
* Copied from single_user(). This is a bit paranoid.
1144
*/
1145
requested_transition = 0;
1146
do {
1147
if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
1148
collect_child(wpid);
1149
if (requested_transition == death_single ||
1150
requested_transition == reroot)
1151
return (state_func_t) requested_transition;
1152
if (wpid == -1) {
1153
if (errno == EINTR)
1154
continue;
1155
warning("wait for %s on %s failed: %m; going to "
1156
"single user mode", shell, script);
1157
return (state_func_t) single_user;
1158
}
1159
if (wpid == pid && WIFSTOPPED(status)) {
1160
warning("init: %s on %s stopped, restarting\n",
1161
shell, script);
1162
kill(pid, SIGCONT);
1163
wpid = -1;
1164
}
1165
} while (wpid != pid);
1166
1167
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
1168
requested_transition == catatonia) {
1169
/* /etc/rc executed /sbin/reboot; wait for the end quietly */
1170
sigset_t s;
1171
1172
sigfillset(&s);
1173
for (;;)
1174
sigsuspend(&s);
1175
}
1176
1177
if (!WIFEXITED(status)) {
1178
warning("%s on %s terminated abnormally, going to single "
1179
"user mode", shell, script);
1180
return (state_func_t) single_user;
1181
}
1182
1183
if (WEXITSTATUS(status))
1184
return (state_func_t) single_user;
1185
1186
return (state_func_t) 0;
1187
}
1188
1189
/*
1190
* Open the session database.
1191
*
1192
* NB: We could pass in the size here; is it necessary?
1193
*/
1194
static int
1195
start_session_db(void)
1196
{
1197
if (session_db && (*session_db->close)(session_db))
1198
emergency("session database close: %m");
1199
if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == NULL) {
1200
emergency("session database open: %m");
1201
return (1);
1202
}
1203
return (0);
1204
1205
}
1206
1207
/*
1208
* Add a new login session.
1209
*/
1210
static void
1211
add_session(session_t *sp)
1212
{
1213
DBT key;
1214
DBT data;
1215
1216
key.data = &sp->se_process;
1217
key.size = sizeof sp->se_process;
1218
data.data = &sp;
1219
data.size = sizeof sp;
1220
1221
if ((*session_db->put)(session_db, &key, &data, 0))
1222
emergency("insert %d: %m", sp->se_process);
1223
}
1224
1225
/*
1226
* Delete an old login session.
1227
*/
1228
static void
1229
del_session(session_t *sp)
1230
{
1231
DBT key;
1232
1233
key.data = &sp->se_process;
1234
key.size = sizeof sp->se_process;
1235
1236
if ((*session_db->del)(session_db, &key, 0))
1237
emergency("delete %d: %m", sp->se_process);
1238
}
1239
1240
/*
1241
* Look up a login session by pid.
1242
*/
1243
static session_t *
1244
find_session(pid_t pid)
1245
{
1246
DBT key;
1247
DBT data;
1248
session_t *ret;
1249
1250
key.data = &pid;
1251
key.size = sizeof pid;
1252
if ((*session_db->get)(session_db, &key, &data, 0) != 0)
1253
return 0;
1254
bcopy(data.data, (char *)&ret, sizeof(ret));
1255
return ret;
1256
}
1257
1258
/*
1259
* Construct an argument vector from a command line.
1260
*/
1261
static char **
1262
construct_argv(char *command)
1263
{
1264
int argc = 0;
1265
char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1)
1266
* sizeof (char *));
1267
1268
if ((argv[argc++] = strk(command)) == NULL) {
1269
free(argv);
1270
return (NULL);
1271
}
1272
while ((argv[argc++] = strk((char *) 0)) != NULL)
1273
continue;
1274
return argv;
1275
}
1276
1277
/*
1278
* Deallocate a session descriptor.
1279
*/
1280
static void
1281
free_session(session_t *sp)
1282
{
1283
free(sp->se_device);
1284
if (sp->se_getty) {
1285
free(sp->se_getty);
1286
free(sp->se_getty_argv_space);
1287
free(sp->se_getty_argv);
1288
}
1289
if (sp->se_window) {
1290
free(sp->se_window);
1291
free(sp->se_window_argv_space);
1292
free(sp->se_window_argv);
1293
}
1294
if (sp->se_type)
1295
free(sp->se_type);
1296
free(sp);
1297
}
1298
1299
/*
1300
* Allocate a new session descriptor.
1301
* Mark it SE_PRESENT.
1302
*/
1303
static session_t *
1304
new_session(session_t *sprev, struct ttyent *typ)
1305
{
1306
session_t *sp;
1307
1308
if ((typ->ty_status & TTY_ON) == 0 ||
1309
typ->ty_name == 0 ||
1310
typ->ty_getty == 0)
1311
return 0;
1312
1313
sp = (session_t *) calloc(1, sizeof (session_t));
1314
1315
sp->se_flags |= SE_PRESENT;
1316
1317
if ((typ->ty_status & TTY_IFEXISTS) != 0)
1318
sp->se_flags |= SE_IFEXISTS;
1319
1320
if ((typ->ty_status & TTY_IFCONSOLE) != 0)
1321
sp->se_flags |= SE_IFCONSOLE;
1322
1323
if (asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name) < 0)
1324
err(1, "asprintf");
1325
1326
if (setupargv(sp, typ) == 0) {
1327
free_session(sp);
1328
return (0);
1329
}
1330
1331
sp->se_next = 0;
1332
if (sprev == NULL) {
1333
sessions = sp;
1334
sp->se_prev = 0;
1335
} else {
1336
sprev->se_next = sp;
1337
sp->se_prev = sprev;
1338
}
1339
1340
return sp;
1341
}
1342
1343
/*
1344
* Calculate getty and if useful window argv vectors.
1345
*/
1346
static int
1347
setupargv(session_t *sp, struct ttyent *typ)
1348
{
1349
1350
if (sp->se_getty) {
1351
free(sp->se_getty);
1352
free(sp->se_getty_argv_space);
1353
free(sp->se_getty_argv);
1354
}
1355
if (asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name) < 0)
1356
err(1, "asprintf");
1357
sp->se_getty_argv_space = strdup(sp->se_getty);
1358
sp->se_getty_argv = construct_argv(sp->se_getty_argv_space);
1359
if (sp->se_getty_argv == NULL) {
1360
warning("can't parse getty for port %s", sp->se_device);
1361
free(sp->se_getty);
1362
free(sp->se_getty_argv_space);
1363
sp->se_getty = sp->se_getty_argv_space = 0;
1364
return (0);
1365
}
1366
if (sp->se_window) {
1367
free(sp->se_window);
1368
free(sp->se_window_argv_space);
1369
free(sp->se_window_argv);
1370
}
1371
sp->se_window = sp->se_window_argv_space = 0;
1372
sp->se_window_argv = 0;
1373
if (typ->ty_window) {
1374
sp->se_window = strdup(typ->ty_window);
1375
sp->se_window_argv_space = strdup(sp->se_window);
1376
sp->se_window_argv = construct_argv(sp->se_window_argv_space);
1377
if (sp->se_window_argv == NULL) {
1378
warning("can't parse window for port %s",
1379
sp->se_device);
1380
free(sp->se_window_argv_space);
1381
free(sp->se_window);
1382
sp->se_window = sp->se_window_argv_space = 0;
1383
return (0);
1384
}
1385
}
1386
if (sp->se_type)
1387
free(sp->se_type);
1388
sp->se_type = typ->ty_type ? strdup(typ->ty_type) : 0;
1389
return (1);
1390
}
1391
1392
/*
1393
* Walk the list of ttys and create sessions for each active line.
1394
*/
1395
static state_func_t
1396
read_ttys(void)
1397
{
1398
session_t *sp, *snext;
1399
struct ttyent *typ;
1400
1401
/*
1402
* Destroy any previous session state.
1403
* There shouldn't be any, but just in case...
1404
*/
1405
for (sp = sessions; sp; sp = snext) {
1406
snext = sp->se_next;
1407
free_session(sp);
1408
}
1409
sessions = 0;
1410
if (start_session_db())
1411
return (state_func_t) single_user;
1412
1413
/*
1414
* Allocate a session entry for each active port.
1415
* Note that sp starts at 0.
1416
*/
1417
while ((typ = getttyent()) != NULL)
1418
if ((snext = new_session(sp, typ)) != NULL)
1419
sp = snext;
1420
1421
endttyent();
1422
1423
return (state_func_t) multi_user;
1424
}
1425
1426
/*
1427
* Start a window system running.
1428
*/
1429
static void
1430
start_window_system(session_t *sp)
1431
{
1432
pid_t pid;
1433
sigset_t mask;
1434
char term[64], *env[2];
1435
int status;
1436
1437
if ((pid = fork()) == -1) {
1438
emergency("can't fork for window system on port %s: %m",
1439
sp->se_device);
1440
/* hope that getty fails and we can try again */
1441
return;
1442
}
1443
if (pid) {
1444
waitpid(-1, &status, 0);
1445
return;
1446
}
1447
1448
/* reparent window process to the init to not make a zombie on exit */
1449
if ((pid = fork()) == -1) {
1450
emergency("can't fork for window system on port %s: %m",
1451
sp->se_device);
1452
_exit(1);
1453
}
1454
if (pid)
1455
_exit(0);
1456
1457
sigemptyset(&mask);
1458
sigprocmask(SIG_SETMASK, &mask, NULL);
1459
1460
if (setsid() < 0)
1461
emergency("setsid failed (window) %m");
1462
1463
#ifdef LOGIN_CAP
1464
setprocresources(RESOURCE_WINDOW);
1465
#endif
1466
if (sp->se_type) {
1467
/* Don't use malloc after fork */
1468
strcpy(term, "TERM=");
1469
strlcat(term, sp->se_type, sizeof(term));
1470
env[0] = term;
1471
env[1] = NULL;
1472
}
1473
else
1474
env[0] = NULL;
1475
execve(sp->se_window_argv[0], sp->se_window_argv, env);
1476
stall("can't exec window system '%s' for port %s: %m",
1477
sp->se_window_argv[0], sp->se_device);
1478
_exit(1);
1479
}
1480
1481
/*
1482
* Start a login session running.
1483
*/
1484
static pid_t
1485
start_getty(session_t *sp)
1486
{
1487
pid_t pid;
1488
sigset_t mask;
1489
time_t current_time = time((time_t *) 0);
1490
int too_quick = 0;
1491
char term[64], *env[2];
1492
1493
if (current_time >= sp->se_started &&
1494
current_time - sp->se_started < GETTY_SPACING) {
1495
if (++sp->se_nspace > GETTY_NSPACE) {
1496
sp->se_nspace = 0;
1497
too_quick = 1;
1498
}
1499
} else
1500
sp->se_nspace = 0;
1501
1502
/*
1503
* fork(), not vfork() -- we can't afford to block.
1504
*/
1505
if ((pid = fork()) == -1) {
1506
emergency("can't fork for getty on port %s: %m", sp->se_device);
1507
return -1;
1508
}
1509
1510
if (pid)
1511
return pid;
1512
1513
if (too_quick) {
1514
warning("getty repeating too quickly on port %s, sleeping %d secs",
1515
sp->se_device, GETTY_SLEEP);
1516
sleep((unsigned) GETTY_SLEEP);
1517
}
1518
1519
if (sp->se_window) {
1520
start_window_system(sp);
1521
sleep(WINDOW_WAIT);
1522
}
1523
1524
sigemptyset(&mask);
1525
sigprocmask(SIG_SETMASK, &mask, NULL);
1526
1527
#ifdef LOGIN_CAP
1528
setprocresources(RESOURCE_GETTY);
1529
#endif
1530
if (sp->se_type) {
1531
/* Don't use malloc after fork */
1532
strcpy(term, "TERM=");
1533
strlcat(term, sp->se_type, sizeof(term));
1534
env[0] = term;
1535
env[1] = NULL;
1536
} else
1537
env[0] = NULL;
1538
execve(sp->se_getty_argv[0], sp->se_getty_argv, env);
1539
stall("can't exec getty '%s' for port %s: %m",
1540
sp->se_getty_argv[0], sp->se_device);
1541
_exit(1);
1542
}
1543
1544
/*
1545
* Return 1 if the session is defined as "onifexists"
1546
* or "onifconsole" and the device node does not exist.
1547
*/
1548
static int
1549
session_has_no_tty(session_t *sp)
1550
{
1551
int fd;
1552
1553
if ((sp->se_flags & SE_IFEXISTS) == 0 &&
1554
(sp->se_flags & SE_IFCONSOLE) == 0)
1555
return (0);
1556
1557
fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0);
1558
if (fd < 0) {
1559
if (errno == ENOENT)
1560
return (1);
1561
return (0);
1562
}
1563
1564
close(fd);
1565
return (0);
1566
}
1567
1568
/*
1569
* Collect exit status for a child.
1570
* If an exiting login, start a new login running.
1571
*/
1572
static void
1573
collect_child(pid_t pid)
1574
{
1575
session_t *sp, *sprev, *snext;
1576
1577
if (! sessions)
1578
return;
1579
1580
if (! (sp = find_session(pid)))
1581
return;
1582
1583
del_session(sp);
1584
sp->se_process = 0;
1585
1586
if (sp->se_flags & SE_SHUTDOWN ||
1587
session_has_no_tty(sp)) {
1588
if ((sprev = sp->se_prev) != NULL)
1589
sprev->se_next = sp->se_next;
1590
else
1591
sessions = sp->se_next;
1592
if ((snext = sp->se_next) != NULL)
1593
snext->se_prev = sp->se_prev;
1594
free_session(sp);
1595
return;
1596
}
1597
1598
if ((pid = start_getty(sp)) == -1) {
1599
/* serious trouble */
1600
requested_transition = clean_ttys;
1601
return;
1602
}
1603
1604
sp->se_process = pid;
1605
sp->se_started = time((time_t *) 0);
1606
add_session(sp);
1607
}
1608
1609
static const char *
1610
get_current_state(void)
1611
{
1612
1613
if (current_state == single_user)
1614
return ("single-user");
1615
if (current_state == runcom)
1616
return ("runcom");
1617
if (current_state == read_ttys)
1618
return ("read-ttys");
1619
if (current_state == multi_user)
1620
return ("multi-user");
1621
if (current_state == clean_ttys)
1622
return ("clean-ttys");
1623
if (current_state == catatonia)
1624
return ("catatonia");
1625
if (current_state == death)
1626
return ("death");
1627
if (current_state == death_single)
1628
return ("death-single");
1629
return ("unknown");
1630
}
1631
1632
static void
1633
boottrace_transition(int sig)
1634
{
1635
const char *action;
1636
1637
switch (sig) {
1638
case SIGUSR2:
1639
action = "halt & poweroff";
1640
break;
1641
case SIGUSR1:
1642
action = "halt";
1643
break;
1644
case SIGINT:
1645
action = "reboot";
1646
break;
1647
case SIGWINCH:
1648
action = "powercycle";
1649
break;
1650
case SIGTERM:
1651
action = Reboot ? "reboot" : "single-user";
1652
break;
1653
default:
1654
BOOTTRACE("signal %d from %s", sig, get_current_state());
1655
return;
1656
}
1657
1658
/* Trace the shutdown reason. */
1659
SHUTTRACE("%s from %s", action, get_current_state());
1660
}
1661
1662
/*
1663
* Catch a signal and request a state transition.
1664
*/
1665
static void
1666
transition_handler(int sig)
1667
{
1668
1669
boottrace_transition(sig);
1670
switch (sig) {
1671
case SIGHUP:
1672
if (current_state == read_ttys || current_state == multi_user ||
1673
current_state == clean_ttys || current_state == catatonia)
1674
requested_transition = clean_ttys;
1675
break;
1676
case SIGUSR2:
1677
howto = RB_POWEROFF;
1678
case SIGUSR1:
1679
howto |= RB_HALT;
1680
case SIGWINCH:
1681
case SIGINT:
1682
if (sig == SIGWINCH)
1683
howto |= RB_POWERCYCLE;
1684
Reboot = true;
1685
case SIGTERM:
1686
if (current_state == read_ttys || current_state == multi_user ||
1687
current_state == clean_ttys || current_state == catatonia)
1688
requested_transition = death;
1689
else
1690
requested_transition = death_single;
1691
break;
1692
case SIGTSTP:
1693
if (current_state == runcom || current_state == read_ttys ||
1694
current_state == clean_ttys ||
1695
current_state == multi_user || current_state == catatonia)
1696
requested_transition = catatonia;
1697
break;
1698
case SIGEMT:
1699
requested_transition = reroot;
1700
break;
1701
default:
1702
requested_transition = 0;
1703
break;
1704
}
1705
}
1706
1707
/*
1708
* Take the system multiuser.
1709
*/
1710
static state_func_t
1711
multi_user(void)
1712
{
1713
static bool inmultiuser = false;
1714
pid_t pid;
1715
session_t *sp;
1716
1717
requested_transition = 0;
1718
1719
/*
1720
* If the administrator has not set the security level to -1
1721
* to indicate that the kernel should not run multiuser in secure
1722
* mode, and the run script has not set a higher level of security
1723
* than level 1, then put the kernel into secure mode.
1724
*/
1725
if (getsecuritylevel() == 0)
1726
setsecuritylevel(1);
1727
1728
for (sp = sessions; sp; sp = sp->se_next) {
1729
if (sp->se_process)
1730
continue;
1731
if (session_has_no_tty(sp))
1732
continue;
1733
if ((pid = start_getty(sp)) == -1) {
1734
/* serious trouble */
1735
requested_transition = clean_ttys;
1736
break;
1737
}
1738
sp->se_process = pid;
1739
sp->se_started = time((time_t *) 0);
1740
add_session(sp);
1741
}
1742
1743
if (requested_transition == 0 && !inmultiuser) {
1744
inmultiuser = true;
1745
/* This marks the change from boot-time tracing to run-time. */
1746
RUNTRACE("multi-user start");
1747
}
1748
while (!requested_transition)
1749
if ((pid = waitpid(-1, (int *) 0, 0)) != -1)
1750
collect_child(pid);
1751
1752
return (state_func_t) requested_transition;
1753
}
1754
1755
/*
1756
* This is an (n*2)+(n^2) algorithm. We hope it isn't run often...
1757
*/
1758
static state_func_t
1759
clean_ttys(void)
1760
{
1761
session_t *sp, *sprev;
1762
struct ttyent *typ;
1763
int devlen;
1764
char *old_getty, *old_window, *old_type;
1765
1766
/*
1767
* mark all sessions for death, (!SE_PRESENT)
1768
* as we find or create new ones they'll be marked as keepers,
1769
* we'll later nuke all the ones not found in /etc/ttys
1770
*/
1771
for (sp = sessions; sp != NULL; sp = sp->se_next)
1772
sp->se_flags &= ~SE_PRESENT;
1773
1774
devlen = sizeof(_PATH_DEV) - 1;
1775
while ((typ = getttyent()) != NULL) {
1776
for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next)
1777
if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
1778
break;
1779
1780
if (sp) {
1781
/* we want this one to live */
1782
sp->se_flags |= SE_PRESENT;
1783
if ((typ->ty_status & TTY_ON) == 0 ||
1784
typ->ty_getty == 0) {
1785
sp->se_flags |= SE_SHUTDOWN;
1786
kill(sp->se_process, SIGHUP);
1787
continue;
1788
}
1789
sp->se_flags &= ~SE_SHUTDOWN;
1790
old_getty = sp->se_getty ? strdup(sp->se_getty) : 0;
1791
old_window = sp->se_window ? strdup(sp->se_window) : 0;
1792
old_type = sp->se_type ? strdup(sp->se_type) : 0;
1793
if (setupargv(sp, typ) == 0) {
1794
warning("can't parse getty for port %s",
1795
sp->se_device);
1796
sp->se_flags |= SE_SHUTDOWN;
1797
kill(sp->se_process, SIGHUP);
1798
}
1799
else if ( !old_getty
1800
|| (!old_type && sp->se_type)
1801
|| (old_type && !sp->se_type)
1802
|| (!old_window && sp->se_window)
1803
|| (old_window && !sp->se_window)
1804
|| (strcmp(old_getty, sp->se_getty) != 0)
1805
|| (old_window && strcmp(old_window, sp->se_window) != 0)
1806
|| (old_type && strcmp(old_type, sp->se_type) != 0)
1807
) {
1808
/* Don't set SE_SHUTDOWN here */
1809
sp->se_nspace = 0;
1810
sp->se_started = 0;
1811
kill(sp->se_process, SIGHUP);
1812
}
1813
if (old_getty)
1814
free(old_getty);
1815
if (old_window)
1816
free(old_window);
1817
if (old_type)
1818
free(old_type);
1819
continue;
1820
}
1821
1822
new_session(sprev, typ);
1823
}
1824
1825
endttyent();
1826
1827
/*
1828
* sweep through and kill all deleted sessions
1829
* ones who's /etc/ttys line was deleted (SE_PRESENT unset)
1830
*/
1831
for (sp = sessions; sp != NULL; sp = sp->se_next) {
1832
if ((sp->se_flags & SE_PRESENT) == 0) {
1833
sp->se_flags |= SE_SHUTDOWN;
1834
kill(sp->se_process, SIGHUP);
1835
}
1836
}
1837
1838
return (state_func_t) multi_user;
1839
}
1840
1841
/*
1842
* Block further logins.
1843
*/
1844
static state_func_t
1845
catatonia(void)
1846
{
1847
session_t *sp;
1848
1849
for (sp = sessions; sp; sp = sp->se_next)
1850
sp->se_flags |= SE_SHUTDOWN;
1851
1852
return (state_func_t) multi_user;
1853
}
1854
1855
/*
1856
* Note SIGALRM.
1857
*/
1858
static void
1859
alrm_handler(int sig)
1860
{
1861
1862
(void)sig;
1863
clang = true;
1864
}
1865
1866
/*
1867
* Bring the system down to single user.
1868
*/
1869
static state_func_t
1870
death(void)
1871
{
1872
int block, blocked;
1873
size_t len;
1874
1875
/* Temporarily block suspend. */
1876
len = sizeof(blocked);
1877
block = 1;
1878
if (sysctlbyname("kern.suspend_blocked", &blocked, &len,
1879
&block, sizeof(block)) == -1)
1880
blocked = 0;
1881
1882
/*
1883
* Also revoke the TTY here. Because runshutdown() may reopen
1884
* the TTY whose getty we're killing here, there is no guarantee
1885
* runshutdown() will perform the initial open() call, causing
1886
* the terminal attributes to be misconfigured.
1887
*/
1888
revoke_ttys();
1889
1890
/* Try to run the rc.shutdown script within a period of time */
1891
runshutdown();
1892
1893
/* Unblock suspend if we blocked it. */
1894
if (!blocked)
1895
sysctlbyname("kern.suspend_blocked", NULL, NULL,
1896
&blocked, sizeof(blocked));
1897
1898
return (state_func_t) death_single;
1899
}
1900
1901
/*
1902
* Do what is necessary to reinitialize single user mode or reboot
1903
* from an incomplete state.
1904
*/
1905
static state_func_t
1906
death_single(void)
1907
{
1908
int i;
1909
pid_t pid;
1910
static const int death_sigs[2] = { SIGTERM, SIGKILL };
1911
1912
revoke(_PATH_CONSOLE);
1913
1914
BOOTTRACE("start killing user processes");
1915
for (i = 0; i < 2; ++i) {
1916
if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH)
1917
return (state_func_t) single_user;
1918
1919
clang = false;
1920
alarm(DEATH_WATCH);
1921
do
1922
if ((pid = waitpid(-1, (int *)0, 0)) != -1)
1923
collect_child(pid);
1924
while (!clang && errno != ECHILD);
1925
1926
if (errno == ECHILD)
1927
return (state_func_t) single_user;
1928
}
1929
1930
warning("some processes would not die; ps axl advised");
1931
1932
return (state_func_t) single_user;
1933
}
1934
1935
static void
1936
revoke_ttys(void)
1937
{
1938
session_t *sp;
1939
1940
for (sp = sessions; sp; sp = sp->se_next) {
1941
sp->se_flags |= SE_SHUTDOWN;
1942
kill(sp->se_process, SIGHUP);
1943
revoke(sp->se_device);
1944
}
1945
}
1946
1947
/*
1948
* Run the system shutdown script.
1949
*
1950
* Exit codes: XXX I should document more
1951
* -2 shutdown script terminated abnormally
1952
* -1 fatal error - can't run script
1953
* 0 good.
1954
* >0 some error (exit code)
1955
*/
1956
static int
1957
runshutdown(void)
1958
{
1959
pid_t pid, wpid;
1960
int status;
1961
int shutdowntimeout;
1962
size_t len;
1963
char *argv[SCRIPT_ARGV_SIZE];
1964
struct stat sb;
1965
1966
BOOTTRACE("init(8): start rc.shutdown");
1967
1968
/*
1969
* rc.shutdown is optional, so to prevent any unnecessary
1970
* complaints from the shell we simply don't run it if the
1971
* file does not exist. If the stat() here fails for other
1972
* reasons, we'll let the shell complain.
1973
*/
1974
if (stat(_PATH_RUNDOWN, &sb) == -1 && errno == ENOENT)
1975
return 0;
1976
1977
if ((pid = fork()) == 0) {
1978
char _reboot[] = "reboot";
1979
char _single[] = "single";
1980
char _path_rundown[] = _PATH_RUNDOWN;
1981
1982
argv[0] = _path_rundown;
1983
argv[1] = Reboot ? _reboot : _single;
1984
argv[2] = NULL;
1985
1986
execute_script(argv);
1987
_exit(1); /* force single user mode */
1988
}
1989
1990
if (pid == -1) {
1991
emergency("can't fork for %s: %m", _PATH_RUNDOWN);
1992
while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1993
continue;
1994
sleep(STALL_TIMEOUT);
1995
return -1;
1996
}
1997
1998
len = sizeof(shutdowntimeout);
1999
if (sysctlbyname("kern.init_shutdown_timeout", &shutdowntimeout, &len,
2000
NULL, 0) == -1 || shutdowntimeout < 2)
2001
shutdowntimeout = DEATH_SCRIPT;
2002
alarm(shutdowntimeout);
2003
clang = false;
2004
/*
2005
* Copied from single_user(). This is a bit paranoid.
2006
* Use the same ALRM handler.
2007
*/
2008
do {
2009
if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
2010
collect_child(wpid);
2011
if (clang) {
2012
/* we were waiting for the sub-shell */
2013
kill(wpid, SIGTERM);
2014
warning("timeout expired for %s: %m; going to "
2015
"single user mode", _PATH_RUNDOWN);
2016
BOOTTRACE("rc.shutdown's %d sec timeout expired",
2017
shutdowntimeout);
2018
return -1;
2019
}
2020
if (wpid == -1) {
2021
if (errno == EINTR)
2022
continue;
2023
warning("wait for %s failed: %m; going to "
2024
"single user mode", _PATH_RUNDOWN);
2025
return -1;
2026
}
2027
if (wpid == pid && WIFSTOPPED(status)) {
2028
warning("init: %s stopped, restarting\n",
2029
_PATH_RUNDOWN);
2030
kill(pid, SIGCONT);
2031
wpid = -1;
2032
}
2033
} while (wpid != pid && !clang);
2034
2035
/* Turn off the alarm */
2036
alarm(0);
2037
2038
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
2039
requested_transition == catatonia) {
2040
/*
2041
* /etc/rc.shutdown executed /sbin/reboot;
2042
* wait for the end quietly
2043
*/
2044
sigset_t s;
2045
2046
sigfillset(&s);
2047
for (;;)
2048
sigsuspend(&s);
2049
}
2050
2051
if (!WIFEXITED(status)) {
2052
warning("%s terminated abnormally, going to "
2053
"single user mode", _PATH_RUNDOWN);
2054
return -2;
2055
}
2056
2057
if ((status = WEXITSTATUS(status)) != 0)
2058
warning("%s returned status %d", _PATH_RUNDOWN, status);
2059
2060
return status;
2061
}
2062
2063
static char *
2064
strk(char *p)
2065
{
2066
static char *t;
2067
char *q;
2068
int c;
2069
2070
if (p)
2071
t = p;
2072
if (!t)
2073
return 0;
2074
2075
c = *t;
2076
while (c == ' ' || c == '\t' )
2077
c = *++t;
2078
if (!c) {
2079
t = 0;
2080
return 0;
2081
}
2082
q = t;
2083
if (c == '\'') {
2084
c = *++t;
2085
q = t;
2086
while (c && c != '\'')
2087
c = *++t;
2088
if (!c) /* unterminated string */
2089
q = t = 0;
2090
else
2091
*t++ = 0;
2092
} else {
2093
while (c && c != ' ' && c != '\t' )
2094
c = *++t;
2095
*t++ = 0;
2096
if (!c)
2097
t = 0;
2098
}
2099
return q;
2100
}
2101
2102
#ifdef LOGIN_CAP
2103
static void
2104
setprocresources(const char *cname)
2105
{
2106
login_cap_t *lc;
2107
if ((lc = login_getclassbyname(cname, NULL)) != NULL) {
2108
setusercontext(lc, (struct passwd*)NULL, 0,
2109
LOGIN_SETENV |
2110
LOGIN_SETPRIORITY | LOGIN_SETRESOURCES |
2111
LOGIN_SETLOGINCLASS | LOGIN_SETCPUMASK);
2112
login_close(lc);
2113
}
2114
}
2115
#endif
2116
2117
/*
2118
* Run /etc/rc.final to execute scripts after all user processes have been
2119
* terminated.
2120
*/
2121
static void
2122
runfinal(void)
2123
{
2124
struct stat sb;
2125
pid_t other_pid, pid;
2126
sigset_t mask;
2127
2128
/* Avoid any surprises. */
2129
alarm(0);
2130
2131
/* rc.final is optional. */
2132
if (stat(_PATH_RUNFINAL, &sb) == -1 && errno == ENOENT)
2133
return;
2134
if (access(_PATH_RUNFINAL, X_OK) != 0) {
2135
warning("%s exists, but not executable", _PATH_RUNFINAL);
2136
return;
2137
}
2138
2139
pid = fork();
2140
if (pid == 0) {
2141
/*
2142
* Reopen stdin/stdout/stderr so that scripts can write to
2143
* console.
2144
*/
2145
close(0);
2146
open(_PATH_DEVNULL, O_RDONLY);
2147
close(1);
2148
close(2);
2149
open_console();
2150
dup2(1, 2);
2151
sigemptyset(&mask);
2152
sigprocmask(SIG_SETMASK, &mask, NULL);
2153
signal(SIGCHLD, SIG_DFL);
2154
execl(_PATH_RUNFINAL, _PATH_RUNFINAL, NULL);
2155
perror("execl(" _PATH_RUNFINAL ") failed");
2156
exit(1);
2157
}
2158
2159
/* Wait for rc.final script to exit */
2160
while ((other_pid = waitpid(-1, NULL, 0)) != pid && other_pid > 0) {
2161
continue;
2162
}
2163
}
2164
2165