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/kern_shutdown.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) 1986, 1988, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  * (c) UNIX System Laboratories, Inc.
    5  * All or some portions of this file are derived from material licensed
    6  * to the University of California by American Telephone and Telegraph
    7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8  * the permission of UNIX System Laboratories, 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  * 4. 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  *      @(#)kern_shutdown.c     8.3 (Berkeley) 1/21/94
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD: releng/11.1/sys/kern/kern_shutdown.c 313119 2017-02-03 00:54:27Z markj $");
   39 
   40 #include "opt_ddb.h"
   41 #include "opt_kdb.h"
   42 #include "opt_panic.h"
   43 #include "opt_sched.h"
   44 #include "opt_watchdog.h"
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/bio.h>
   49 #include <sys/buf.h>
   50 #include <sys/conf.h>
   51 #include <sys/cons.h>
   52 #include <sys/eventhandler.h>
   53 #include <sys/filedesc.h>
   54 #include <sys/jail.h>
   55 #include <sys/kdb.h>
   56 #include <sys/kernel.h>
   57 #include <sys/kerneldump.h>
   58 #include <sys/kthread.h>
   59 #include <sys/ktr.h>
   60 #include <sys/malloc.h>
   61 #include <sys/mount.h>
   62 #include <sys/priv.h>
   63 #include <sys/proc.h>
   64 #include <sys/reboot.h>
   65 #include <sys/resourcevar.h>
   66 #include <sys/rwlock.h>
   67 #include <sys/sched.h>
   68 #include <sys/smp.h>
   69 #include <sys/sysctl.h>
   70 #include <sys/sysproto.h>
   71 #include <sys/vnode.h>
   72 #include <sys/watchdog.h>
   73 
   74 #include <ddb/ddb.h>
   75 
   76 #include <machine/cpu.h>
   77 #include <machine/dump.h>
   78 #include <machine/pcb.h>
   79 #include <machine/smp.h>
   80 
   81 #include <security/mac/mac_framework.h>
   82 
   83 #include <vm/vm.h>
   84 #include <vm/vm_object.h>
   85 #include <vm/vm_page.h>
   86 #include <vm/vm_pager.h>
   87 #include <vm/swap_pager.h>
   88 
   89 #include <sys/signalvar.h>
   90 
   91 static MALLOC_DEFINE(M_DUMPER, "dumper", "dumper block buffer");
   92 
   93 #ifndef PANIC_REBOOT_WAIT_TIME
   94 #define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
   95 #endif
   96 static int panic_reboot_wait_time = PANIC_REBOOT_WAIT_TIME;
   97 SYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN,
   98     &panic_reboot_wait_time, 0,
   99     "Seconds to wait before rebooting after a panic");
  100 
  101 /*
  102  * Note that stdarg.h and the ANSI style va_start macro is used for both
  103  * ANSI and traditional C compilers.
  104  */
  105 #include <machine/stdarg.h>
  106 
  107 #ifdef KDB
  108 #ifdef KDB_UNATTENDED
  109 int debugger_on_panic = 0;
  110 #else
  111 int debugger_on_panic = 1;
  112 #endif
  113 SYSCTL_INT(_debug, OID_AUTO, debugger_on_panic,
  114     CTLFLAG_RWTUN | CTLFLAG_SECURE,
  115     &debugger_on_panic, 0, "Run debugger on kernel panic");
  116 
  117 #ifdef KDB_TRACE
  118 static int trace_on_panic = 1;
  119 #else
  120 static int trace_on_panic = 0;
  121 #endif
  122 SYSCTL_INT(_debug, OID_AUTO, trace_on_panic,
  123     CTLFLAG_RWTUN | CTLFLAG_SECURE,
  124     &trace_on_panic, 0, "Print stack trace on kernel panic");
  125 #endif /* KDB */
  126 
  127 static int sync_on_panic = 0;
  128 SYSCTL_INT(_kern, OID_AUTO, sync_on_panic, CTLFLAG_RWTUN,
  129         &sync_on_panic, 0, "Do a sync before rebooting from a panic");
  130 
  131 static SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW, 0,
  132     "Shutdown environment");
  133 
  134 #ifndef DIAGNOSTIC
  135 static int show_busybufs;
  136 #else
  137 static int show_busybufs = 1;
  138 #endif
  139 SYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW,
  140         &show_busybufs, 0, "");
  141 
  142 int suspend_blocked = 0;
  143 SYSCTL_INT(_kern, OID_AUTO, suspend_blocked, CTLFLAG_RW,
  144         &suspend_blocked, 0, "Block suspend due to a pending shutdown");
  145 
  146 /*
  147  * Variable panicstr contains argument to first call to panic; used as flag
  148  * to indicate that the kernel has already called panic.
  149  */
  150 const char *panicstr;
  151 
  152 int dumping;                            /* system is dumping */
  153 int rebooting;                          /* system is rebooting */
  154 static struct dumperinfo dumper;        /* our selected dumper */
  155 
  156 /* Context information for dump-debuggers. */
  157 static struct pcb dumppcb;              /* Registers. */
  158 lwpid_t dumptid;                        /* Thread ID. */
  159 
  160 static struct cdevsw reroot_cdevsw = {
  161      .d_version = D_VERSION,
  162      .d_name    = "reroot",
  163 };
  164 
  165 static void poweroff_wait(void *, int);
  166 static void shutdown_halt(void *junk, int howto);
  167 static void shutdown_panic(void *junk, int howto);
  168 static void shutdown_reset(void *junk, int howto);
  169 static int kern_reroot(void);
  170 
  171 /* register various local shutdown events */
  172 static void
  173 shutdown_conf(void *unused)
  174 {
  175 
  176         EVENTHANDLER_REGISTER(shutdown_final, poweroff_wait, NULL,
  177             SHUTDOWN_PRI_FIRST);
  178         EVENTHANDLER_REGISTER(shutdown_final, shutdown_halt, NULL,
  179             SHUTDOWN_PRI_LAST + 100);
  180         EVENTHANDLER_REGISTER(shutdown_final, shutdown_panic, NULL,
  181             SHUTDOWN_PRI_LAST + 100);
  182         EVENTHANDLER_REGISTER(shutdown_final, shutdown_reset, NULL,
  183             SHUTDOWN_PRI_LAST + 200);
  184 }
  185 
  186 SYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL);
  187 
  188 /*
  189  * The only reason this exists is to create the /dev/reroot/ directory,
  190  * used by reroot code in init(8) as a mountpoint for tmpfs.
  191  */
  192 static void
  193 reroot_conf(void *unused)
  194 {
  195         int error;
  196         struct cdev *cdev;
  197 
  198         error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &cdev,
  199             &reroot_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0600, "reroot/reroot");
  200         if (error != 0) {
  201                 printf("%s: failed to create device node, error %d",
  202                     __func__, error);
  203         }
  204 }
  205 
  206 SYSINIT(reroot_conf, SI_SUB_DEVFS, SI_ORDER_ANY, reroot_conf, NULL);
  207 
  208 /*
  209  * The system call that results in a reboot.
  210  */
  211 /* ARGSUSED */
  212 int
  213 sys_reboot(struct thread *td, struct reboot_args *uap)
  214 {
  215         int error;
  216 
  217         error = 0;
  218 #ifdef MAC
  219         error = mac_system_check_reboot(td->td_ucred, uap->opt);
  220 #endif
  221         if (error == 0)
  222                 error = priv_check(td, PRIV_REBOOT);
  223         if (error == 0) {
  224                 if (uap->opt & RB_REROOT) {
  225                         error = kern_reroot();
  226                 } else {
  227                         mtx_lock(&Giant);
  228                         kern_reboot(uap->opt);
  229                         mtx_unlock(&Giant);
  230                 }
  231         }
  232         return (error);
  233 }
  234 
  235 /*
  236  * Called by events that want to shut down.. e.g  <CTL><ALT><DEL> on a PC
  237  */
  238 void
  239 shutdown_nice(int howto)
  240 {
  241 
  242         if (initproc != NULL) {
  243                 /* Send a signal to init(8) and have it shutdown the world. */
  244                 PROC_LOCK(initproc);
  245                 if (howto & RB_POWEROFF)
  246                         kern_psignal(initproc, SIGUSR2);
  247                 else if (howto & RB_HALT)
  248                         kern_psignal(initproc, SIGUSR1);
  249                 else
  250                         kern_psignal(initproc, SIGINT);
  251                 PROC_UNLOCK(initproc);
  252         } else {
  253                 /* No init(8) running, so simply reboot. */
  254                 kern_reboot(howto | RB_NOSYNC);
  255         }
  256 }
  257 
  258 static void
  259 print_uptime(void)
  260 {
  261         int f;
  262         struct timespec ts;
  263 
  264         getnanouptime(&ts);
  265         printf("Uptime: ");
  266         f = 0;
  267         if (ts.tv_sec >= 86400) {
  268                 printf("%ldd", (long)ts.tv_sec / 86400);
  269                 ts.tv_sec %= 86400;
  270                 f = 1;
  271         }
  272         if (f || ts.tv_sec >= 3600) {
  273                 printf("%ldh", (long)ts.tv_sec / 3600);
  274                 ts.tv_sec %= 3600;
  275                 f = 1;
  276         }
  277         if (f || ts.tv_sec >= 60) {
  278                 printf("%ldm", (long)ts.tv_sec / 60);
  279                 ts.tv_sec %= 60;
  280                 f = 1;
  281         }
  282         printf("%lds\n", (long)ts.tv_sec);
  283 }
  284 
  285 int
  286 doadump(boolean_t textdump)
  287 {
  288         boolean_t coredump;
  289         int error;
  290 
  291         error = 0;
  292         if (dumping)
  293                 return (EBUSY);
  294         if (dumper.dumper == NULL)
  295                 return (ENXIO);
  296 
  297         savectx(&dumppcb);
  298         dumptid = curthread->td_tid;
  299         dumping++;
  300 
  301         coredump = TRUE;
  302 #ifdef DDB
  303         if (textdump && textdump_pending) {
  304                 coredump = FALSE;
  305                 textdump_dumpsys(&dumper);
  306         }
  307 #endif
  308         if (coredump)
  309                 error = dumpsys(&dumper);
  310 
  311         dumping--;
  312         return (error);
  313 }
  314 
  315 /*
  316  * Shutdown the system cleanly to prepare for reboot, halt, or power off.
  317  */
  318 void
  319 kern_reboot(int howto)
  320 {
  321         static int once = 0;
  322 
  323 #if defined(SMP)
  324         /*
  325          * Bind us to CPU 0 so that all shutdown code runs there.  Some
  326          * systems don't shutdown properly (i.e., ACPI power off) if we
  327          * run on another processor.
  328          */
  329         if (!SCHEDULER_STOPPED()) {
  330                 thread_lock(curthread);
  331                 sched_bind(curthread, 0);
  332                 thread_unlock(curthread);
  333                 KASSERT(PCPU_GET(cpuid) == 0, ("boot: not running on cpu 0"));
  334         }
  335 #endif
  336         /* We're in the process of rebooting. */
  337         rebooting = 1;
  338 
  339         /* We are out of the debugger now. */
  340         kdb_active = 0;
  341 
  342         /*
  343          * Do any callouts that should be done BEFORE syncing the filesystems.
  344          */
  345         EVENTHANDLER_INVOKE(shutdown_pre_sync, howto);
  346 
  347         /* 
  348          * Now sync filesystems
  349          */
  350         if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) {
  351                 once = 1;
  352                 bufshutdown(show_busybufs);
  353         }
  354 
  355         print_uptime();
  356 
  357         cngrab();
  358 
  359         /*
  360          * Ok, now do things that assume all filesystem activity has
  361          * been completed.
  362          */
  363         EVENTHANDLER_INVOKE(shutdown_post_sync, howto);
  364 
  365         if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) 
  366                 doadump(TRUE);
  367 
  368         /* Now that we're going to really halt the system... */
  369         EVENTHANDLER_INVOKE(shutdown_final, howto);
  370 
  371         for(;;) ;       /* safety against shutdown_reset not working */
  372         /* NOTREACHED */
  373 }
  374 
  375 /*
  376  * The system call that results in changing the rootfs.
  377  */
  378 static int
  379 kern_reroot(void)
  380 {
  381         struct vnode *oldrootvnode, *vp;
  382         struct mount *mp, *devmp;
  383         int error;
  384 
  385         if (curproc != initproc)
  386                 return (EPERM);
  387 
  388         /*
  389          * Mark the filesystem containing currently-running executable
  390          * (the temporary copy of init(8)) busy.
  391          */
  392         vp = curproc->p_textvp;
  393         error = vn_lock(vp, LK_SHARED);
  394         if (error != 0)
  395                 return (error);
  396         mp = vp->v_mount;
  397         error = vfs_busy(mp, MBF_NOWAIT);
  398         if (error != 0) {
  399                 vfs_ref(mp);
  400                 VOP_UNLOCK(vp, 0);
  401                 error = vfs_busy(mp, 0);
  402                 vn_lock(vp, LK_SHARED | LK_RETRY);
  403                 vfs_rel(mp);
  404                 if (error != 0) {
  405                         VOP_UNLOCK(vp, 0);
  406                         return (ENOENT);
  407                 }
  408                 if (vp->v_iflag & VI_DOOMED) {
  409                         VOP_UNLOCK(vp, 0);
  410                         vfs_unbusy(mp);
  411                         return (ENOENT);
  412                 }
  413         }
  414         VOP_UNLOCK(vp, 0);
  415 
  416         /*
  417          * Remove the filesystem containing currently-running executable
  418          * from the mount list, to prevent it from being unmounted
  419          * by vfs_unmountall(), and to avoid confusing vfs_mountroot().
  420          *
  421          * Also preserve /dev - forcibly unmounting it could cause driver
  422          * reinitialization.
  423          */
  424 
  425         vfs_ref(rootdevmp);
  426         devmp = rootdevmp;
  427         rootdevmp = NULL;
  428 
  429         mtx_lock(&mountlist_mtx);
  430         TAILQ_REMOVE(&mountlist, mp, mnt_list);
  431         TAILQ_REMOVE(&mountlist, devmp, mnt_list);
  432         mtx_unlock(&mountlist_mtx);
  433 
  434         oldrootvnode = rootvnode;
  435 
  436         /*
  437          * Unmount everything except for the two filesystems preserved above.
  438          */
  439         vfs_unmountall();
  440 
  441         /*
  442          * Add /dev back; vfs_mountroot() will move it into its new place.
  443          */
  444         mtx_lock(&mountlist_mtx);
  445         TAILQ_INSERT_HEAD(&mountlist, devmp, mnt_list);
  446         mtx_unlock(&mountlist_mtx);
  447         rootdevmp = devmp;
  448         vfs_rel(rootdevmp);
  449 
  450         /*
  451          * Mount the new rootfs.
  452          */
  453         vfs_mountroot();
  454 
  455         /*
  456          * Update all references to the old rootvnode.
  457          */
  458         mountcheckdirs(oldrootvnode, rootvnode);
  459 
  460         /*
  461          * Add the temporary filesystem back and unbusy it.
  462          */
  463         mtx_lock(&mountlist_mtx);
  464         TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  465         mtx_unlock(&mountlist_mtx);
  466         vfs_unbusy(mp);
  467 
  468         return (0);
  469 }
  470 
  471 /*
  472  * If the shutdown was a clean halt, behave accordingly.
  473  */
  474 static void
  475 shutdown_halt(void *junk, int howto)
  476 {
  477 
  478         if (howto & RB_HALT) {
  479                 printf("\n");
  480                 printf("The operating system has halted.\n");
  481                 printf("Please press any key to reboot.\n\n");
  482                 switch (cngetc()) {
  483                 case -1:                /* No console, just die */
  484                         cpu_halt();
  485                         /* NOTREACHED */
  486                 default:
  487                         howto &= ~RB_HALT;
  488                         break;
  489                 }
  490         }
  491 }
  492 
  493 /*
  494  * Check to see if the system paniced, pause and then reboot
  495  * according to the specified delay.
  496  */
  497 static void
  498 shutdown_panic(void *junk, int howto)
  499 {
  500         int loop;
  501 
  502         if (howto & RB_DUMP) {
  503                 if (panic_reboot_wait_time != 0) {
  504                         if (panic_reboot_wait_time != -1) {
  505                                 printf("Automatic reboot in %d seconds - "
  506                                        "press a key on the console to abort\n",
  507                                         panic_reboot_wait_time);
  508                                 for (loop = panic_reboot_wait_time * 10;
  509                                      loop > 0; --loop) {
  510                                         DELAY(1000 * 100); /* 1/10th second */
  511                                         /* Did user type a key? */
  512                                         if (cncheckc() != -1)
  513                                                 break;
  514                                 }
  515                                 if (!loop)
  516                                         return;
  517                         }
  518                 } else { /* zero time specified - reboot NOW */
  519                         return;
  520                 }
  521                 printf("--> Press a key on the console to reboot,\n");
  522                 printf("--> or switch off the system now.\n");
  523                 cngetc();
  524         }
  525 }
  526 
  527 /*
  528  * Everything done, now reset
  529  */
  530 static void
  531 shutdown_reset(void *junk, int howto)
  532 {
  533 
  534         printf("Rebooting...\n");
  535         DELAY(1000000); /* wait 1 sec for printf's to complete and be read */
  536 
  537         /*
  538          * Acquiring smp_ipi_mtx here has a double effect:
  539          * - it disables interrupts avoiding CPU0 preemption
  540          *   by fast handlers (thus deadlocking  against other CPUs)
  541          * - it avoids deadlocks against smp_rendezvous() or, more 
  542          *   generally, threads busy-waiting, with this spinlock held,
  543          *   and waiting for responses by threads on other CPUs
  544          *   (ie. smp_tlb_shootdown()).
  545          *
  546          * For the !SMP case it just needs to handle the former problem.
  547          */
  548 #ifdef SMP
  549         mtx_lock_spin(&smp_ipi_mtx);
  550 #else
  551         spinlock_enter();
  552 #endif
  553 
  554         /* cpu_boot(howto); */ /* doesn't do anything at the moment */
  555         cpu_reset();
  556         /* NOTREACHED */ /* assuming reset worked */
  557 }
  558 
  559 #if defined(WITNESS) || defined(INVARIANT_SUPPORT)
  560 static int kassert_warn_only = 0;
  561 #ifdef KDB
  562 static int kassert_do_kdb = 0;
  563 #endif
  564 #ifdef KTR
  565 static int kassert_do_ktr = 0;
  566 #endif
  567 static int kassert_do_log = 1;
  568 static int kassert_log_pps_limit = 4;
  569 static int kassert_log_mute_at = 0;
  570 static int kassert_log_panic_at = 0;
  571 static int kassert_warnings = 0;
  572 
  573 SYSCTL_NODE(_debug, OID_AUTO, kassert, CTLFLAG_RW, NULL, "kassert options");
  574 
  575 SYSCTL_INT(_debug_kassert, OID_AUTO, warn_only, CTLFLAG_RWTUN,
  576     &kassert_warn_only, 0,
  577     "KASSERT triggers a panic (1) or just a warning (0)");
  578 
  579 #ifdef KDB
  580 SYSCTL_INT(_debug_kassert, OID_AUTO, do_kdb, CTLFLAG_RWTUN,
  581     &kassert_do_kdb, 0, "KASSERT will enter the debugger");
  582 #endif
  583 
  584 #ifdef KTR
  585 SYSCTL_UINT(_debug_kassert, OID_AUTO, do_ktr, CTLFLAG_RWTUN,
  586     &kassert_do_ktr, 0,
  587     "KASSERT does a KTR, set this to the KTRMASK you want");
  588 #endif
  589 
  590 SYSCTL_INT(_debug_kassert, OID_AUTO, do_log, CTLFLAG_RWTUN,
  591     &kassert_do_log, 0, "KASSERT triggers a panic (1) or just a warning (0)");
  592 
  593 SYSCTL_INT(_debug_kassert, OID_AUTO, warnings, CTLFLAG_RWTUN,
  594     &kassert_warnings, 0, "number of KASSERTs that have been triggered");
  595 
  596 SYSCTL_INT(_debug_kassert, OID_AUTO, log_panic_at, CTLFLAG_RWTUN,
  597     &kassert_log_panic_at, 0, "max number of KASSERTS before we will panic");
  598 
  599 SYSCTL_INT(_debug_kassert, OID_AUTO, log_pps_limit, CTLFLAG_RWTUN,
  600     &kassert_log_pps_limit, 0, "limit number of log messages per second");
  601 
  602 SYSCTL_INT(_debug_kassert, OID_AUTO, log_mute_at, CTLFLAG_RWTUN,
  603     &kassert_log_mute_at, 0, "max number of KASSERTS to log");
  604 
  605 static int kassert_sysctl_kassert(SYSCTL_HANDLER_ARGS);
  606 
  607 SYSCTL_PROC(_debug_kassert, OID_AUTO, kassert,
  608     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0,
  609     kassert_sysctl_kassert, "I", "set to trigger a test kassert");
  610 
  611 static int
  612 kassert_sysctl_kassert(SYSCTL_HANDLER_ARGS)
  613 {
  614         int error, i;
  615 
  616         error = sysctl_wire_old_buffer(req, sizeof(int));
  617         if (error == 0) {
  618                 i = 0;
  619                 error = sysctl_handle_int(oidp, &i, 0, req);
  620         }
  621         if (error != 0 || req->newptr == NULL)
  622                 return (error);
  623         KASSERT(0, ("kassert_sysctl_kassert triggered kassert %d", i));
  624         return (0);
  625 }
  626 
  627 /*
  628  * Called by KASSERT, this decides if we will panic
  629  * or if we will log via printf and/or ktr.
  630  */
  631 void
  632 kassert_panic(const char *fmt, ...)
  633 {
  634         static char buf[256];
  635         va_list ap;
  636 
  637         va_start(ap, fmt);
  638         (void)vsnprintf(buf, sizeof(buf), fmt, ap);
  639         va_end(ap);
  640 
  641         /*
  642          * panic if we're not just warning, or if we've exceeded
  643          * kassert_log_panic_at warnings.
  644          */
  645         if (!kassert_warn_only ||
  646             (kassert_log_panic_at > 0 &&
  647              kassert_warnings >= kassert_log_panic_at)) {
  648                 va_start(ap, fmt);
  649                 vpanic(fmt, ap);
  650                 /* NORETURN */
  651         }
  652 #ifdef KTR
  653         if (kassert_do_ktr)
  654                 CTR0(ktr_mask, buf);
  655 #endif /* KTR */
  656         /*
  657          * log if we've not yet met the mute limit.
  658          */
  659         if (kassert_do_log &&
  660             (kassert_log_mute_at == 0 ||
  661              kassert_warnings < kassert_log_mute_at)) {
  662                 static  struct timeval lasterr;
  663                 static  int curerr;
  664 
  665                 if (ppsratecheck(&lasterr, &curerr, kassert_log_pps_limit)) {
  666                         printf("KASSERT failed: %s\n", buf);
  667                         kdb_backtrace();
  668                 }
  669         }
  670 #ifdef KDB
  671         if (kassert_do_kdb) {
  672                 kdb_enter(KDB_WHY_KASSERT, buf);
  673         }
  674 #endif
  675         atomic_add_int(&kassert_warnings, 1);
  676 }
  677 #endif
  678 
  679 /*
  680  * Panic is called on unresolvable fatal errors.  It prints "panic: mesg",
  681  * and then reboots.  If we are called twice, then we avoid trying to sync
  682  * the disks as this often leads to recursive panics.
  683  */
  684 void
  685 panic(const char *fmt, ...)
  686 {
  687         va_list ap;
  688 
  689         va_start(ap, fmt);
  690         vpanic(fmt, ap);
  691 }
  692 
  693 void
  694 vpanic(const char *fmt, va_list ap)
  695 {
  696 #ifdef SMP
  697         cpuset_t other_cpus;
  698 #endif
  699         struct thread *td = curthread;
  700         int bootopt, newpanic;
  701         static char buf[256];
  702 
  703         spinlock_enter();
  704 
  705 #ifdef SMP
  706         /*
  707          * stop_cpus_hard(other_cpus) should prevent multiple CPUs from
  708          * concurrently entering panic.  Only the winner will proceed
  709          * further.
  710          */
  711         if (panicstr == NULL && !kdb_active) {
  712                 other_cpus = all_cpus;
  713                 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
  714                 stop_cpus_hard(other_cpus);
  715         }
  716 #endif
  717 
  718         /*
  719          * Ensure that the scheduler is stopped while panicking, even if panic
  720          * has been entered from kdb.
  721          */
  722         td->td_stopsched = 1;
  723 
  724         bootopt = RB_AUTOBOOT;
  725         newpanic = 0;
  726         if (panicstr)
  727                 bootopt |= RB_NOSYNC;
  728         else {
  729                 bootopt |= RB_DUMP;
  730                 panicstr = fmt;
  731                 newpanic = 1;
  732         }
  733 
  734         if (newpanic) {
  735                 (void)vsnprintf(buf, sizeof(buf), fmt, ap);
  736                 panicstr = buf;
  737                 cngrab();
  738                 printf("panic: %s\n", buf);
  739         } else {
  740                 printf("panic: ");
  741                 vprintf(fmt, ap);
  742                 printf("\n");
  743         }
  744 #ifdef SMP
  745         printf("cpuid = %d\n", PCPU_GET(cpuid));
  746 #endif
  747 
  748 #ifdef KDB
  749         if (newpanic && trace_on_panic)
  750                 kdb_backtrace();
  751         if (debugger_on_panic)
  752                 kdb_enter(KDB_WHY_PANIC, "panic");
  753 #endif
  754         /*thread_lock(td); */
  755         td->td_flags |= TDF_INPANIC;
  756         /* thread_unlock(td); */
  757         if (!sync_on_panic)
  758                 bootopt |= RB_NOSYNC;
  759         kern_reboot(bootopt);
  760 }
  761 
  762 /*
  763  * Support for poweroff delay.
  764  *
  765  * Please note that setting this delay too short might power off your machine
  766  * before the write cache on your hard disk has been flushed, leading to
  767  * soft-updates inconsistencies.
  768  */
  769 #ifndef POWEROFF_DELAY
  770 # define POWEROFF_DELAY 5000
  771 #endif
  772 static int poweroff_delay = POWEROFF_DELAY;
  773 
  774 SYSCTL_INT(_kern_shutdown, OID_AUTO, poweroff_delay, CTLFLAG_RW,
  775     &poweroff_delay, 0, "Delay before poweroff to write disk caches (msec)");
  776 
  777 static void
  778 poweroff_wait(void *junk, int howto)
  779 {
  780 
  781         if (!(howto & RB_POWEROFF) || poweroff_delay <= 0)
  782                 return;
  783         DELAY(poweroff_delay * 1000);
  784 }
  785 
  786 /*
  787  * Some system processes (e.g. syncer) need to be stopped at appropriate
  788  * points in their main loops prior to a system shutdown, so that they
  789  * won't interfere with the shutdown process (e.g. by holding a disk buf
  790  * to cause sync to fail).  For each of these system processes, register
  791  * shutdown_kproc() as a handler for one of shutdown events.
  792  */
  793 static int kproc_shutdown_wait = 60;
  794 SYSCTL_INT(_kern_shutdown, OID_AUTO, kproc_shutdown_wait, CTLFLAG_RW,
  795     &kproc_shutdown_wait, 0, "Max wait time (sec) to stop for each process");
  796 
  797 void
  798 kproc_shutdown(void *arg, int howto)
  799 {
  800         struct proc *p;
  801         int error;
  802 
  803         if (panicstr)
  804                 return;
  805 
  806         p = (struct proc *)arg;
  807         printf("Waiting (max %d seconds) for system process `%s' to stop... ",
  808             kproc_shutdown_wait, p->p_comm);
  809         error = kproc_suspend(p, kproc_shutdown_wait * hz);
  810 
  811         if (error == EWOULDBLOCK)
  812                 printf("timed out\n");
  813         else
  814                 printf("done\n");
  815 }
  816 
  817 void
  818 kthread_shutdown(void *arg, int howto)
  819 {
  820         struct thread *td;
  821         int error;
  822 
  823         if (panicstr)
  824                 return;
  825 
  826         td = (struct thread *)arg;
  827         printf("Waiting (max %d seconds) for system thread `%s' to stop... ",
  828             kproc_shutdown_wait, td->td_name);
  829         error = kthread_suspend(td, kproc_shutdown_wait * hz);
  830 
  831         if (error == EWOULDBLOCK)
  832                 printf("timed out\n");
  833         else
  834                 printf("done\n");
  835 }
  836 
  837 static char dumpdevname[sizeof(((struct cdev*)NULL)->si_name)];
  838 SYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD,
  839     dumpdevname, 0, "Device for kernel dumps");
  840 
  841 /* Registration of dumpers */
  842 int
  843 set_dumper(struct dumperinfo *di, const char *devname, struct thread *td)
  844 {
  845         size_t wantcopy;
  846         int error;
  847 
  848         error = priv_check(td, PRIV_SETDUMPER);
  849         if (error != 0)
  850                 return (error);
  851 
  852         if (di == NULL) {
  853                 if (dumper.blockbuf != NULL)
  854                         free(dumper.blockbuf, M_DUMPER);
  855                 bzero(&dumper, sizeof(dumper));
  856                 dumpdevname[0] = '\0';
  857                 return (0);
  858         }
  859         if (dumper.dumper != NULL)
  860                 return (EBUSY);
  861         dumper = *di;
  862         wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname));
  863         if (wantcopy >= sizeof(dumpdevname)) {
  864                 printf("set_dumper: device name truncated from '%s' -> '%s'\n",
  865                         devname, dumpdevname);
  866         }
  867         dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
  868         return (0);
  869 }
  870 
  871 /* Call dumper with bounds checking. */
  872 int
  873 dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
  874     off_t offset, size_t length)
  875 {
  876 
  877         if (length != 0 && (offset < di->mediaoffset ||
  878             offset - di->mediaoffset + length > di->mediasize)) {
  879                 printf("Attempt to write outside dump device boundaries.\n"
  880             "offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n",
  881                     (intmax_t)offset, (intmax_t)di->mediaoffset,
  882                     (uintmax_t)length, (intmax_t)di->mediasize);
  883                 return (ENOSPC);
  884         }
  885         return (di->dumper(di->priv, virtual, physical, offset, length));
  886 }
  887 
  888 /* Call dumper with bounds checking. */
  889 int
  890 dump_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical,
  891     off_t offset, size_t length, size_t *size)
  892 {
  893         char *temp;
  894         int ret;
  895 
  896         if (length > di->blocksize)
  897                 return (ENOMEM);
  898 
  899         *size = di->blocksize;
  900         if (length == di->blocksize)
  901                 temp = virtual;
  902         else {
  903                 temp = di->blockbuf;
  904                 memset(temp + length, 0, di->blocksize - length);
  905                 memcpy(temp, virtual, length);
  906         }
  907         ret = dump_write(di, temp, physical, offset, *size);
  908 
  909         return (ret);
  910 }
  911 
  912 
  913 void
  914 mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
  915     uint64_t dumplen, uint32_t blksz)
  916 {
  917 
  918         bzero(kdh, sizeof(*kdh));
  919         strlcpy(kdh->magic, magic, sizeof(kdh->magic));
  920         strlcpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture));
  921         kdh->version = htod32(KERNELDUMPVERSION);
  922         kdh->architectureversion = htod32(archver);
  923         kdh->dumplength = htod64(dumplen);
  924         kdh->dumptime = htod64(time_second);
  925         kdh->blocksize = htod32(blksz);
  926         strlcpy(kdh->hostname, prison0.pr_hostname, sizeof(kdh->hostname));
  927         strlcpy(kdh->versionstring, version, sizeof(kdh->versionstring));
  928         if (panicstr != NULL)
  929                 strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring));
  930         kdh->parity = kerneldump_parity(kdh);
  931 }
  932 
  933 #ifdef DDB
  934 DB_SHOW_COMMAND(panic, db_show_panic)
  935 {
  936 
  937         if (panicstr == NULL)
  938                 db_printf("panicstr not set\n");
  939         else
  940                 db_printf("panic: %s\n", panicstr);
  941 }
  942 #endif

Cache object: 08e118642a1b8102e1e35318891c0276


[ 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.