The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/init_main.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1995 Terrence R. Lambert
    3  * All rights reserved.
    4  *
    5  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. All advertising materials mentioning features or use of this software
   22  *    must display the following acknowledgement:
   23  *      This product includes software developed by the University of
   24  *      California, Berkeley and its contributors.
   25  * 4. Neither the name of the University nor the names of its contributors
   26  *    may be used to endorse or promote products derived from this software
   27  *    without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  *      @(#)init_main.c 8.9 (Berkeley) 1/21/94
   42  */
   43 
   44 #include <sys/cdefs.h>
   45 __FBSDID("$FreeBSD$");
   46 
   47 #include "opt_ddb.h"
   48 #include "opt_init_path.h"
   49 #include "opt_mac.h"
   50 
   51 #include <sys/param.h>
   52 #include <sys/kernel.h>
   53 #include <sys/exec.h>
   54 #include <sys/file.h>
   55 #include <sys/filedesc.h>
   56 #include <sys/ktr.h>
   57 #include <sys/lock.h>
   58 #include <sys/mount.h>
   59 #include <sys/mutex.h>
   60 #include <sys/syscallsubr.h>
   61 #include <sys/sysctl.h>
   62 #include <sys/proc.h>
   63 #include <sys/resourcevar.h>
   64 #include <sys/systm.h>
   65 #include <sys/signalvar.h>
   66 #include <sys/vnode.h>
   67 #include <sys/sysent.h>
   68 #include <sys/reboot.h>
   69 #include <sys/sched.h>
   70 #include <sys/sx.h>
   71 #include <sys/sysproto.h>
   72 #include <sys/vmmeter.h>
   73 #include <sys/unistd.h>
   74 #include <sys/malloc.h>
   75 #include <sys/conf.h>
   76 
   77 #include <machine/cpu.h>
   78 
   79 #include <security/audit/audit.h>
   80 #include <security/mac/mac_framework.h>
   81 
   82 #include <vm/vm.h>
   83 #include <vm/vm_param.h>
   84 #include <vm/pmap.h>
   85 #include <vm/vm_map.h>
   86 #include <sys/copyright.h>
   87 
   88 #include <ddb/ddb.h>
   89 #include <ddb/db_sym.h>
   90 
   91 void mi_startup(void);                          /* Should be elsewhere */
   92 
   93 /* Components of the first process -- never freed. */
   94 static struct session session0;
   95 static struct pgrp pgrp0;
   96 struct  proc proc0;
   97 struct  thread thread0 __aligned(16);
   98 struct  vmspace vmspace0;
   99 struct  proc *initproc;
  100 
  101 int     boothowto = 0;          /* initialized so that it can be patched */
  102 SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
  103 int     bootverbose;
  104 SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
  105 
  106 /*
  107  * This ensures that there is at least one entry so that the sysinit_set
  108  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
  109  * executed.
  110  */
  111 SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
  112 
  113 /*
  114  * The sysinit table itself.  Items are checked off as the are run.
  115  * If we want to register new sysinit types, add them to newsysinit.
  116  */
  117 SET_DECLARE(sysinit_set, struct sysinit);
  118 struct sysinit **sysinit, **sysinit_end;
  119 struct sysinit **newsysinit, **newsysinit_end;
  120 
  121 /*
  122  * Merge a new sysinit set into the current set, reallocating it if
  123  * necessary.  This can only be called after malloc is running.
  124  */
  125 void
  126 sysinit_add(struct sysinit **set, struct sysinit **set_end)
  127 {
  128         struct sysinit **newset;
  129         struct sysinit **sipp;
  130         struct sysinit **xipp;
  131         int count;
  132 
  133         count = set_end - set;
  134         if (newsysinit)
  135                 count += newsysinit_end - newsysinit;
  136         else
  137                 count += sysinit_end - sysinit;
  138         newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
  139         if (newset == NULL)
  140                 panic("cannot malloc for sysinit");
  141         xipp = newset;
  142         if (newsysinit)
  143                 for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
  144                         *xipp++ = *sipp;
  145         else
  146                 for (sipp = sysinit; sipp < sysinit_end; sipp++)
  147                         *xipp++ = *sipp;
  148         for (sipp = set; sipp < set_end; sipp++)
  149                 *xipp++ = *sipp;
  150         if (newsysinit)
  151                 free(newsysinit, M_TEMP);
  152         newsysinit = newset;
  153         newsysinit_end = newset + count;
  154 }
  155 
  156 /*
  157  * System startup; initialize the world, create process 0, mount root
  158  * filesystem, and fork to create init and pagedaemon.  Most of the
  159  * hard work is done in the lower-level initialization routines including
  160  * startup(), which does memory initialization and autoconfiguration.
  161  *
  162  * This allows simple addition of new kernel subsystems that require
  163  * boot time initialization.  It also allows substitution of subsystem
  164  * (for instance, a scheduler, kernel profiler, or VM system) by object
  165  * module.  Finally, it allows for optional "kernel threads".
  166  */
  167 void
  168 mi_startup(void)
  169 {
  170 
  171         register struct sysinit **sipp;         /* system initialization*/
  172         register struct sysinit **xipp;         /* interior loop of sort*/
  173         register struct sysinit *save;          /* bubble*/
  174 
  175 #if defined(VERBOSE_SYSINIT)
  176         int last;
  177         int verbose;
  178 #endif
  179 
  180         if (sysinit == NULL) {
  181                 sysinit = SET_BEGIN(sysinit_set);
  182                 sysinit_end = SET_LIMIT(sysinit_set);
  183         }
  184 
  185 restart:
  186         /*
  187          * Perform a bubble sort of the system initialization objects by
  188          * their subsystem (primary key) and order (secondary key).
  189          */
  190         for (sipp = sysinit; sipp < sysinit_end; sipp++) {
  191                 for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
  192                         if ((*sipp)->subsystem < (*xipp)->subsystem ||
  193                              ((*sipp)->subsystem == (*xipp)->subsystem &&
  194                               (*sipp)->order <= (*xipp)->order))
  195                                 continue;       /* skip*/
  196                         save = *sipp;
  197                         *sipp = *xipp;
  198                         *xipp = save;
  199                 }
  200         }
  201 
  202 #if defined(VERBOSE_SYSINIT)
  203         last = SI_SUB_COPYRIGHT;
  204         verbose = 0;
  205 #if !defined(DDB)
  206         printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
  207 #endif
  208 #endif
  209 
  210         /*
  211          * Traverse the (now) ordered list of system initialization tasks.
  212          * Perform each task, and continue on to the next task.
  213          *
  214          * The last item on the list is expected to be the scheduler,
  215          * which will not return.
  216          */
  217         for (sipp = sysinit; sipp < sysinit_end; sipp++) {
  218 
  219                 if ((*sipp)->subsystem == SI_SUB_DUMMY)
  220                         continue;       /* skip dummy task(s)*/
  221 
  222                 if ((*sipp)->subsystem == SI_SUB_DONE)
  223                         continue;
  224 
  225 #if defined(VERBOSE_SYSINIT)
  226                 if ((*sipp)->subsystem > last) {
  227                         verbose = 1;
  228                         last = (*sipp)->subsystem;
  229                         printf("subsystem %x\n", last);
  230                 }
  231                 if (verbose) {
  232 #if defined(DDB)
  233                         const char *name;
  234                         c_db_sym_t sym;
  235                         db_expr_t  offset;
  236 
  237                         sym = db_search_symbol((vm_offset_t)(*sipp)->func,
  238                             DB_STGY_PROC, &offset);
  239                         db_symbol_values(sym, &name, NULL);
  240                         if (name != NULL)
  241                                 printf("   %s(%p)... ", name, (*sipp)->udata);
  242                         else
  243 #endif
  244                                 printf("   %p(%p)... ", (*sipp)->func,
  245                                     (*sipp)->udata);
  246                 }
  247 #endif
  248 
  249                 /* Call function */
  250                 (*((*sipp)->func))((*sipp)->udata);
  251 
  252 #if defined(VERBOSE_SYSINIT)
  253                 if (verbose)
  254                         printf("done.\n");
  255 #endif
  256 
  257                 /* Check off the one we're just done */
  258                 (*sipp)->subsystem = SI_SUB_DONE;
  259 
  260                 /* Check if we've installed more sysinit items via KLD */
  261                 if (newsysinit != NULL) {
  262                         if (sysinit != SET_BEGIN(sysinit_set))
  263                                 free(sysinit, M_TEMP);
  264                         sysinit = newsysinit;
  265                         sysinit_end = newsysinit_end;
  266                         newsysinit = NULL;
  267                         newsysinit_end = NULL;
  268                         goto restart;
  269                 }
  270         }
  271 
  272         panic("Shouldn't get here!");
  273         /* NOTREACHED*/
  274 }
  275 
  276 
  277 /*
  278  ***************************************************************************
  279  ****
  280  **** The following SYSINIT's belong elsewhere, but have not yet
  281  **** been moved.
  282  ****
  283  ***************************************************************************
  284  */
  285 static void
  286 print_caddr_t(void *data __unused)
  287 {
  288         printf("%s", (char *)data);
  289 }
  290 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
  291 SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, trademark)
  292 SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_caddr_t, version)
  293 
  294 #ifdef WITNESS
  295 static char wit_warn[] =
  296      "WARNING: WITNESS option enabled, expect reduced performance.\n";
  297 SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
  298    print_caddr_t, wit_warn)
  299 SYSINIT(witwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 1,
  300    print_caddr_t, wit_warn)
  301 #endif
  302 
  303 #ifdef DIAGNOSTIC
  304 static char diag_warn[] =
  305      "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
  306 SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
  307     print_caddr_t, diag_warn)
  308 SYSINIT(diagwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 2,
  309     print_caddr_t, diag_warn)
  310 #endif
  311 
  312 static void
  313 set_boot_verbose(void *data __unused)
  314 {
  315 
  316         if (boothowto & RB_VERBOSE)
  317                 bootverbose++;
  318 }
  319 SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
  320 
  321 struct sysentvec null_sysvec = {
  322         0,
  323         NULL,
  324         0,
  325         0,
  326         NULL,
  327         0,
  328         NULL,
  329         NULL,
  330         NULL,
  331         NULL,
  332         NULL,
  333         NULL,
  334         NULL,
  335         "null",
  336         NULL,
  337         NULL,
  338         0,
  339         PAGE_SIZE,
  340         VM_MIN_ADDRESS,
  341         VM_MAXUSER_ADDRESS,
  342         USRSTACK,
  343         PS_STRINGS,
  344         VM_PROT_ALL,
  345         NULL,
  346         NULL,
  347         NULL
  348 };
  349 
  350 /*
  351  ***************************************************************************
  352  ****
  353  **** The two following SYSINIT's are proc0 specific glue code.  I am not
  354  **** convinced that they can not be safely combined, but their order of
  355  **** operation has been maintained as the same as the original init_main.c
  356  **** for right now.
  357  ****
  358  **** These probably belong in init_proc.c or kern_proc.c, since they
  359  **** deal with proc0 (the fork template process).
  360  ****
  361  ***************************************************************************
  362  */
  363 /* ARGSUSED*/
  364 static void
  365 proc0_init(void *dummy __unused)
  366 {
  367         struct proc *p;
  368         unsigned i;
  369         struct thread *td;
  370 
  371         GIANT_REQUIRED;
  372         p = &proc0;
  373         td = &thread0;
  374 
  375         /*
  376          * Initialize magic number and osrel.
  377          */
  378         p->p_magic = P_MAGIC;
  379         p->p_osrel = osreldate;
  380 
  381         /*
  382          * Initialize thread and process structures.
  383          */
  384         procinit();     /* set up proc zone */
  385         threadinit();   /* set up UMA zones */
  386 
  387         /*
  388          * Initialise scheduler resources.
  389          * Add scheduler specific parts to proc, thread as needed.
  390          */
  391         schedinit();    /* scheduler gets its house in order */
  392         /*
  393          * Initialize sleep queue hash table
  394          */
  395         sleepinit();
  396 
  397         /*
  398          * additional VM structures
  399          */
  400         vm_init2();
  401 
  402         /*
  403          * Create process 0 (the swapper).
  404          */
  405         LIST_INSERT_HEAD(&allproc, p, p_list);
  406         LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
  407         mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
  408         p->p_pgrp = &pgrp0;
  409         LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
  410         LIST_INIT(&pgrp0.pg_members);
  411         LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
  412 
  413         pgrp0.pg_session = &session0;
  414         mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
  415         session0.s_count = 1;
  416         session0.s_leader = p;
  417 
  418         p->p_sysent = &null_sysvec;
  419         p->p_flag = P_SYSTEM | P_INMEM;
  420         p->p_state = PRS_NORMAL;
  421         knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL);
  422         STAILQ_INIT(&p->p_ktr);
  423         p->p_nice = NZERO;
  424         td->td_state = TDS_RUNNING;
  425         td->td_pri_class = PRI_TIMESHARE;
  426         td->td_user_pri = PUSER;
  427         td->td_base_user_pri = PUSER;
  428         td->td_priority = PVM;
  429         td->td_base_pri = PUSER;
  430         td->td_oncpu = 0;
  431         td->td_flags = TDF_INMEM;
  432         p->p_peers = 0;
  433         p->p_leader = p;
  434 
  435 
  436         bcopy("swapper", p->p_comm, sizeof ("swapper"));
  437 
  438         callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
  439         callout_init_mtx(&p->p_limco, &p->p_mtx, 0);
  440         callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
  441 
  442         /* Create credentials. */
  443         p->p_ucred = crget();
  444         p->p_ucred->cr_ngroups = 1;     /* group 0 */
  445         p->p_ucred->cr_uidinfo = uifind(0);
  446         p->p_ucred->cr_ruidinfo = uifind(0);
  447         p->p_ucred->cr_prison = NULL;   /* Don't jail it. */
  448 #ifdef AUDIT
  449         audit_cred_kproc0(p->p_ucred);
  450 #endif
  451 #ifdef MAC
  452         mac_create_proc0(p->p_ucred);
  453 #endif
  454         td->td_ucred = crhold(p->p_ucred);
  455 
  456         /* Create sigacts. */
  457         p->p_sigacts = sigacts_alloc();
  458 
  459         /* Initialize signal state for process 0. */
  460         siginit(&proc0);
  461 
  462         /* Create the file descriptor table. */
  463         p->p_fd = fdinit(NULL);
  464         p->p_fdtol = NULL;
  465 
  466         /* Create the limits structures. */
  467         p->p_limit = lim_alloc();
  468         for (i = 0; i < RLIM_NLIMITS; i++)
  469                 p->p_limit->pl_rlimit[i].rlim_cur =
  470                     p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
  471         p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
  472             p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
  473         p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
  474             p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
  475         i = ptoa(cnt.v_free_count);
  476         p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
  477         p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
  478         p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
  479         p->p_cpulimit = RLIM_INFINITY;
  480 
  481         p->p_stats = pstats_alloc();
  482 
  483         /* Allocate a prototype map so we have something to fork. */
  484         pmap_pinit0(vmspace_pmap(&vmspace0));
  485         p->p_vmspace = &vmspace0;
  486         vmspace0.vm_refcnt = 1;
  487         vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
  488             p->p_sysent->sv_maxuser);
  489         vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
  490         /*-
  491          * call the init and ctor for the new thread and proc
  492          * we wait to do this until all other structures
  493          * are fairly sane.
  494          */
  495         EVENTHANDLER_INVOKE(process_init, p);
  496         EVENTHANDLER_INVOKE(thread_init, td);
  497         EVENTHANDLER_INVOKE(process_ctor, p);
  498         EVENTHANDLER_INVOKE(thread_ctor, td);
  499 
  500         /*
  501          * Charge root for one process.
  502          */
  503         (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
  504 }
  505 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
  506 
  507 /* ARGSUSED*/
  508 static void
  509 proc0_post(void *dummy __unused)
  510 {
  511         struct timespec ts;
  512         struct proc *p;
  513         struct rusage ru;
  514 
  515         /*
  516          * Now we can look at the time, having had a chance to verify the
  517          * time from the filesystem.  Pretend that proc0 started now.
  518          */
  519         sx_slock(&allproc_lock);
  520         FOREACH_PROC_IN_SYSTEM(p) {
  521                 microuptime(&p->p_stats->p_start);
  522                 PROC_SLOCK(p);
  523                 rufetch(p, &ru);        /* Clears thread stats */
  524                 PROC_SUNLOCK(p);
  525                 p->p_rux.rux_runtime = 0;
  526                 p->p_rux.rux_uticks = 0;
  527                 p->p_rux.rux_sticks = 0;
  528                 p->p_rux.rux_iticks = 0;
  529         }
  530         sx_sunlock(&allproc_lock);
  531         PCPU_SET(switchtime, cpu_ticks());
  532         PCPU_SET(switchticks, ticks);
  533 
  534         /*
  535          * Give the ``random'' number generator a thump.
  536          */
  537         nanotime(&ts);
  538         srandom(ts.tv_sec ^ ts.tv_nsec);
  539 }
  540 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
  541 
  542 /*
  543  ***************************************************************************
  544  ****
  545  **** The following SYSINIT's and glue code should be moved to the
  546  **** respective files on a per subsystem basis.
  547  ****
  548  ***************************************************************************
  549  */
  550 
  551 
  552 /*
  553  ***************************************************************************
  554  ****
  555  **** The following code probably belongs in another file, like
  556  **** kern/init_init.c.
  557  ****
  558  ***************************************************************************
  559  */
  560 
  561 /*
  562  * List of paths to try when searching for "init".
  563  */
  564 static char init_path[MAXPATHLEN] =
  565 #ifdef  INIT_PATH
  566     __XSTRING(INIT_PATH);
  567 #else
  568     "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
  569 #endif
  570 SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
  571         "Path used to search the init process");
  572 
  573 /*
  574  * Shutdown timeout of init(8).
  575  * Unused within kernel, but used to control init(8), hence do not remove.
  576  */
  577 #ifndef INIT_SHUTDOWN_TIMEOUT
  578 #define INIT_SHUTDOWN_TIMEOUT 120
  579 #endif
  580 static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT;
  581 SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
  582         CTLFLAG_RW, &init_shutdown_timeout, 0, "");
  583 
  584 /*
  585  * Start the initial user process; try exec'ing each pathname in init_path.
  586  * The program is invoked with one argument containing the boot flags.
  587  */
  588 static void
  589 start_init(void *dummy)
  590 {
  591         vm_offset_t addr;
  592         struct execve_args args;
  593         int options, error;
  594         char *var, *path, *next, *s;
  595         char *ucp, **uap, *arg0, *arg1;
  596         struct thread *td;
  597         struct proc *p;
  598 
  599         mtx_lock(&Giant);
  600 
  601         GIANT_REQUIRED;
  602 
  603         td = curthread;
  604         p = td->td_proc;
  605 
  606         vfs_mountroot();
  607 
  608         /*
  609          * Need just enough stack to hold the faked-up "execve()" arguments.
  610          */
  611         addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
  612         if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
  613                         FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
  614                 panic("init: couldn't allocate argument space");
  615         p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
  616         p->p_vmspace->vm_ssize = 1;
  617 
  618         if ((var = getenv("init_path")) != NULL) {
  619                 strlcpy(init_path, var, sizeof(init_path));
  620                 freeenv(var);
  621         }
  622         
  623         for (path = init_path; *path != '\0'; path = next) {
  624                 while (*path == ':')
  625                         path++;
  626                 if (*path == '\0')
  627                         break;
  628                 for (next = path; *next != '\0' && *next != ':'; next++)
  629                         /* nothing */ ;
  630                 if (bootverbose)
  631                         printf("start_init: trying %.*s\n", (int)(next - path),
  632                             path);
  633                         
  634                 /*
  635                  * Move out the boot flag argument.
  636                  */
  637                 options = 0;
  638                 ucp = (char *)p->p_sysent->sv_usrstack;
  639                 (void)subyte(--ucp, 0);         /* trailing zero */
  640                 if (boothowto & RB_SINGLE) {
  641                         (void)subyte(--ucp, 's');
  642                         options = 1;
  643                 }
  644 #ifdef notyet
  645                 if (boothowto & RB_FASTBOOT) {
  646                         (void)subyte(--ucp, 'f');
  647                         options = 1;
  648                 }
  649 #endif
  650 
  651 #ifdef BOOTCDROM
  652                 (void)subyte(--ucp, 'C');
  653                 options = 1;
  654 #endif
  655 
  656                 if (options == 0)
  657                         (void)subyte(--ucp, '-');
  658                 (void)subyte(--ucp, '-');               /* leading hyphen */
  659                 arg1 = ucp;
  660 
  661                 /*
  662                  * Move out the file name (also arg 0).
  663                  */
  664                 (void)subyte(--ucp, 0);
  665                 for (s = next - 1; s >= path; s--)
  666                         (void)subyte(--ucp, *s);
  667                 arg0 = ucp;
  668 
  669                 /*
  670                  * Move out the arg pointers.
  671                  */
  672                 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
  673                 (void)suword((caddr_t)--uap, (long)0);  /* terminator */
  674                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
  675                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
  676 
  677                 /*
  678                  * Point at the arguments.
  679                  */
  680                 args.fname = arg0;
  681                 args.argv = uap;
  682                 args.envv = NULL;
  683 
  684                 /*
  685                  * Now try to exec the program.  If can't for any reason
  686                  * other than it doesn't exist, complain.
  687                  *
  688                  * Otherwise, return via fork_trampoline() all the way
  689                  * to user mode as init!
  690                  */
  691                 if ((error = execve(td, &args)) == 0) {
  692                         mtx_unlock(&Giant);
  693                         return;
  694                 }
  695                 if (error != ENOENT)
  696                         printf("exec %.*s: error %d\n", (int)(next - path), 
  697                             path, error);
  698         }
  699         printf("init: not found in path %s\n", init_path);
  700         panic("no init");
  701 }
  702 
  703 /*
  704  * Like kthread_create(), but runs in it's own address space.
  705  * We do this early to reserve pid 1.
  706  *
  707  * Note special case - do not make it runnable yet.  Other work
  708  * in progress will change this more.
  709  */
  710 static void
  711 create_init(const void *udata __unused)
  712 {
  713         struct ucred *newcred, *oldcred;
  714         int error;
  715 
  716         error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
  717         if (error)
  718                 panic("cannot fork init: %d\n", error);
  719         KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
  720         /* divorce init's credentials from the kernel's */
  721         newcred = crget();
  722         PROC_LOCK(initproc);
  723         initproc->p_flag |= P_SYSTEM | P_INMEM;
  724         oldcred = initproc->p_ucred;
  725         crcopy(newcred, oldcred);
  726 #ifdef MAC
  727         mac_create_proc1(newcred);
  728 #endif
  729 #ifdef AUDIT
  730         audit_cred_proc1(newcred);
  731 #endif
  732         initproc->p_ucred = newcred;
  733         PROC_UNLOCK(initproc);
  734         crfree(oldcred);
  735         cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
  736         cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
  737 }
  738 SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
  739 
  740 /*
  741  * Make it runnable now.
  742  */
  743 static void
  744 kick_init(const void *udata __unused)
  745 {
  746         struct thread *td;
  747 
  748         td = FIRST_THREAD_IN_PROC(initproc);
  749         thread_lock(td);
  750         TD_SET_CAN_RUN(td);
  751         sched_add(td, SRQ_BORING);
  752         thread_unlock(td);
  753 }
  754 SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)

Cache object: ac9c1e82f674d9df1be7e0b68e6b1b43


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.