44 #include <sys/cdefs.h>
48 #include "opt_init_path.h"
50 #include <sys/param.h>
51 #include <sys/kernel.h>
54 #include <sys/filedesc.h>
58 #include <sys/loginclass.h>
59 #include <sys/mount.h>
60 #include <sys/mutex.h>
61 #include <sys/syscallsubr.h>
62 #include <sys/sysctl.h>
64 #include <sys/racct.h>
65 #include <sys/resourcevar.h>
66 #include <sys/systm.h>
67 #include <sys/signalvar.h>
68 #include <sys/vnode.h>
69 #include <sys/sysent.h>
70 #include <sys/reboot.h>
71 #include <sys/sched.h>
73 #include <sys/sysproto.h>
74 #include <sys/vmmeter.h>
75 #include <sys/unistd.h>
76 #include <sys/malloc.h>
78 #include <sys/cpuset.h>
80 #include <machine/cpu.h>
82 #include <security/audit/audit.h>
83 #include <security/mac/mac_framework.h>
86 #include <vm/vm_param.h>
88 #include <vm/vm_map.h>
89 #include <sys/copyright.h>
92 #include <ddb/db_sym.h>
106 "Boot control flags, passed from loader");
109 "Control the output of verbose kernel messages");
116 SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL);
138 count = set_end -
set;
143 newset =
malloc(count *
sizeof(*sipp), M_TEMP, M_NOWAIT);
145 panic(
"cannot malloc for sysinit");
153 for (sipp = set; sipp < set_end; sipp++)
156 free(newsysinit, M_TEMP);
158 newsysinit_end = newset +
count;
161 #if defined (DDB) && defined(VERBOSE_SYSINIT)
163 symbol_name(vm_offset_t va, db_strategy_t strategy)
171 sym = db_search_symbol(va, strategy, &offset);
174 db_symbol_values(sym, &name, NULL);
194 register struct sysinit **sipp;
195 register struct sysinit **xipp;
198 #if defined(VERBOSE_SYSINIT)
207 sysinit = SET_BEGIN(sysinit_set);
217 for (xipp = sipp + 1; xipp <
sysinit_end; xipp++) {
218 if ((*sipp)->subsystem < (*xipp)->subsystem ||
219 ((*sipp)->subsystem == (*xipp)->subsystem &&
220 (*sipp)->order <= (*xipp)->order))
228 #if defined(VERBOSE_SYSINIT)
229 last = SI_SUB_COPYRIGHT;
232 printf(
"VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
242 if ((*sipp)->subsystem == SI_SUB_DUMMY)
245 if ((*sipp)->subsystem == SI_SUB_DONE)
248 #if defined(VERBOSE_SYSINIT)
249 if ((*sipp)->subsystem > last) {
251 last = (*sipp)->subsystem;
252 printf(
"subsystem %x\n", last);
256 const char *func, *data;
262 if (func != NULL && data != NULL)
263 printf(
" %s(&%s)... ", func, data);
264 else if (func != NULL)
265 printf(
" %s(%p)... ", func, (*sipp)->udata);
268 printf(
" %p(%p)... ", (*sipp)->func,
274 (*((*sipp)->func))((*sipp)->udata);
276 #if defined(VERBOSE_SYSINIT)
282 (*sipp)->subsystem = SI_SUB_DONE;
286 if (
sysinit != SET_BEGIN(sysinit_set))
296 mtx_assert(&
Giant, MA_OWNED | MA_NOTRECURSED);
318 printf(
"%s", (
char *)data);
327 len = strlen(version);
328 while (len > 0 && version[len - 1] ==
'\n')
330 printf(
"%.*s %s\n", len, version, machine);
331 printf(
"%s\n", compiler_version);
341 static char wit_warn[] =
342 "WARNING: WITNESS option enabled, expect reduced performance.\n";
343 SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
345 SYSINIT(witwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 1,
350 static char diag_warn[] =
351 "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
352 SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
354 SYSINIT(diagwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 2,
360 struct syscall_args *sa __unused)
363 panic(
"null_fetch_syscall_args");
370 panic(
"null_set_syscall_retval");
381 .sv_transtrap = NULL,
385 .sv_szsigcode = NULL,
386 .sv_prepsyscall = NULL,
389 .sv_imgact_try = NULL,
391 .sv_pagesize = PAGE_SIZE,
392 .sv_minuser = VM_MIN_ADDRESS,
393 .sv_maxuser = VM_MAXUSER_ADDRESS,
394 .sv_usrstack = USRSTACK,
395 .sv_psstrings = PS_STRINGS,
396 .sv_stackprot = VM_PROT_ALL,
397 .sv_copyout_strings = NULL,
404 .sv_syscallnames = NULL,
405 .sv_schedtail = NULL,
427 vm_paddr_t pageablemem;
437 p->p_magic = P_MAGIC;
438 p->p_osrel = osreldate;
464 LIST_INSERT_HEAD(&
allproc, p, p_list);
465 LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
466 mtx_init(&
pgrp0.pg_mtx,
"process group", NULL, MTX_DEF | MTX_DUPOK);
468 LIST_INSERT_HEAD(PGRPHASH(0), &
pgrp0, pg_hash);
469 LIST_INIT(&
pgrp0.pg_members);
470 LIST_INSERT_HEAD(&
pgrp0.pg_members, p, p_pglist);
474 refcount_init(&
session0.s_count, 1);
478 p->p_flag = P_SYSTEM | P_INMEM | P_KTHREAD;
480 p->p_state = PRS_NORMAL;
482 STAILQ_INIT(&p->p_ktr);
485 td->td_tid = PID_MAX + 1;
486 LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
487 td->td_state = TDS_RUNNING;
488 td->td_pri_class = PRI_TIMESHARE;
489 td->td_user_pri = PUSER;
490 td->td_base_user_pri = PUSER;
491 td->td_lend_user_pri = PRI_MAX;
492 td->td_priority = PVM;
493 td->td_base_pri = PVM;
495 td->td_flags = TDF_INMEM|TDP_KTHREAD;
502 strncpy(p->p_comm,
"kernel", sizeof (p->p_comm));
503 strncpy(td->td_name,
"swapper", sizeof (td->td_name));
505 callout_init_mtx(&p->p_itcallout, &p->p_mtx, 0);
506 callout_init_mtx(&p->p_limco, &p->p_mtx, 0);
510 p->p_ucred =
crget();
511 p->p_ucred->cr_ngroups = 1;
512 p->p_ucred->cr_uidinfo =
uifind(0);
513 p->p_ucred->cr_ruidinfo =
uifind(0);
514 p->p_ucred->cr_prison = &
prison0;
517 audit_cred_kproc0(p->p_ucred);
520 mac_cred_create_swapper(p->p_ucred);
522 td->td_ucred =
crhold(p->p_ucred);
536 for (i = 0; i < RLIM_NLIMITS; i++)
537 p->p_limit->pl_rlimit[i].rlim_cur =
538 p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
539 p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
540 p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max =
maxfiles;
541 p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
542 p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max =
maxproc;
543 p->p_limit->pl_rlimit[RLIMIT_DATA].rlim_cur =
dfldsiz;
544 p->p_limit->pl_rlimit[RLIMIT_DATA].rlim_max =
maxdsiz;
545 p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur =
dflssiz;
546 p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_max =
maxssiz;
548 pageablemem = ptoa((vm_paddr_t)cnt.v_free_count);
549 p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_cur =
550 p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = pageablemem;
551 p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = pageablemem / 3;
552 p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = pageablemem;
553 p->p_cpulimit = RLIM_INFINITY;
561 pmap_pinit0(vmspace_pmap(&
vmspace0));
570 p->p_sysent->sv_minuser, p->p_sysent->sv_maxuser);
576 EVENTHANDLER_INVOKE(process_init, p);
578 EVENTHANDLER_INVOKE(process_ctor, p);
584 (void)
chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
605 FOREACH_PROC_IN_SYSTEM(p) {
610 p->p_rux.rux_runtime = 0;
611 p->p_rux.rux_uticks = 0;
612 p->p_rux.rux_sticks = 0;
613 p->p_rux.rux_iticks = 0;
614 FOREACH_THREAD_IN_PROC(p, td) {
620 PCPU_SET(switchticks,
ticks);
626 srandom(ts.tv_sec ^ ts.tv_nsec);
639 srandom(get_cyclecount());
667 __XSTRING(INIT_PATH);
669 "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
671 SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
672 "Path used to search the init process");
678 #ifndef INIT_SHUTDOWN_TIMEOUT
679 #define INIT_SHUTDOWN_TIMEOUT 120
682 SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
683 CTLFLAG_RW, &init_shutdown_timeout, 0,
"Shutdown timeout of init(8). "
684 "Unused within kernel, but used to control init(8)");
696 char *var, *
path, *next, *s;
697 char *
ucp, **uap, *arg0, *arg1;
713 addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
714 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
715 FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
716 panic(
"init: couldn't allocate argument space");
717 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
718 p->p_vmspace->vm_ssize = 1;
720 if ((var =
getenv(
"init_path")) != NULL) {
721 strlcpy(init_path, var,
sizeof(init_path));
725 for (path = init_path; *path !=
'\0'; path = next) {
730 for (next = path; *next !=
'\0' && *next !=
':'; next++)
733 printf(
"start_init: trying %.*s\n", (
int)(next - path),
740 ucp = (
char *)p->p_sysent->sv_usrstack;
741 (
void)subyte(--ucp, 0);
743 (void)subyte(--ucp,
's');
748 (void)subyte(--ucp,
'f');
754 (void)subyte(--ucp,
'C');
759 (void)subyte(--ucp,
'-');
760 (void)subyte(--ucp,
'-');
766 (void)subyte(--ucp, 0);
767 for (s = next - 1; s >=
path; s--)
768 (
void)subyte(--ucp, *s);
774 uap = (
char **)((intptr_t)ucp & ~(
sizeof(intptr_t)-1));
775 (void)
suword((caddr_t)--uap, (long)0);
776 (void)
suword((caddr_t)--uap, (long)(intptr_t)arg1);
777 (void)
suword((caddr_t)--uap, (long)(intptr_t)arg0);
798 printf(
"exec %.*s: error %d\n", (
int)(next - path),
801 printf(
"init: not found in path %s\n", init_path);
815 struct ucred *newcred, *oldcred;
818 error =
fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &
initproc,
821 panic(
"cannot fork init: %d\n", error);
822 KASSERT(
initproc->p_pid == 1, (
"create_init: initproc->p_pid != 1"));
826 initproc->p_flag |= P_SYSTEM | P_INMEM;
830 mac_cred_create_init(newcred);
833 audit_cred_proc1(newcred);
851 td = FIRST_THREAD_IN_PROC(
initproc);
struct sysentvec null_sysvec
static struct session session0
void rufetch(struct proc *p, struct rusage *ru)
struct sigacts * sigacts_alloc(void)
void cred_update_thread(struct thread *td)
static void kick_init(const void *udata __unused)
static void print_caddr_t(void *data)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
struct sysinit ** newsysinit
void siginit(struct proc *p)
static int null_fetch_syscall_args(struct thread *td __unused, struct syscall_args *sa __unused)
struct uidinfo * uifind(uid_t uid)
void panic(const char *fmt,...)
SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
static void start_init(void *dummy)
SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD,&boothowto, 0,"Boot control flags, passed from loader")
int fork1(struct thread *td, int flags, int pages, struct proc **procp, int *procdescp, int pdflags)
static void create_init(const void *udata __unused)
static void print_version(void *data __unused)
struct plimit * lim_alloc()
void sched_add(struct thread *td, int flags)
struct cpuset * cpuset_ref(struct cpuset *set)
void racct_add_force(struct proc *p, int resource, uint64_t amount)
struct filedesc * fdinit(struct filedesc *fdp)
static void random_init(void *dummy __unused)
struct sysinit ** newsysinit_end
struct sysinit ** sysinit
static int thread_init(void *mem, int size, int flags)
int chgproccnt(struct uidinfo *uip, int diff, rlim_t max)
struct pstats * pstats_alloc(void)
void crfree(struct ucred *cr)
struct cpuset * cpuset_thread0(void)
static void proc0_init(void *dummy __unused)
static int thread_ctor(void *mem, int size, void *arg, int flags)
void nanotime(struct timespec *tsp)
static int init_shutdown_timeout
char * getenv(const char *name)
int sys_execve(struct thread *td, struct execve_args *uap)
struct loginclass * loginclass_find(const char *name)
struct ucred * crhold(struct ucred *cr)
static void proc0_post(void *dummy __unused)
void free(void *addr, struct malloc_type *mtp)
#define INIT_SHUTDOWN_TIMEOUT
int printf(const char *fmt,...)
void callout_init(struct callout *c, int mpsafe)
static void null_set_syscall_retval(struct thread *td __unused, int error __unused)
void mtx_init(struct mtx *m, const char *name, const char *type, int opts)
SET_DECLARE(sysinit_set, struct sysinit)
void sysinit_add(struct sysinit **set, struct sysinit **set_end)
void microuptime(struct timeval *tvp)
struct getcontext_args * ucp
struct thread thread0 __aligned(16)
void crcopy(struct ucred *dest, struct ucred *src)
struct ucred * crget(void)
void racct_create(struct racct **racctp)
static char init_path[MAXPATHLEN]
SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,"Path used to search the init process")
static const char * symbol_name(elf_file_t ef, Elf_Size r_info)
void knlist_init_mtx(struct knlist *knl, struct mtx *lock)
struct sysinit ** sysinit_end