kern_shutdown.c revision 283115
117658Sjulian/*- 217658Sjulian * Copyright (c) 1986, 1988, 1991, 1993 317658Sjulian * The Regents of the University of California. All rights reserved. 417658Sjulian * (c) UNIX System Laboratories, Inc. 517658Sjulian * All or some portions of this file are derived from material licensed 617658Sjulian * to the University of California by American Telephone and Telegraph 717658Sjulian * Co. or Unix System Laboratories, Inc. and are reproduced herein with 817658Sjulian * the permission of UNIX System Laboratories, Inc. 917658Sjulian * 1017658Sjulian * Redistribution and use in source and binary forms, with or without 1117658Sjulian * modification, are permitted provided that the following conditions 1217658Sjulian * are met: 1317658Sjulian * 1. Redistributions of source code must retain the above copyright 1417658Sjulian * notice, this list of conditions and the following disclaimer. 1517658Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1617658Sjulian * notice, this list of conditions and the following disclaimer in the 1717658Sjulian * documentation and/or other materials provided with the distribution. 1817658Sjulian * 4. Neither the name of the University nor the names of its contributors 1917658Sjulian * may be used to endorse or promote products derived from this software 2017658Sjulian * without specific prior written permission. 2117658Sjulian * 2217658Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2317658Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2417658Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2517658Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2617658Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2717658Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2817658Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2917658Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3017658Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3117658Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3217658Sjulian * SUCH DAMAGE. 3317658Sjulian * 3417658Sjulian * @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94 3517658Sjulian */ 3617658Sjulian 37116182Sobrien#include <sys/cdefs.h> 38116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_shutdown.c 283115 2015-05-19 16:23:47Z asomers $"); 39116182Sobrien 40174921Srwatson#include "opt_ddb.h" 41131927Smarcel#include "opt_kdb.h" 4228976Sbde#include "opt_panic.h" 43134649Sscottl#include "opt_sched.h" 44221173Sattilio#include "opt_watchdog.h" 4517658Sjulian 4617658Sjulian#include <sys/param.h> 4717658Sjulian#include <sys/systm.h> 4860041Sphk#include <sys/bio.h> 4931275Sbde#include <sys/buf.h> 5078767Sjhb#include <sys/conf.h> 5178767Sjhb#include <sys/cons.h> 5278767Sjhb#include <sys/eventhandler.h> 53193066Sjamie#include <sys/jail.h> 54131927Smarcel#include <sys/kdb.h> 5517658Sjulian#include <sys/kernel.h> 56183527Speter#include <sys/kerneldump.h> 5755539Sluoqi#include <sys/kthread.h> 58243980Salfred#include <sys/ktr.h> 5989601Ssobomax#include <sys/malloc.h> 6021776Sbde#include <sys/mount.h> 61164033Srwatson#include <sys/priv.h> 6278767Sjhb#include <sys/proc.h> 6378767Sjhb#include <sys/reboot.h> 6478767Sjhb#include <sys/resourcevar.h> 65248084Sattilio#include <sys/rwlock.h> 66137263Speter#include <sys/sched.h> 67206878Sattilio#include <sys/smp.h> 6817658Sjulian#include <sys/sysctl.h> 6917658Sjulian#include <sys/sysproto.h> 70225448Sattilio#include <sys/vnode.h> 71221173Sattilio#include <sys/watchdog.h> 7217658Sjulian 73174921Srwatson#include <ddb/ddb.h> 74174921Srwatson 75118990Smarcel#include <machine/cpu.h> 76276772Smarkj#include <machine/dump.h> 7794169Sphk#include <machine/pcb.h> 7891778Sjake#include <machine/smp.h> 7917658Sjulian 80163606Srwatson#include <security/mac/mac_framework.h> 81163606Srwatson 82157628Spjd#include <vm/vm.h> 83157628Spjd#include <vm/vm_object.h> 84157628Spjd#include <vm/vm_page.h> 85157628Spjd#include <vm/vm_pager.h> 86157628Spjd#include <vm/swap_pager.h> 87157628Spjd 8817658Sjulian#include <sys/signalvar.h> 8917658Sjulian 9017658Sjulian#ifndef PANIC_REBOOT_WAIT_TIME 9117658Sjulian#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ 9217658Sjulian#endif 93258956Scpercivastatic int panic_reboot_wait_time = PANIC_REBOOT_WAIT_TIME; 94267992ShselaskySYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN, 95258893Scperciva &panic_reboot_wait_time, 0, 96258893Scperciva "Seconds to wait before rebooting after a panic"); 9717658Sjulian 9817658Sjulian/* 9917658Sjulian * Note that stdarg.h and the ANSI style va_start macro is used for both 10017658Sjulian * ANSI and traditional C compilers. 10117658Sjulian */ 10217658Sjulian#include <machine/stdarg.h> 10317658Sjulian 104131927Smarcel#ifdef KDB 105131927Smarcel#ifdef KDB_UNATTENDED 10642135Smsmithint debugger_on_panic = 0; 10717658Sjulian#else 10842135Smsmithint debugger_on_panic = 1; 10917658Sjulian#endif 110228475SobrienSYSCTL_INT(_debug, OID_AUTO, debugger_on_panic, 111267992Shselasky CTLFLAG_RWTUN | CTLFLAG_SECURE, 112228487Sobrien &debugger_on_panic, 0, "Run debugger on kernel panic"); 113103647Sjhb 114131927Smarcel#ifdef KDB_TRACE 115213322Savgstatic int trace_on_panic = 1; 116103647Sjhb#else 117213322Savgstatic int trace_on_panic = 0; 11817658Sjulian#endif 119228475SobrienSYSCTL_INT(_debug, OID_AUTO, trace_on_panic, 120267992Shselasky CTLFLAG_RWTUN | CTLFLAG_SECURE, 121228487Sobrien &trace_on_panic, 0, "Print stack trace on kernel panic"); 122131927Smarcel#endif /* KDB */ 12317658Sjulian 124213322Savgstatic int sync_on_panic = 0; 125267992ShselaskySYSCTL_INT(_kern, OID_AUTO, sync_on_panic, CTLFLAG_RWTUN, 12685202Speter &sync_on_panic, 0, "Do a sync before rebooting from a panic"); 12785202Speter 128227309Sedstatic SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW, 0, 129227309Sed "Shutdown environment"); 13043436Smsmith 131225448Sattilio#ifndef DIAGNOSTIC 132225448Sattiliostatic int show_busybufs; 133225448Sattilio#else 134225448Sattiliostatic int show_busybufs = 1; 135225448Sattilio#endif 136225448SattilioSYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW, 137225448Sattilio &show_busybufs, 0, ""); 138225448Sattilio 13917658Sjulian/* 14017658Sjulian * Variable panicstr contains argument to first call to panic; used as flag 14117658Sjulian * to indicate that the kernel has already called panic. 14217658Sjulian */ 14317658Sjulianconst char *panicstr; 14417658Sjulian 14593496Sphkint dumping; /* system is dumping */ 146155383Sjeffint rebooting; /* system is rebooting */ 14793496Sphkstatic struct dumperinfo dumper; /* our selected dumper */ 14867093Sps 149131927Smarcel/* Context information for dump-debuggers. */ 150131927Smarcelstatic struct pcb dumppcb; /* Registers. */ 151235777Shartilwpid_t dumptid; /* Thread ID. */ 152131927Smarcel 15365395Speterstatic void poweroff_wait(void *, int); 15465395Speterstatic void shutdown_halt(void *junk, int howto); 15565395Speterstatic void shutdown_panic(void *junk, int howto); 15665395Speterstatic void shutdown_reset(void *junk, int howto); 15717658Sjulian 15850107Smsmith/* register various local shutdown events */ 159110859Salfredstatic void 16050107Smsmithshutdown_conf(void *unused) 16150107Smsmith{ 162110859Salfred 163110859Salfred EVENTHANDLER_REGISTER(shutdown_final, poweroff_wait, NULL, 164214279Sbrucec SHUTDOWN_PRI_FIRST); 165110859Salfred EVENTHANDLER_REGISTER(shutdown_final, shutdown_halt, NULL, 166110859Salfred SHUTDOWN_PRI_LAST + 100); 167110859Salfred EVENTHANDLER_REGISTER(shutdown_final, shutdown_panic, NULL, 168110859Salfred SHUTDOWN_PRI_LAST + 100); 169110859Salfred EVENTHANDLER_REGISTER(shutdown_final, shutdown_reset, NULL, 170110859Salfred SHUTDOWN_PRI_LAST + 200); 17150107Smsmith} 17248868Sphk 173177253SrwatsonSYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL); 17450107Smsmith 17517658Sjulian/* 176167211Srwatson * The system call that results in a reboot. 17717658Sjulian */ 17882749Sdillon/* ARGSUSED */ 17917658Sjulianint 180225617Skmacysys_reboot(struct thread *td, struct reboot_args *uap) 18117658Sjulian{ 18217658Sjulian int error; 18317658Sjulian 184106024Srwatson error = 0; 185106024Srwatson#ifdef MAC 186172930Srwatson error = mac_system_check_reboot(td->td_ucred, uap->opt); 187106024Srwatson#endif 188106024Srwatson if (error == 0) 189164033Srwatson error = priv_check(td, PRIV_REBOOT); 190106024Srwatson if (error == 0) { 191106024Srwatson mtx_lock(&Giant); 192214004Smarcel kern_reboot(uap->opt); 193106024Srwatson mtx_unlock(&Giant); 194106024Srwatson } 19582749Sdillon return (error); 19617658Sjulian} 19717658Sjulian 19817658Sjulian/* 19917658Sjulian * Called by events that want to shut down.. e.g <CTL><ALT><DEL> on a PC 20017658Sjulian */ 20117658Sjulianvoid 20265268Smsmithshutdown_nice(int howto) 20317658Sjulian{ 204110859Salfred 20517658Sjulian if (initproc != NULL) { 206264237Sed /* Send a signal to init(8) and have it shutdown the world. */ 20773913Sjhb PROC_LOCK(initproc); 208264237Sed if (howto & RB_POWEROFF) 209264237Sed kern_psignal(initproc, SIGUSR2); 210264237Sed else if (howto & RB_HALT) 211264237Sed kern_psignal(initproc, SIGUSR1); 212264237Sed else 213264237Sed kern_psignal(initproc, SIGINT); 21473913Sjhb PROC_UNLOCK(initproc); 21517658Sjulian } else { 216264237Sed /* No init(8) running, so simply reboot. */ 217264240Sed kern_reboot(howto | RB_NOSYNC); 21817658Sjulian } 21917658Sjulian} 22017658Sjulian 22154233Sphkstatic void 22265395Speterprint_uptime(void) 22354233Sphk{ 22454233Sphk int f; 22554233Sphk struct timespec ts; 22654233Sphk 22754233Sphk getnanouptime(&ts); 22854233Sphk printf("Uptime: "); 22954233Sphk f = 0; 23054233Sphk if (ts.tv_sec >= 86400) { 23165764Sjhb printf("%ldd", (long)ts.tv_sec / 86400); 23254233Sphk ts.tv_sec %= 86400; 23354233Sphk f = 1; 23454233Sphk } 23554233Sphk if (f || ts.tv_sec >= 3600) { 23665764Sjhb printf("%ldh", (long)ts.tv_sec / 3600); 23754233Sphk ts.tv_sec %= 3600; 23854233Sphk f = 1; 23954233Sphk } 24054233Sphk if (f || ts.tv_sec >= 60) { 24165764Sjhb printf("%ldm", (long)ts.tv_sec / 60); 24254233Sphk ts.tv_sec %= 60; 24354233Sphk f = 1; 24454233Sphk } 24565764Sjhb printf("%lds\n", (long)ts.tv_sec); 24654233Sphk} 24754233Sphk 248222801Smarcelint 249222801Smarceldoadump(boolean_t textdump) 25094169Sphk{ 251222801Smarcel boolean_t coredump; 252269105Sgavin int error; 253110859Salfred 254269105Sgavin error = 0; 255222801Smarcel if (dumping) 256222801Smarcel return (EBUSY); 257222801Smarcel if (dumper.dumper == NULL) 258222801Smarcel return (ENXIO); 259132412Sjulian 26094169Sphk savectx(&dumppcb); 261131927Smarcel dumptid = curthread->td_tid; 26294169Sphk dumping++; 263222801Smarcel 264222801Smarcel coredump = TRUE; 265174921Srwatson#ifdef DDB 266222801Smarcel if (textdump && textdump_pending) { 267222801Smarcel coredump = FALSE; 268174921Srwatson textdump_dumpsys(&dumper); 269222801Smarcel } 270174921Srwatson#endif 271222801Smarcel if (coredump) 272269105Sgavin error = dumpsys(&dumper); 273222801Smarcel 274176788Sru dumping--; 275269105Sgavin return (error); 27694169Sphk} 27794169Sphk 278149875Struckmanstatic int 279149875Struckmanisbufbusy(struct buf *bp) 280149875Struckman{ 281149875Struckman if (((bp->b_flags & (B_INVAL | B_PERSISTENT)) == 0 && 282175486Sattilio BUF_ISLOCKED(bp)) || 283149875Struckman ((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI)) 284149875Struckman return (1); 285149875Struckman return (0); 286149875Struckman} 287149875Struckman 28817658Sjulian/* 289137329Snjl * Shutdown the system cleanly to prepare for reboot, halt, or power off. 29017658Sjulian */ 291214004Smarcelvoid 292214004Smarcelkern_reboot(int howto) 29317658Sjulian{ 294133763Struckman static int first_buf_printf = 1; 295264237Sed static int waittime = -1; 29617658Sjulian 297137375Smarcel#if defined(SMP) 298137329Snjl /* 299137329Snjl * Bind us to CPU 0 so that all shutdown code runs there. Some 300137329Snjl * systems don't shutdown properly (i.e., ACPI power off) if we 301137329Snjl * run on another processor. 302137329Snjl */ 303228424Savg if (!SCHEDULER_STOPPED()) { 304228424Savg thread_lock(curthread); 305228424Savg sched_bind(curthread, 0); 306228424Savg thread_unlock(curthread); 307228424Savg KASSERT(PCPU_GET(cpuid) == 0, ("boot: not running on cpu 0")); 308228424Savg } 309137263Speter#endif 310155383Sjeff /* We're in the process of rebooting. */ 311155383Sjeff rebooting = 1; 312137263Speter 31382119Sjhb /* We are out of the debugger now. */ 314131927Smarcel kdb_active = 0; 31582119Sjhb 31627997Sjulian /* 31727997Sjulian * Do any callouts that should be done BEFORE syncing the filesystems. 31827997Sjulian */ 31950107Smsmith EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); 32027997Sjulian 32127997Sjulian /* 32227997Sjulian * Now sync filesystems 32327997Sjulian */ 32417658Sjulian if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) { 32517658Sjulian register struct buf *bp; 32665707Sjasone int iter, nbusy, pbusy; 327131481Sjhb#ifndef PREEMPTION 32865707Sjasone int subiter; 329131481Sjhb#endif 33017658Sjulian 33117658Sjulian waittime = 0; 33217658Sjulian 333221173Sattilio wdog_kern_pat(WD_LASTVAL); 334225617Skmacy sys_sync(curthread, NULL); 33517658Sjulian 33634266Sjulian /* 33734266Sjulian * With soft updates, some buffers that are 33834266Sjulian * written will be remarked as dirty until other 33934266Sjulian * buffers are written. 34034266Sjulian */ 34165707Sjasone for (iter = pbusy = 0; iter < 20; iter++) { 34217658Sjulian nbusy = 0; 343149875Struckman for (bp = &buf[nbuf]; --bp >= buf; ) 344149875Struckman if (isbufbusy(bp)) 34517658Sjulian nbusy++; 346133763Struckman if (nbusy == 0) { 347133763Struckman if (first_buf_printf) 348136115Sphk printf("All buffers synced."); 34917658Sjulian break; 350133763Struckman } 351133763Struckman if (first_buf_printf) { 352133763Struckman printf("Syncing disks, buffers remaining... "); 353133763Struckman first_buf_printf = 0; 354133763Struckman } 35517658Sjulian printf("%d ", nbusy); 35665707Sjasone if (nbusy < pbusy) 35765707Sjasone iter = 0; 35865707Sjasone pbusy = nbusy; 359236503Savg 360221173Sattilio wdog_kern_pat(WD_LASTVAL); 361225617Skmacy sys_sync(curthread, NULL); 362131481Sjhb 363131481Sjhb#ifdef PREEMPTION 364131481Sjhb /* 365131481Sjhb * Drop Giant and spin for a while to allow 366131481Sjhb * interrupt threads to run. 367131481Sjhb */ 368131481Sjhb DROP_GIANT(); 36934266Sjulian DELAY(50000 * iter); 370131481Sjhb PICKUP_GIANT(); 371131481Sjhb#else 372131481Sjhb /* 373131481Sjhb * Drop Giant and context switch several times to 374131481Sjhb * allow interrupt threads to run. 375131481Sjhb */ 376131481Sjhb DROP_GIANT(); 377131481Sjhb for (subiter = 0; subiter < 50 * iter; subiter++) { 378170307Sjeff thread_lock(curthread); 379131481Sjhb mi_switch(SW_VOL, NULL); 380170307Sjeff thread_unlock(curthread); 381131481Sjhb DELAY(1000); 382131481Sjhb } 383131481Sjhb PICKUP_GIANT(); 384131481Sjhb#endif 38517658Sjulian } 386133418Snjl printf("\n"); 38741137Smsmith /* 38841137Smsmith * Count only busy local buffers to prevent forcing 38941137Smsmith * a fsck if we're just a client of a wedged NFS server 39041137Smsmith */ 39141137Smsmith nbusy = 0; 39241137Smsmith for (bp = &buf[nbuf]; --bp >= buf; ) { 393149875Struckman if (isbufbusy(bp)) { 394137186Sphk#if 0 395137186Sphk/* XXX: This is bogus. We should probably have a BO_REMOTE flag instead */ 396130640Sphk if (bp->b_dev == NULL) { 39753452Sphk TAILQ_REMOVE(&mountlist, 39848225Smckusick bp->b_vp->v_mount, mnt_list); 39953023Sphk continue; 40053023Sphk } 401137186Sphk#endif 40253023Sphk nbusy++; 403225448Sattilio if (show_busybufs > 0) { 404225448Sattilio printf( 405225448Sattilio "%d: buf:%p, vnode:%p, flags:%0x, blkno:%jd, lblkno:%jd, buflock:", 406225448Sattilio nbusy, bp, bp->b_vp, bp->b_flags, 407225448Sattilio (intmax_t)bp->b_blkno, 408225448Sattilio (intmax_t)bp->b_lblkno); 409225448Sattilio BUF_LOCKPRINTINFO(bp); 410225448Sattilio if (show_busybufs > 1) 411225448Sattilio vn_printf(bp->b_vp, 412225448Sattilio "vnode content: "); 413225448Sattilio } 41446568Speter } 41541137Smsmith } 41617658Sjulian if (nbusy) { 41717658Sjulian /* 41817658Sjulian * Failed to sync all blocks. Indicate this and don't 41917658Sjulian * unmount filesystems (thus forcing an fsck on reboot). 42017658Sjulian */ 421133763Struckman printf("Giving up on %d buffers\n", nbusy); 42217658Sjulian DELAY(5000000); /* 5 seconds */ 42317658Sjulian } else { 424133763Struckman if (!first_buf_printf) 425133763Struckman printf("Final sync complete\n"); 42617658Sjulian /* 42717658Sjulian * Unmount filesystems 42817658Sjulian */ 42917658Sjulian if (panicstr == 0) 43017658Sjulian vfs_unmountall(); 43117658Sjulian } 432157628Spjd swapoff_all(); 43339237Sgibbs DELAY(100000); /* wait for console output to finish */ 43417658Sjulian } 43527997Sjulian 43654233Sphk print_uptime(); 43754233Sphk 438228632Savg cngrab(); 439228632Savg 44027997Sjulian /* 44127997Sjulian * Ok, now do things that assume all filesystem activity has 44227997Sjulian * been completed. 44327997Sjulian */ 44450107Smsmith EVENTHANDLER_INVOKE(shutdown_post_sync, howto); 445137329Snjl 446132412Sjulian if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) 447222801Smarcel doadump(TRUE); 44839237Sgibbs 44939237Sgibbs /* Now that we're going to really halt the system... */ 45050107Smsmith EVENTHANDLER_INVOKE(shutdown_final, howto); 45139237Sgibbs 45250107Smsmith for(;;) ; /* safety against shutdown_reset not working */ 45350107Smsmith /* NOTREACHED */ 45450107Smsmith} 45550107Smsmith 45650107Smsmith/* 45750107Smsmith * If the shutdown was a clean halt, behave accordingly. 45850107Smsmith */ 45950107Smsmithstatic void 46050107Smsmithshutdown_halt(void *junk, int howto) 46150107Smsmith{ 462110859Salfred 46317658Sjulian if (howto & RB_HALT) { 46417658Sjulian printf("\n"); 46517658Sjulian printf("The operating system has halted.\n"); 46617658Sjulian printf("Please press any key to reboot.\n\n"); 46719274Sjulian switch (cngetc()) { 46819274Sjulian case -1: /* No console, just die */ 46919274Sjulian cpu_halt(); 47019274Sjulian /* NOTREACHED */ 47119274Sjulian default: 47239237Sgibbs howto &= ~RB_HALT; 47319274Sjulian break; 47419274Sjulian } 47550107Smsmith } 47650107Smsmith} 47717658Sjulian 47850107Smsmith/* 47950107Smsmith * Check to see if the system paniced, pause and then reboot 48050107Smsmith * according to the specified delay. 48150107Smsmith */ 48250107Smsmithstatic void 48350107Smsmithshutdown_panic(void *junk, int howto) 48450107Smsmith{ 48550107Smsmith int loop; 48650107Smsmith 48750107Smsmith if (howto & RB_DUMP) { 488258893Scperciva if (panic_reboot_wait_time != 0) { 489258893Scperciva if (panic_reboot_wait_time != -1) { 49039237Sgibbs printf("Automatic reboot in %d seconds - " 49139237Sgibbs "press a key on the console to abort\n", 492258893Scperciva panic_reboot_wait_time); 493258893Scperciva for (loop = panic_reboot_wait_time * 10; 49439237Sgibbs loop > 0; --loop) { 49539237Sgibbs DELAY(1000 * 100); /* 1/10th second */ 49639237Sgibbs /* Did user type a key? */ 49739237Sgibbs if (cncheckc() != -1) 49839237Sgibbs break; 49917658Sjulian } 50039237Sgibbs if (!loop) 50150107Smsmith return; 50217658Sjulian } 50339237Sgibbs } else { /* zero time specified - reboot NOW */ 50450107Smsmith return; 50517658Sjulian } 50689522Snik printf("--> Press a key on the console to reboot,\n"); 50789522Snik printf("--> or switch off the system now.\n"); 50839237Sgibbs cngetc(); 50917658Sjulian } 51050107Smsmith} 51150107Smsmith 51250107Smsmith/* 51350107Smsmith * Everything done, now reset 51450107Smsmith */ 51550107Smsmithstatic void 51650107Smsmithshutdown_reset(void *junk, int howto) 51750107Smsmith{ 518110859Salfred 519206878Sattilio printf("Rebooting...\n"); 520206878Sattilio DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 521206878Sattilio 522196196Sattilio /* 523206878Sattilio * Acquiring smp_ipi_mtx here has a double effect: 524206878Sattilio * - it disables interrupts avoiding CPU0 preemption 525206878Sattilio * by fast handlers (thus deadlocking against other CPUs) 526206878Sattilio * - it avoids deadlocks against smp_rendezvous() or, more 527206878Sattilio * generally, threads busy-waiting, with this spinlock held, 528206878Sattilio * and waiting for responses by threads on other CPUs 529206878Sattilio * (ie. smp_tlb_shootdown()). 530206897Sattilio * 531206897Sattilio * For the !SMP case it just needs to handle the former problem. 532196196Sattilio */ 533206897Sattilio#ifdef SMP 534206878Sattilio mtx_lock_spin(&smp_ipi_mtx); 535206897Sattilio#else 536206897Sattilio spinlock_enter(); 537206897Sattilio#endif 538196196Sattilio 53917677Sjulian /* cpu_boot(howto); */ /* doesn't do anything at the moment */ 54017658Sjulian cpu_reset(); 54150107Smsmith /* NOTREACHED */ /* assuming reset worked */ 54217658Sjulian} 54317658Sjulian 544244105Salfred#if defined(WITNESS) || defined(INVARIANTS) 545243980Salfredstatic int kassert_warn_only = 0; 546244099Salfred#ifdef KDB 547244099Salfredstatic int kassert_do_kdb = 0; 548244099Salfred#endif 549243980Salfred#ifdef KTR 550243980Salfredstatic int kassert_do_ktr = 0; 551243980Salfred#endif 552243980Salfredstatic int kassert_do_log = 1; 553243980Salfredstatic int kassert_log_pps_limit = 4; 554243980Salfredstatic int kassert_log_mute_at = 0; 555243980Salfredstatic int kassert_log_panic_at = 0; 556243980Salfredstatic int kassert_warnings = 0; 557243980Salfred 558243980SalfredSYSCTL_NODE(_debug, OID_AUTO, kassert, CTLFLAG_RW, NULL, "kassert options"); 559243980Salfred 560267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, warn_only, CTLFLAG_RWTUN, 561243980Salfred &kassert_warn_only, 0, 562243980Salfred "KASSERT triggers a panic (1) or just a warning (0)"); 563243980Salfred 564244099Salfred#ifdef KDB 565267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, do_kdb, CTLFLAG_RWTUN, 566244099Salfred &kassert_do_kdb, 0, "KASSERT will enter the debugger"); 567244099Salfred#endif 568244099Salfred 569243980Salfred#ifdef KTR 570267992ShselaskySYSCTL_UINT(_debug_kassert, OID_AUTO, do_ktr, CTLFLAG_RWTUN, 571243980Salfred &kassert_do_ktr, 0, 572243980Salfred "KASSERT does a KTR, set this to the KTRMASK you want"); 573243980Salfred#endif 574243980Salfred 575267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, do_log, CTLFLAG_RWTUN, 576243980Salfred &kassert_do_log, 0, "KASSERT triggers a panic (1) or just a warning (0)"); 577243980Salfred 578267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, warnings, CTLFLAG_RWTUN, 579243980Salfred &kassert_warnings, 0, "number of KASSERTs that have been triggered"); 580243980Salfred 581267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, log_panic_at, CTLFLAG_RWTUN, 582243980Salfred &kassert_log_panic_at, 0, "max number of KASSERTS before we will panic"); 583243980Salfred 584267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, log_pps_limit, CTLFLAG_RWTUN, 585243980Salfred &kassert_log_pps_limit, 0, "limit number of log messages per second"); 586243980Salfred 587267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, log_mute_at, CTLFLAG_RWTUN, 588243980Salfred &kassert_log_mute_at, 0, "max number of KASSERTS to log"); 589243980Salfred 590243980Salfredstatic int kassert_sysctl_kassert(SYSCTL_HANDLER_ARGS); 591243980Salfred 592243980SalfredSYSCTL_PROC(_debug_kassert, OID_AUTO, kassert, 593243980Salfred CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0, 594243980Salfred kassert_sysctl_kassert, "I", "set to trigger a test kassert"); 595243980Salfred 596243980Salfredstatic int 597243980Salfredkassert_sysctl_kassert(SYSCTL_HANDLER_ARGS) 598243980Salfred{ 599243980Salfred int error, i; 600243980Salfred 601243980Salfred error = sysctl_wire_old_buffer(req, sizeof(int)); 602243980Salfred if (error == 0) { 603243980Salfred i = 0; 604243980Salfred error = sysctl_handle_int(oidp, &i, 0, req); 605243980Salfred } 606243980Salfred if (error != 0 || req->newptr == NULL) 607243980Salfred return (error); 608243980Salfred KASSERT(0, ("kassert_sysctl_kassert triggered kassert %d", i)); 609243980Salfred return (0); 610243980Salfred} 611243980Salfred 61217658Sjulian/* 613243980Salfred * Called by KASSERT, this decides if we will panic 614243980Salfred * or if we will log via printf and/or ktr. 615243980Salfred */ 616243980Salfredvoid 617243980Salfredkassert_panic(const char *fmt, ...) 618243980Salfred{ 619243980Salfred static char buf[256]; 620243980Salfred va_list ap; 621243980Salfred 622243980Salfred va_start(ap, fmt); 623243980Salfred (void)vsnprintf(buf, sizeof(buf), fmt, ap); 624243980Salfred va_end(ap); 625243980Salfred 626243980Salfred /* 627243980Salfred * panic if we're not just warning, or if we've exceeded 628243980Salfred * kassert_log_panic_at warnings. 629243980Salfred */ 630243980Salfred if (!kassert_warn_only || 631243980Salfred (kassert_log_panic_at > 0 && 632243980Salfred kassert_warnings >= kassert_log_panic_at)) { 633243980Salfred va_start(ap, fmt); 634243980Salfred vpanic(fmt, ap); 635243980Salfred /* NORETURN */ 636243980Salfred } 637243980Salfred#ifdef KTR 638243980Salfred if (kassert_do_ktr) 639243980Salfred CTR0(ktr_mask, buf); 640243980Salfred#endif /* KTR */ 641243980Salfred /* 642243980Salfred * log if we've not yet met the mute limit. 643243980Salfred */ 644243980Salfred if (kassert_do_log && 645243980Salfred (kassert_log_mute_at == 0 || 646243980Salfred kassert_warnings < kassert_log_mute_at)) { 647243980Salfred static struct timeval lasterr; 648243980Salfred static int curerr; 649243980Salfred 650243980Salfred if (ppsratecheck(&lasterr, &curerr, kassert_log_pps_limit)) { 651243980Salfred printf("KASSERT failed: %s\n", buf); 652243980Salfred kdb_backtrace(); 653243980Salfred } 654243980Salfred } 655244099Salfred#ifdef KDB 656244099Salfred if (kassert_do_kdb) { 657244099Salfred kdb_enter(KDB_WHY_KASSERT, buf); 658244099Salfred } 659244099Salfred#endif 660243980Salfred atomic_add_int(&kassert_warnings, 1); 661243980Salfred} 662243980Salfred#endif 663243980Salfred 664243980Salfred/* 66517658Sjulian * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 66617658Sjulian * and then reboots. If we are called twice, then we avoid trying to sync 66717658Sjulian * the disks as this often leads to recursive panics. 66817658Sjulian */ 66917658Sjulianvoid 670130164Sphkpanic(const char *fmt, ...) 67117658Sjulian{ 672243980Salfred va_list ap; 673243980Salfred 674243980Salfred va_start(ap, fmt); 675243980Salfred vpanic(fmt, ap); 676243980Salfred} 677243980Salfred 678281915Smarkjvoid 679243980Salfredvpanic(const char *fmt, va_list ap) 680243980Salfred{ 681213648Savg#ifdef SMP 682228424Savg cpuset_t other_cpus; 683213648Savg#endif 684100209Sgallatin struct thread *td = curthread; 685103647Sjhb int bootopt, newpanic; 68638874Sache static char buf[256]; 68717658Sjulian 688243515Savg spinlock_enter(); 689228424Savg 69065557Sjasone#ifdef SMP 69182115Sjhb /* 692243515Savg * stop_cpus_hard(other_cpus) should prevent multiple CPUs from 693243515Savg * concurrently entering panic. Only the winner will proceed 694243515Savg * further. 69582115Sjhb */ 696243515Savg if (panicstr == NULL && !kdb_active) { 697243515Savg other_cpus = all_cpus; 698243515Savg CPU_CLR(PCPU_GET(cpuid), &other_cpus); 699243515Savg stop_cpus_hard(other_cpus); 700243515Savg } 701228424Savg 702243515Savg /* 703282332Smarkj * Ensure that the scheduler is stopped while panicking, even if panic 704282332Smarkj * has been entered from kdb. 705243515Savg */ 706243515Savg td->td_stopsched = 1; 70765557Sjasone#endif 70865557Sjasone 709222865Sattilio bootopt = RB_AUTOBOOT; 710103647Sjhb newpanic = 0; 71117658Sjulian if (panicstr) 71217658Sjulian bootopt |= RB_NOSYNC; 713103647Sjhb else { 714222865Sattilio bootopt |= RB_DUMP; 71517658Sjulian panicstr = fmt; 716103647Sjhb newpanic = 1; 717103647Sjhb } 71817658Sjulian 719116398Siedowse if (newpanic) { 720116398Siedowse (void)vsnprintf(buf, sizeof(buf), fmt, ap); 72138874Sache panicstr = buf; 722228632Savg cngrab(); 723130164Sphk printf("panic: %s\n", buf); 724116398Siedowse } else { 725116398Siedowse printf("panic: "); 726116398Siedowse vprintf(fmt, ap); 727130164Sphk printf("\n"); 728116398Siedowse } 72926100Sfsmp#ifdef SMP 730134089Sjhb printf("cpuid = %d\n", PCPU_GET(cpuid)); 73126100Sfsmp#endif 73217658Sjulian 733131927Smarcel#ifdef KDB 734103647Sjhb if (newpanic && trace_on_panic) 735131927Smarcel kdb_backtrace(); 73617658Sjulian if (debugger_on_panic) 737174898Srwatson kdb_enter(KDB_WHY_PANIC, "panic"); 73817658Sjulian#endif 739170307Sjeff /*thread_lock(td); */ 740100209Sgallatin td->td_flags |= TDF_INPANIC; 741170307Sjeff /* thread_unlock(td); */ 74285202Speter if (!sync_on_panic) 74385202Speter bootopt |= RB_NOSYNC; 744214004Smarcel kern_reboot(bootopt); 74517658Sjulian} 74617658Sjulian 74717768Sjulian/* 74843436Smsmith * Support for poweroff delay. 749197071Sn_hibma * 750197071Sn_hibma * Please note that setting this delay too short might power off your machine 751197071Sn_hibma * before the write cache on your hard disk has been flushed, leading to 752197071Sn_hibma * soft-updates inconsistencies. 75343436Smsmith */ 75454248Smsmith#ifndef POWEROFF_DELAY 75554248Smsmith# define POWEROFF_DELAY 5000 75654248Smsmith#endif 75754248Smsmithstatic int poweroff_delay = POWEROFF_DELAY; 75854248Smsmith 75943436SmsmithSYSCTL_INT(_kern_shutdown, OID_AUTO, poweroff_delay, CTLFLAG_RW, 760228449Seadler &poweroff_delay, 0, "Delay before poweroff to write disk caches (msec)"); 76143436Smsmith 762110859Salfredstatic void 76350107Smsmithpoweroff_wait(void *junk, int howto) 76443436Smsmith{ 765110859Salfred 766110859Salfred if (!(howto & RB_POWEROFF) || poweroff_delay <= 0) 76743436Smsmith return; 76843436Smsmith DELAY(poweroff_delay * 1000); 76943436Smsmith} 77055539Sluoqi 77155539Sluoqi/* 77255539Sluoqi * Some system processes (e.g. syncer) need to be stopped at appropriate 77355539Sluoqi * points in their main loops prior to a system shutdown, so that they 77455539Sluoqi * won't interfere with the shutdown process (e.g. by holding a disk buf 77555539Sluoqi * to cause sync to fail). For each of these system processes, register 77655539Sluoqi * shutdown_kproc() as a handler for one of shutdown events. 77755539Sluoqi */ 77855539Sluoqistatic int kproc_shutdown_wait = 60; 77955539SluoqiSYSCTL_INT(_kern_shutdown, OID_AUTO, kproc_shutdown_wait, CTLFLAG_RW, 780228449Seadler &kproc_shutdown_wait, 0, "Max wait time (sec) to stop for each process"); 78155539Sluoqi 78255539Sluoqivoid 78370063Sjhbkproc_shutdown(void *arg, int howto) 78455539Sluoqi{ 78555539Sluoqi struct proc *p; 78655539Sluoqi int error; 78755539Sluoqi 78855539Sluoqi if (panicstr) 78955539Sluoqi return; 79055539Sluoqi 79155539Sluoqi p = (struct proc *)arg; 792132866Snjl printf("Waiting (max %d seconds) for system process `%s' to stop...", 793198408Sjhb kproc_shutdown_wait, p->p_comm); 794172836Sjulian error = kproc_suspend(p, kproc_shutdown_wait * hz); 79555539Sluoqi 79655539Sluoqi if (error == EWOULDBLOCK) 797132866Snjl printf("timed out\n"); 79855539Sluoqi else 799132866Snjl printf("done\n"); 80055539Sluoqi} 80193496Sphk 802173004Sjulianvoid 803173004Sjuliankthread_shutdown(void *arg, int howto) 804173004Sjulian{ 805173004Sjulian struct thread *td; 806173004Sjulian int error; 807173004Sjulian 808173004Sjulian if (panicstr) 809173004Sjulian return; 810173004Sjulian 811173004Sjulian td = (struct thread *)arg; 812173004Sjulian printf("Waiting (max %d seconds) for system thread `%s' to stop...", 813198408Sjhb kproc_shutdown_wait, td->td_name); 814173004Sjulian error = kthread_suspend(td, kproc_shutdown_wait * hz); 815173004Sjulian 816173004Sjulian if (error == EWOULDBLOCK) 817173004Sjulian printf("timed out\n"); 818173004Sjulian else 819173004Sjulian printf("done\n"); 820173004Sjulian} 821173004Sjulian 822242439Salfredstatic char dumpdevname[sizeof(((struct cdev*)NULL)->si_name)]; 823242439SalfredSYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD, 824242439Salfred dumpdevname, 0, "Device for kernel dumps"); 825242439Salfred 82693496Sphk/* Registration of dumpers */ 82793496Sphkint 828274366Spjdset_dumper(struct dumperinfo *di, const char *devname, struct thread *td) 82993496Sphk{ 830242489Salfred size_t wantcopy; 831274366Spjd int error; 832110859Salfred 833274366Spjd error = priv_check(td, PRIV_SETDUMPER); 834274366Spjd if (error != 0) 835274366Spjd return (error); 836274366Spjd 83793496Sphk if (di == NULL) { 83893496Sphk bzero(&dumper, sizeof dumper); 839242439Salfred dumpdevname[0] = '\0'; 84093496Sphk return (0); 84193496Sphk } 84293496Sphk if (dumper.dumper != NULL) 84393496Sphk return (EBUSY); 84493496Sphk dumper = *di; 845242489Salfred wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname)); 846242489Salfred if (wantcopy >= sizeof(dumpdevname)) { 847242439Salfred printf("set_dumper: device name truncated from '%s' -> '%s'\n", 848242439Salfred devname, dumpdevname); 849242439Salfred } 85093496Sphk return (0); 85193496Sphk} 85293496Sphk 853175768Sru/* Call dumper with bounds checking. */ 854175768Sruint 855175768Srudump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, 856175768Sru off_t offset, size_t length) 857175768Sru{ 858175768Sru 859175768Sru if (length != 0 && (offset < di->mediaoffset || 860175768Sru offset - di->mediaoffset + length > di->mediasize)) { 861225516Sattilio printf("Attempt to write outside dump device boundaries.\n" 862225516Sattilio "offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n", 863225516Sattilio (intmax_t)offset, (intmax_t)di->mediaoffset, 864225516Sattilio (uintmax_t)length, (intmax_t)di->mediasize); 865225516Sattilio return (ENOSPC); 866175768Sru } 867175768Sru return (di->dumper(di->priv, virtual, physical, offset, length)); 868175768Sru} 869175768Sru 87093496Sphkvoid 871183527Spetermkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, 872183527Speter uint64_t dumplen, uint32_t blksz) 873183527Speter{ 874183527Speter 875183527Speter bzero(kdh, sizeof(*kdh)); 876283115Sasomers strlcpy(kdh->magic, magic, sizeof(kdh->magic)); 877283115Sasomers strlcpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture)); 878183527Speter kdh->version = htod32(KERNELDUMPVERSION); 879183527Speter kdh->architectureversion = htod32(archver); 880183527Speter kdh->dumplength = htod64(dumplen); 881183527Speter kdh->dumptime = htod64(time_second); 882183527Speter kdh->blocksize = htod32(blksz); 883283115Sasomers strlcpy(kdh->hostname, prison0.pr_hostname, sizeof(kdh->hostname)); 884283115Sasomers strlcpy(kdh->versionstring, version, sizeof(kdh->versionstring)); 885183527Speter if (panicstr != NULL) 886283115Sasomers strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); 887183527Speter kdh->parity = kerneldump_parity(kdh); 888183527Speter} 889