kern_shutdown.c revision 269105
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 269105 2014-07-25 23:52:53Z gavin $"); 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> 7694169Sphk#include <machine/pcb.h> 7791778Sjake#include <machine/smp.h> 7817658Sjulian 79163606Srwatson#include <security/mac/mac_framework.h> 80163606Srwatson 81157628Spjd#include <vm/vm.h> 82157628Spjd#include <vm/vm_object.h> 83157628Spjd#include <vm/vm_page.h> 84157628Spjd#include <vm/vm_pager.h> 85157628Spjd#include <vm/swap_pager.h> 86157628Spjd 8717658Sjulian#include <sys/signalvar.h> 8817658Sjulian 8917658Sjulian#ifndef PANIC_REBOOT_WAIT_TIME 9017658Sjulian#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ 9117658Sjulian#endif 92258956Scpercivastatic int panic_reboot_wait_time = PANIC_REBOOT_WAIT_TIME; 93267992ShselaskySYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN, 94258893Scperciva &panic_reboot_wait_time, 0, 95258893Scperciva "Seconds to wait before rebooting after a panic"); 9617658Sjulian 9717658Sjulian/* 9817658Sjulian * Note that stdarg.h and the ANSI style va_start macro is used for both 9917658Sjulian * ANSI and traditional C compilers. 10017658Sjulian */ 10117658Sjulian#include <machine/stdarg.h> 10217658Sjulian 103131927Smarcel#ifdef KDB 104131927Smarcel#ifdef KDB_UNATTENDED 10542135Smsmithint debugger_on_panic = 0; 10617658Sjulian#else 10742135Smsmithint debugger_on_panic = 1; 10817658Sjulian#endif 109228475SobrienSYSCTL_INT(_debug, OID_AUTO, debugger_on_panic, 110267992Shselasky CTLFLAG_RWTUN | CTLFLAG_SECURE, 111228487Sobrien &debugger_on_panic, 0, "Run debugger on kernel panic"); 112103647Sjhb 113131927Smarcel#ifdef KDB_TRACE 114213322Savgstatic int trace_on_panic = 1; 115103647Sjhb#else 116213322Savgstatic int trace_on_panic = 0; 11717658Sjulian#endif 118228475SobrienSYSCTL_INT(_debug, OID_AUTO, trace_on_panic, 119267992Shselasky CTLFLAG_RWTUN | CTLFLAG_SECURE, 120228487Sobrien &trace_on_panic, 0, "Print stack trace on kernel panic"); 121131927Smarcel#endif /* KDB */ 12217658Sjulian 123213322Savgstatic int sync_on_panic = 0; 124267992ShselaskySYSCTL_INT(_kern, OID_AUTO, sync_on_panic, CTLFLAG_RWTUN, 12585202Speter &sync_on_panic, 0, "Do a sync before rebooting from a panic"); 12685202Speter 127227309Sedstatic SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW, 0, 128227309Sed "Shutdown environment"); 12943436Smsmith 130225448Sattilio#ifndef DIAGNOSTIC 131225448Sattiliostatic int show_busybufs; 132225448Sattilio#else 133225448Sattiliostatic int show_busybufs = 1; 134225448Sattilio#endif 135225448SattilioSYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW, 136225448Sattilio &show_busybufs, 0, ""); 137225448Sattilio 13817658Sjulian/* 13917658Sjulian * Variable panicstr contains argument to first call to panic; used as flag 14017658Sjulian * to indicate that the kernel has already called panic. 14117658Sjulian */ 14217658Sjulianconst char *panicstr; 14317658Sjulian 14493496Sphkint dumping; /* system is dumping */ 145155383Sjeffint rebooting; /* system is rebooting */ 14693496Sphkstatic struct dumperinfo dumper; /* our selected dumper */ 14767093Sps 148131927Smarcel/* Context information for dump-debuggers. */ 149131927Smarcelstatic struct pcb dumppcb; /* Registers. */ 150235777Shartilwpid_t dumptid; /* Thread ID. */ 151131927Smarcel 15265395Speterstatic void poweroff_wait(void *, int); 15365395Speterstatic void shutdown_halt(void *junk, int howto); 15465395Speterstatic void shutdown_panic(void *junk, int howto); 15565395Speterstatic void shutdown_reset(void *junk, int howto); 156243980Salfredstatic void vpanic(const char *fmt, va_list ap) __dead2; 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 678243980Salfredstatic void 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 /* 703243515Savg * We set stop_scheduler here and not in the block above, 704243515Savg * because we want to ensure that if panic has been called and 705243515Savg * stop_scheduler_on_panic is true, then stop_scheduler will 706243515Savg * always be set. Even if panic has been entered from kdb. 707243515Savg */ 708243515Savg td->td_stopsched = 1; 70965557Sjasone#endif 71065557Sjasone 711222865Sattilio bootopt = RB_AUTOBOOT; 712103647Sjhb newpanic = 0; 71317658Sjulian if (panicstr) 71417658Sjulian bootopt |= RB_NOSYNC; 715103647Sjhb else { 716222865Sattilio bootopt |= RB_DUMP; 71717658Sjulian panicstr = fmt; 718103647Sjhb newpanic = 1; 719103647Sjhb } 72017658Sjulian 721116398Siedowse if (newpanic) { 722116398Siedowse (void)vsnprintf(buf, sizeof(buf), fmt, ap); 72338874Sache panicstr = buf; 724228632Savg cngrab(); 725130164Sphk printf("panic: %s\n", buf); 726116398Siedowse } else { 727116398Siedowse printf("panic: "); 728116398Siedowse vprintf(fmt, ap); 729130164Sphk printf("\n"); 730116398Siedowse } 73126100Sfsmp#ifdef SMP 732134089Sjhb printf("cpuid = %d\n", PCPU_GET(cpuid)); 73326100Sfsmp#endif 73417658Sjulian 735131927Smarcel#ifdef KDB 736103647Sjhb if (newpanic && trace_on_panic) 737131927Smarcel kdb_backtrace(); 73817658Sjulian if (debugger_on_panic) 739174898Srwatson kdb_enter(KDB_WHY_PANIC, "panic"); 74017658Sjulian#endif 741170307Sjeff /*thread_lock(td); */ 742100209Sgallatin td->td_flags |= TDF_INPANIC; 743170307Sjeff /* thread_unlock(td); */ 74485202Speter if (!sync_on_panic) 74585202Speter bootopt |= RB_NOSYNC; 746214004Smarcel kern_reboot(bootopt); 74717658Sjulian} 74817658Sjulian 74917768Sjulian/* 75043436Smsmith * Support for poweroff delay. 751197071Sn_hibma * 752197071Sn_hibma * Please note that setting this delay too short might power off your machine 753197071Sn_hibma * before the write cache on your hard disk has been flushed, leading to 754197071Sn_hibma * soft-updates inconsistencies. 75543436Smsmith */ 75654248Smsmith#ifndef POWEROFF_DELAY 75754248Smsmith# define POWEROFF_DELAY 5000 75854248Smsmith#endif 75954248Smsmithstatic int poweroff_delay = POWEROFF_DELAY; 76054248Smsmith 76143436SmsmithSYSCTL_INT(_kern_shutdown, OID_AUTO, poweroff_delay, CTLFLAG_RW, 762228449Seadler &poweroff_delay, 0, "Delay before poweroff to write disk caches (msec)"); 76343436Smsmith 764110859Salfredstatic void 76550107Smsmithpoweroff_wait(void *junk, int howto) 76643436Smsmith{ 767110859Salfred 768110859Salfred if (!(howto & RB_POWEROFF) || poweroff_delay <= 0) 76943436Smsmith return; 77043436Smsmith DELAY(poweroff_delay * 1000); 77143436Smsmith} 77255539Sluoqi 77355539Sluoqi/* 77455539Sluoqi * Some system processes (e.g. syncer) need to be stopped at appropriate 77555539Sluoqi * points in their main loops prior to a system shutdown, so that they 77655539Sluoqi * won't interfere with the shutdown process (e.g. by holding a disk buf 77755539Sluoqi * to cause sync to fail). For each of these system processes, register 77855539Sluoqi * shutdown_kproc() as a handler for one of shutdown events. 77955539Sluoqi */ 78055539Sluoqistatic int kproc_shutdown_wait = 60; 78155539SluoqiSYSCTL_INT(_kern_shutdown, OID_AUTO, kproc_shutdown_wait, CTLFLAG_RW, 782228449Seadler &kproc_shutdown_wait, 0, "Max wait time (sec) to stop for each process"); 78355539Sluoqi 78455539Sluoqivoid 78570063Sjhbkproc_shutdown(void *arg, int howto) 78655539Sluoqi{ 78755539Sluoqi struct proc *p; 78855539Sluoqi int error; 78955539Sluoqi 79055539Sluoqi if (panicstr) 79155539Sluoqi return; 79255539Sluoqi 79355539Sluoqi p = (struct proc *)arg; 794132866Snjl printf("Waiting (max %d seconds) for system process `%s' to stop...", 795198408Sjhb kproc_shutdown_wait, p->p_comm); 796172836Sjulian error = kproc_suspend(p, kproc_shutdown_wait * hz); 79755539Sluoqi 79855539Sluoqi if (error == EWOULDBLOCK) 799132866Snjl printf("timed out\n"); 80055539Sluoqi else 801132866Snjl printf("done\n"); 80255539Sluoqi} 80393496Sphk 804173004Sjulianvoid 805173004Sjuliankthread_shutdown(void *arg, int howto) 806173004Sjulian{ 807173004Sjulian struct thread *td; 808173004Sjulian int error; 809173004Sjulian 810173004Sjulian if (panicstr) 811173004Sjulian return; 812173004Sjulian 813173004Sjulian td = (struct thread *)arg; 814173004Sjulian printf("Waiting (max %d seconds) for system thread `%s' to stop...", 815198408Sjhb kproc_shutdown_wait, td->td_name); 816173004Sjulian error = kthread_suspend(td, kproc_shutdown_wait * hz); 817173004Sjulian 818173004Sjulian if (error == EWOULDBLOCK) 819173004Sjulian printf("timed out\n"); 820173004Sjulian else 821173004Sjulian printf("done\n"); 822173004Sjulian} 823173004Sjulian 824242439Salfredstatic char dumpdevname[sizeof(((struct cdev*)NULL)->si_name)]; 825242439SalfredSYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD, 826242439Salfred dumpdevname, 0, "Device for kernel dumps"); 827242439Salfred 82893496Sphk/* Registration of dumpers */ 82993496Sphkint 830242439Salfredset_dumper(struct dumperinfo *di, const char *devname) 83193496Sphk{ 832242489Salfred size_t wantcopy; 833110859Salfred 83493496Sphk if (di == NULL) { 83593496Sphk bzero(&dumper, sizeof dumper); 836242439Salfred dumpdevname[0] = '\0'; 83793496Sphk return (0); 83893496Sphk } 83993496Sphk if (dumper.dumper != NULL) 84093496Sphk return (EBUSY); 84193496Sphk dumper = *di; 842242489Salfred wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname)); 843242489Salfred if (wantcopy >= sizeof(dumpdevname)) { 844242439Salfred printf("set_dumper: device name truncated from '%s' -> '%s'\n", 845242439Salfred devname, dumpdevname); 846242439Salfred } 84793496Sphk return (0); 84893496Sphk} 84993496Sphk 850175768Sru/* Call dumper with bounds checking. */ 851175768Sruint 852175768Srudump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, 853175768Sru off_t offset, size_t length) 854175768Sru{ 855175768Sru 856175768Sru if (length != 0 && (offset < di->mediaoffset || 857175768Sru offset - di->mediaoffset + length > di->mediasize)) { 858225516Sattilio printf("Attempt to write outside dump device boundaries.\n" 859225516Sattilio "offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n", 860225516Sattilio (intmax_t)offset, (intmax_t)di->mediaoffset, 861225516Sattilio (uintmax_t)length, (intmax_t)di->mediasize); 862225516Sattilio return (ENOSPC); 863175768Sru } 864175768Sru return (di->dumper(di->priv, virtual, physical, offset, length)); 865175768Sru} 866175768Sru 86793496Sphkvoid 868183527Spetermkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, 869183527Speter uint64_t dumplen, uint32_t blksz) 870183527Speter{ 871183527Speter 872183527Speter bzero(kdh, sizeof(*kdh)); 873183527Speter strncpy(kdh->magic, magic, sizeof(kdh->magic)); 874183527Speter strncpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture)); 875183527Speter kdh->version = htod32(KERNELDUMPVERSION); 876183527Speter kdh->architectureversion = htod32(archver); 877183527Speter kdh->dumplength = htod64(dumplen); 878183527Speter kdh->dumptime = htod64(time_second); 879183527Speter kdh->blocksize = htod32(blksz); 880194118Sjamie strncpy(kdh->hostname, prison0.pr_hostname, sizeof(kdh->hostname)); 881183527Speter strncpy(kdh->versionstring, version, sizeof(kdh->versionstring)); 882183527Speter if (panicstr != NULL) 883183527Speter strncpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); 884183527Speter kdh->parity = kerneldump_parity(kdh); 885183527Speter} 886