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: releng/11.0/sys/kern/kern_shutdown.c 302349 2016-07-05 18:34:34Z glebius $"); 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> 53287964Strasz#include <sys/filedesc.h> 54193066Sjamie#include <sys/jail.h> 55131927Smarcel#include <sys/kdb.h> 5617658Sjulian#include <sys/kernel.h> 57183527Speter#include <sys/kerneldump.h> 5855539Sluoqi#include <sys/kthread.h> 59243980Salfred#include <sys/ktr.h> 6089601Ssobomax#include <sys/malloc.h> 6121776Sbde#include <sys/mount.h> 62164033Srwatson#include <sys/priv.h> 6378767Sjhb#include <sys/proc.h> 6478767Sjhb#include <sys/reboot.h> 6578767Sjhb#include <sys/resourcevar.h> 66248084Sattilio#include <sys/rwlock.h> 67137263Speter#include <sys/sched.h> 68206878Sattilio#include <sys/smp.h> 6917658Sjulian#include <sys/sysctl.h> 7017658Sjulian#include <sys/sysproto.h> 71225448Sattilio#include <sys/vnode.h> 72221173Sattilio#include <sys/watchdog.h> 7317658Sjulian 74174921Srwatson#include <ddb/ddb.h> 75174921Srwatson 76118990Smarcel#include <machine/cpu.h> 77276772Smarkj#include <machine/dump.h> 7894169Sphk#include <machine/pcb.h> 7991778Sjake#include <machine/smp.h> 8017658Sjulian 81163606Srwatson#include <security/mac/mac_framework.h> 82163606Srwatson 83157628Spjd#include <vm/vm.h> 84157628Spjd#include <vm/vm_object.h> 85157628Spjd#include <vm/vm_page.h> 86157628Spjd#include <vm/vm_pager.h> 87157628Spjd#include <vm/swap_pager.h> 88157628Spjd 8917658Sjulian#include <sys/signalvar.h> 9017658Sjulian 91298076Scemstatic MALLOC_DEFINE(M_DUMPER, "dumper", "dumper block buffer"); 92298076Scem 9317658Sjulian#ifndef PANIC_REBOOT_WAIT_TIME 9417658Sjulian#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ 9517658Sjulian#endif 96258956Scpercivastatic int panic_reboot_wait_time = PANIC_REBOOT_WAIT_TIME; 97267992ShselaskySYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN, 98258893Scperciva &panic_reboot_wait_time, 0, 99258893Scperciva "Seconds to wait before rebooting after a panic"); 10017658Sjulian 10117658Sjulian/* 10217658Sjulian * Note that stdarg.h and the ANSI style va_start macro is used for both 10317658Sjulian * ANSI and traditional C compilers. 10417658Sjulian */ 10517658Sjulian#include <machine/stdarg.h> 10617658Sjulian 107131927Smarcel#ifdef KDB 108131927Smarcel#ifdef KDB_UNATTENDED 10942135Smsmithint debugger_on_panic = 0; 11017658Sjulian#else 11142135Smsmithint debugger_on_panic = 1; 11217658Sjulian#endif 113228475SobrienSYSCTL_INT(_debug, OID_AUTO, debugger_on_panic, 114267992Shselasky CTLFLAG_RWTUN | CTLFLAG_SECURE, 115228487Sobrien &debugger_on_panic, 0, "Run debugger on kernel panic"); 116103647Sjhb 117131927Smarcel#ifdef KDB_TRACE 118213322Savgstatic int trace_on_panic = 1; 119103647Sjhb#else 120213322Savgstatic int trace_on_panic = 0; 12117658Sjulian#endif 122228475SobrienSYSCTL_INT(_debug, OID_AUTO, trace_on_panic, 123267992Shselasky CTLFLAG_RWTUN | CTLFLAG_SECURE, 124228487Sobrien &trace_on_panic, 0, "Print stack trace on kernel panic"); 125131927Smarcel#endif /* KDB */ 12617658Sjulian 127213322Savgstatic int sync_on_panic = 0; 128267992ShselaskySYSCTL_INT(_kern, OID_AUTO, sync_on_panic, CTLFLAG_RWTUN, 12985202Speter &sync_on_panic, 0, "Do a sync before rebooting from a panic"); 13085202Speter 131227309Sedstatic SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW, 0, 132227309Sed "Shutdown environment"); 13343436Smsmith 134225448Sattilio#ifndef DIAGNOSTIC 135225448Sattiliostatic int show_busybufs; 136225448Sattilio#else 137225448Sattiliostatic int show_busybufs = 1; 138225448Sattilio#endif 139225448SattilioSYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW, 140225448Sattilio &show_busybufs, 0, ""); 141225448Sattilio 142288446Scpercivaint suspend_blocked = 0; 143288446ScpercivaSYSCTL_INT(_kern, OID_AUTO, suspend_blocked, CTLFLAG_RW, 144288446Scperciva &suspend_blocked, 0, "Block suspend due to a pending shutdown"); 145288446Scperciva 14617658Sjulian/* 14717658Sjulian * Variable panicstr contains argument to first call to panic; used as flag 14817658Sjulian * to indicate that the kernel has already called panic. 14917658Sjulian */ 15017658Sjulianconst char *panicstr; 15117658Sjulian 15293496Sphkint dumping; /* system is dumping */ 153155383Sjeffint rebooting; /* system is rebooting */ 15493496Sphkstatic struct dumperinfo dumper; /* our selected dumper */ 15567093Sps 156131927Smarcel/* Context information for dump-debuggers. */ 157131927Smarcelstatic struct pcb dumppcb; /* Registers. */ 158235777Shartilwpid_t dumptid; /* Thread ID. */ 159131927Smarcel 160287964Straszstatic struct cdevsw reroot_cdevsw = { 161287964Strasz .d_version = D_VERSION, 162287964Strasz .d_name = "reroot", 163287964Strasz}; 164287964Strasz 16565395Speterstatic void poweroff_wait(void *, int); 16665395Speterstatic void shutdown_halt(void *junk, int howto); 16765395Speterstatic void shutdown_panic(void *junk, int howto); 16865395Speterstatic void shutdown_reset(void *junk, int howto); 169287964Straszstatic int kern_reroot(void); 17017658Sjulian 17150107Smsmith/* register various local shutdown events */ 172110859Salfredstatic void 17350107Smsmithshutdown_conf(void *unused) 17450107Smsmith{ 175110859Salfred 176110859Salfred EVENTHANDLER_REGISTER(shutdown_final, poweroff_wait, NULL, 177214279Sbrucec SHUTDOWN_PRI_FIRST); 178110859Salfred EVENTHANDLER_REGISTER(shutdown_final, shutdown_halt, NULL, 179110859Salfred SHUTDOWN_PRI_LAST + 100); 180110859Salfred EVENTHANDLER_REGISTER(shutdown_final, shutdown_panic, NULL, 181110859Salfred SHUTDOWN_PRI_LAST + 100); 182110859Salfred EVENTHANDLER_REGISTER(shutdown_final, shutdown_reset, NULL, 183110859Salfred SHUTDOWN_PRI_LAST + 200); 18450107Smsmith} 18548868Sphk 186177253SrwatsonSYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL); 18750107Smsmith 18817658Sjulian/* 189287964Strasz * The only reason this exists is to create the /dev/reroot/ directory, 190287964Strasz * used by reroot code in init(8) as a mountpoint for tmpfs. 191287964Strasz */ 192287964Straszstatic void 193287964Straszreroot_conf(void *unused) 194287964Strasz{ 195287964Strasz int error; 196287964Strasz struct cdev *cdev; 197287964Strasz 198287964Strasz error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &cdev, 199287964Strasz &reroot_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0600, "reroot/reroot"); 200287964Strasz if (error != 0) { 201287964Strasz printf("%s: failed to create device node, error %d", 202287964Strasz __func__, error); 203287964Strasz } 204287964Strasz} 205287964Strasz 206287964StraszSYSINIT(reroot_conf, SI_SUB_DEVFS, SI_ORDER_ANY, reroot_conf, NULL); 207287964Strasz 208287964Strasz/* 209167211Srwatson * The system call that results in a reboot. 21017658Sjulian */ 21182749Sdillon/* ARGSUSED */ 21217658Sjulianint 213225617Skmacysys_reboot(struct thread *td, struct reboot_args *uap) 21417658Sjulian{ 21517658Sjulian int error; 21617658Sjulian 217106024Srwatson error = 0; 218106024Srwatson#ifdef MAC 219172930Srwatson error = mac_system_check_reboot(td->td_ucred, uap->opt); 220106024Srwatson#endif 221106024Srwatson if (error == 0) 222164033Srwatson error = priv_check(td, PRIV_REBOOT); 223106024Srwatson if (error == 0) { 224287964Strasz if (uap->opt & RB_REROOT) { 225287964Strasz error = kern_reroot(); 226287964Strasz } else { 227287964Strasz mtx_lock(&Giant); 228287964Strasz kern_reboot(uap->opt); 229287964Strasz mtx_unlock(&Giant); 230287964Strasz } 231106024Srwatson } 23282749Sdillon return (error); 23317658Sjulian} 23417658Sjulian 23517658Sjulian/* 23617658Sjulian * Called by events that want to shut down.. e.g <CTL><ALT><DEL> on a PC 23717658Sjulian */ 23817658Sjulianvoid 23965268Smsmithshutdown_nice(int howto) 24017658Sjulian{ 241110859Salfred 24217658Sjulian if (initproc != NULL) { 243264237Sed /* Send a signal to init(8) and have it shutdown the world. */ 24473913Sjhb PROC_LOCK(initproc); 245264237Sed if (howto & RB_POWEROFF) 246264237Sed kern_psignal(initproc, SIGUSR2); 247264237Sed else if (howto & RB_HALT) 248264237Sed kern_psignal(initproc, SIGUSR1); 249264237Sed else 250264237Sed kern_psignal(initproc, SIGINT); 25173913Sjhb PROC_UNLOCK(initproc); 25217658Sjulian } else { 253264237Sed /* No init(8) running, so simply reboot. */ 254264240Sed kern_reboot(howto | RB_NOSYNC); 25517658Sjulian } 25617658Sjulian} 25717658Sjulian 25854233Sphkstatic void 25965395Speterprint_uptime(void) 26054233Sphk{ 26154233Sphk int f; 26254233Sphk struct timespec ts; 26354233Sphk 26454233Sphk getnanouptime(&ts); 26554233Sphk printf("Uptime: "); 26654233Sphk f = 0; 26754233Sphk if (ts.tv_sec >= 86400) { 26865764Sjhb printf("%ldd", (long)ts.tv_sec / 86400); 26954233Sphk ts.tv_sec %= 86400; 27054233Sphk f = 1; 27154233Sphk } 27254233Sphk if (f || ts.tv_sec >= 3600) { 27365764Sjhb printf("%ldh", (long)ts.tv_sec / 3600); 27454233Sphk ts.tv_sec %= 3600; 27554233Sphk f = 1; 27654233Sphk } 27754233Sphk if (f || ts.tv_sec >= 60) { 27865764Sjhb printf("%ldm", (long)ts.tv_sec / 60); 27954233Sphk ts.tv_sec %= 60; 28054233Sphk f = 1; 28154233Sphk } 28265764Sjhb printf("%lds\n", (long)ts.tv_sec); 28354233Sphk} 28454233Sphk 285222801Smarcelint 286222801Smarceldoadump(boolean_t textdump) 28794169Sphk{ 288222801Smarcel boolean_t coredump; 289269105Sgavin int error; 290110859Salfred 291269105Sgavin error = 0; 292222801Smarcel if (dumping) 293222801Smarcel return (EBUSY); 294222801Smarcel if (dumper.dumper == NULL) 295222801Smarcel return (ENXIO); 296132412Sjulian 29794169Sphk savectx(&dumppcb); 298131927Smarcel dumptid = curthread->td_tid; 29994169Sphk dumping++; 300222801Smarcel 301222801Smarcel coredump = TRUE; 302174921Srwatson#ifdef DDB 303222801Smarcel if (textdump && textdump_pending) { 304222801Smarcel coredump = FALSE; 305174921Srwatson textdump_dumpsys(&dumper); 306222801Smarcel } 307174921Srwatson#endif 308222801Smarcel if (coredump) 309269105Sgavin error = dumpsys(&dumper); 310222801Smarcel 311176788Sru dumping--; 312269105Sgavin return (error); 31394169Sphk} 31494169Sphk 31517658Sjulian/* 316137329Snjl * Shutdown the system cleanly to prepare for reboot, halt, or power off. 31717658Sjulian */ 318214004Smarcelvoid 319214004Smarcelkern_reboot(int howto) 32017658Sjulian{ 321285993Sjeff static int once = 0; 32217658Sjulian 323137375Smarcel#if defined(SMP) 324137329Snjl /* 325137329Snjl * Bind us to CPU 0 so that all shutdown code runs there. Some 326137329Snjl * systems don't shutdown properly (i.e., ACPI power off) if we 327137329Snjl * run on another processor. 328137329Snjl */ 329228424Savg if (!SCHEDULER_STOPPED()) { 330228424Savg thread_lock(curthread); 331228424Savg sched_bind(curthread, 0); 332228424Savg thread_unlock(curthread); 333228424Savg KASSERT(PCPU_GET(cpuid) == 0, ("boot: not running on cpu 0")); 334228424Savg } 335137263Speter#endif 336155383Sjeff /* We're in the process of rebooting. */ 337155383Sjeff rebooting = 1; 338137263Speter 33982119Sjhb /* We are out of the debugger now. */ 340131927Smarcel kdb_active = 0; 34182119Sjhb 34227997Sjulian /* 34327997Sjulian * Do any callouts that should be done BEFORE syncing the filesystems. 34427997Sjulian */ 34550107Smsmith EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); 34627997Sjulian 34727997Sjulian /* 34827997Sjulian * Now sync filesystems 34927997Sjulian */ 350285993Sjeff if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) { 351285993Sjeff once = 1; 352285993Sjeff bufshutdown(show_busybufs); 35317658Sjulian } 35427997Sjulian 35554233Sphk print_uptime(); 35654233Sphk 357228632Savg cngrab(); 358228632Savg 35927997Sjulian /* 36027997Sjulian * Ok, now do things that assume all filesystem activity has 36127997Sjulian * been completed. 36227997Sjulian */ 36350107Smsmith EVENTHANDLER_INVOKE(shutdown_post_sync, howto); 364137329Snjl 365132412Sjulian if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) 366222801Smarcel doadump(TRUE); 36739237Sgibbs 36839237Sgibbs /* Now that we're going to really halt the system... */ 36950107Smsmith EVENTHANDLER_INVOKE(shutdown_final, howto); 37039237Sgibbs 37150107Smsmith for(;;) ; /* safety against shutdown_reset not working */ 37250107Smsmith /* NOTREACHED */ 37350107Smsmith} 37450107Smsmith 37550107Smsmith/* 376287964Strasz * The system call that results in changing the rootfs. 377287964Strasz */ 378287964Straszstatic int 379287964Straszkern_reroot(void) 380287964Strasz{ 381287964Strasz struct vnode *oldrootvnode, *vp; 382287964Strasz struct mount *mp, *devmp; 383287964Strasz int error; 384287964Strasz 385287964Strasz if (curproc != initproc) 386287964Strasz return (EPERM); 387287964Strasz 388287964Strasz /* 389287964Strasz * Mark the filesystem containing currently-running executable 390287964Strasz * (the temporary copy of init(8)) busy. 391287964Strasz */ 392287964Strasz vp = curproc->p_textvp; 393287964Strasz error = vn_lock(vp, LK_SHARED); 394287964Strasz if (error != 0) 395287964Strasz return (error); 396287964Strasz mp = vp->v_mount; 397287964Strasz error = vfs_busy(mp, MBF_NOWAIT); 398287964Strasz if (error != 0) { 399287964Strasz vfs_ref(mp); 400287964Strasz VOP_UNLOCK(vp, 0); 401287964Strasz error = vfs_busy(mp, 0); 402287964Strasz vn_lock(vp, LK_SHARED | LK_RETRY); 403287964Strasz vfs_rel(mp); 404287964Strasz if (error != 0) { 405287964Strasz VOP_UNLOCK(vp, 0); 406287964Strasz return (ENOENT); 407287964Strasz } 408287964Strasz if (vp->v_iflag & VI_DOOMED) { 409287964Strasz VOP_UNLOCK(vp, 0); 410287964Strasz vfs_unbusy(mp); 411287964Strasz return (ENOENT); 412287964Strasz } 413287964Strasz } 414287964Strasz VOP_UNLOCK(vp, 0); 415287964Strasz 416287964Strasz /* 417287964Strasz * Remove the filesystem containing currently-running executable 418287964Strasz * from the mount list, to prevent it from being unmounted 419287964Strasz * by vfs_unmountall(), and to avoid confusing vfs_mountroot(). 420287964Strasz * 421287964Strasz * Also preserve /dev - forcibly unmounting it could cause driver 422287964Strasz * reinitialization. 423287964Strasz */ 424287964Strasz 425287964Strasz vfs_ref(rootdevmp); 426287964Strasz devmp = rootdevmp; 427287964Strasz rootdevmp = NULL; 428287964Strasz 429287964Strasz mtx_lock(&mountlist_mtx); 430287964Strasz TAILQ_REMOVE(&mountlist, mp, mnt_list); 431287964Strasz TAILQ_REMOVE(&mountlist, devmp, mnt_list); 432287964Strasz mtx_unlock(&mountlist_mtx); 433287964Strasz 434287964Strasz oldrootvnode = rootvnode; 435287964Strasz 436287964Strasz /* 437287964Strasz * Unmount everything except for the two filesystems preserved above. 438287964Strasz */ 439287964Strasz vfs_unmountall(); 440287964Strasz 441287964Strasz /* 442287964Strasz * Add /dev back; vfs_mountroot() will move it into its new place. 443287964Strasz */ 444287964Strasz mtx_lock(&mountlist_mtx); 445287964Strasz TAILQ_INSERT_HEAD(&mountlist, devmp, mnt_list); 446287964Strasz mtx_unlock(&mountlist_mtx); 447287964Strasz rootdevmp = devmp; 448287964Strasz vfs_rel(rootdevmp); 449287964Strasz 450287964Strasz /* 451287964Strasz * Mount the new rootfs. 452287964Strasz */ 453287964Strasz vfs_mountroot(); 454287964Strasz 455287964Strasz /* 456287964Strasz * Update all references to the old rootvnode. 457287964Strasz */ 458287964Strasz mountcheckdirs(oldrootvnode, rootvnode); 459287964Strasz 460287964Strasz /* 461287964Strasz * Add the temporary filesystem back and unbusy it. 462287964Strasz */ 463287964Strasz mtx_lock(&mountlist_mtx); 464287964Strasz TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 465287964Strasz mtx_unlock(&mountlist_mtx); 466287964Strasz vfs_unbusy(mp); 467287964Strasz 468287964Strasz return (0); 469287964Strasz} 470287964Strasz 471287964Strasz/* 47250107Smsmith * If the shutdown was a clean halt, behave accordingly. 47350107Smsmith */ 47450107Smsmithstatic void 47550107Smsmithshutdown_halt(void *junk, int howto) 47650107Smsmith{ 477110859Salfred 47817658Sjulian if (howto & RB_HALT) { 47917658Sjulian printf("\n"); 48017658Sjulian printf("The operating system has halted.\n"); 48117658Sjulian printf("Please press any key to reboot.\n\n"); 48219274Sjulian switch (cngetc()) { 48319274Sjulian case -1: /* No console, just die */ 48419274Sjulian cpu_halt(); 48519274Sjulian /* NOTREACHED */ 48619274Sjulian default: 48739237Sgibbs howto &= ~RB_HALT; 48819274Sjulian break; 48919274Sjulian } 49050107Smsmith } 49150107Smsmith} 49217658Sjulian 49350107Smsmith/* 49450107Smsmith * Check to see if the system paniced, pause and then reboot 49550107Smsmith * according to the specified delay. 49650107Smsmith */ 49750107Smsmithstatic void 49850107Smsmithshutdown_panic(void *junk, int howto) 49950107Smsmith{ 50050107Smsmith int loop; 50150107Smsmith 50250107Smsmith if (howto & RB_DUMP) { 503258893Scperciva if (panic_reboot_wait_time != 0) { 504258893Scperciva if (panic_reboot_wait_time != -1) { 50539237Sgibbs printf("Automatic reboot in %d seconds - " 50639237Sgibbs "press a key on the console to abort\n", 507258893Scperciva panic_reboot_wait_time); 508258893Scperciva for (loop = panic_reboot_wait_time * 10; 50939237Sgibbs loop > 0; --loop) { 51039237Sgibbs DELAY(1000 * 100); /* 1/10th second */ 51139237Sgibbs /* Did user type a key? */ 51239237Sgibbs if (cncheckc() != -1) 51339237Sgibbs break; 51417658Sjulian } 51539237Sgibbs if (!loop) 51650107Smsmith return; 51717658Sjulian } 51839237Sgibbs } else { /* zero time specified - reboot NOW */ 51950107Smsmith return; 52017658Sjulian } 52189522Snik printf("--> Press a key on the console to reboot,\n"); 52289522Snik printf("--> or switch off the system now.\n"); 52339237Sgibbs cngetc(); 52417658Sjulian } 52550107Smsmith} 52650107Smsmith 52750107Smsmith/* 52850107Smsmith * Everything done, now reset 52950107Smsmith */ 53050107Smsmithstatic void 53150107Smsmithshutdown_reset(void *junk, int howto) 53250107Smsmith{ 533110859Salfred 534206878Sattilio printf("Rebooting...\n"); 535206878Sattilio DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 536206878Sattilio 537196196Sattilio /* 538206878Sattilio * Acquiring smp_ipi_mtx here has a double effect: 539206878Sattilio * - it disables interrupts avoiding CPU0 preemption 540206878Sattilio * by fast handlers (thus deadlocking against other CPUs) 541206878Sattilio * - it avoids deadlocks against smp_rendezvous() or, more 542206878Sattilio * generally, threads busy-waiting, with this spinlock held, 543206878Sattilio * and waiting for responses by threads on other CPUs 544206878Sattilio * (ie. smp_tlb_shootdown()). 545206897Sattilio * 546206897Sattilio * For the !SMP case it just needs to handle the former problem. 547196196Sattilio */ 548206897Sattilio#ifdef SMP 549206878Sattilio mtx_lock_spin(&smp_ipi_mtx); 550206897Sattilio#else 551206897Sattilio spinlock_enter(); 552206897Sattilio#endif 553196196Sattilio 55417677Sjulian /* cpu_boot(howto); */ /* doesn't do anything at the moment */ 55517658Sjulian cpu_reset(); 55650107Smsmith /* NOTREACHED */ /* assuming reset worked */ 55717658Sjulian} 55817658Sjulian 559302349Sglebius#if defined(WITNESS) || defined(INVARIANT_SUPPORT) 560243980Salfredstatic int kassert_warn_only = 0; 561244099Salfred#ifdef KDB 562244099Salfredstatic int kassert_do_kdb = 0; 563244099Salfred#endif 564243980Salfred#ifdef KTR 565243980Salfredstatic int kassert_do_ktr = 0; 566243980Salfred#endif 567243980Salfredstatic int kassert_do_log = 1; 568243980Salfredstatic int kassert_log_pps_limit = 4; 569243980Salfredstatic int kassert_log_mute_at = 0; 570243980Salfredstatic int kassert_log_panic_at = 0; 571243980Salfredstatic int kassert_warnings = 0; 572243980Salfred 573243980SalfredSYSCTL_NODE(_debug, OID_AUTO, kassert, CTLFLAG_RW, NULL, "kassert options"); 574243980Salfred 575267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, warn_only, CTLFLAG_RWTUN, 576243980Salfred &kassert_warn_only, 0, 577243980Salfred "KASSERT triggers a panic (1) or just a warning (0)"); 578243980Salfred 579244099Salfred#ifdef KDB 580267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, do_kdb, CTLFLAG_RWTUN, 581244099Salfred &kassert_do_kdb, 0, "KASSERT will enter the debugger"); 582244099Salfred#endif 583244099Salfred 584243980Salfred#ifdef KTR 585267992ShselaskySYSCTL_UINT(_debug_kassert, OID_AUTO, do_ktr, CTLFLAG_RWTUN, 586243980Salfred &kassert_do_ktr, 0, 587243980Salfred "KASSERT does a KTR, set this to the KTRMASK you want"); 588243980Salfred#endif 589243980Salfred 590267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, do_log, CTLFLAG_RWTUN, 591243980Salfred &kassert_do_log, 0, "KASSERT triggers a panic (1) or just a warning (0)"); 592243980Salfred 593267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, warnings, CTLFLAG_RWTUN, 594243980Salfred &kassert_warnings, 0, "number of KASSERTs that have been triggered"); 595243980Salfred 596267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, log_panic_at, CTLFLAG_RWTUN, 597243980Salfred &kassert_log_panic_at, 0, "max number of KASSERTS before we will panic"); 598243980Salfred 599267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, log_pps_limit, CTLFLAG_RWTUN, 600243980Salfred &kassert_log_pps_limit, 0, "limit number of log messages per second"); 601243980Salfred 602267992ShselaskySYSCTL_INT(_debug_kassert, OID_AUTO, log_mute_at, CTLFLAG_RWTUN, 603243980Salfred &kassert_log_mute_at, 0, "max number of KASSERTS to log"); 604243980Salfred 605243980Salfredstatic int kassert_sysctl_kassert(SYSCTL_HANDLER_ARGS); 606243980Salfred 607243980SalfredSYSCTL_PROC(_debug_kassert, OID_AUTO, kassert, 608243980Salfred CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0, 609243980Salfred kassert_sysctl_kassert, "I", "set to trigger a test kassert"); 610243980Salfred 611243980Salfredstatic int 612243980Salfredkassert_sysctl_kassert(SYSCTL_HANDLER_ARGS) 613243980Salfred{ 614243980Salfred int error, i; 615243980Salfred 616243980Salfred error = sysctl_wire_old_buffer(req, sizeof(int)); 617243980Salfred if (error == 0) { 618243980Salfred i = 0; 619243980Salfred error = sysctl_handle_int(oidp, &i, 0, req); 620243980Salfred } 621243980Salfred if (error != 0 || req->newptr == NULL) 622243980Salfred return (error); 623243980Salfred KASSERT(0, ("kassert_sysctl_kassert triggered kassert %d", i)); 624243980Salfred return (0); 625243980Salfred} 626243980Salfred 62717658Sjulian/* 628243980Salfred * Called by KASSERT, this decides if we will panic 629243980Salfred * or if we will log via printf and/or ktr. 630243980Salfred */ 631243980Salfredvoid 632243980Salfredkassert_panic(const char *fmt, ...) 633243980Salfred{ 634243980Salfred static char buf[256]; 635243980Salfred va_list ap; 636243980Salfred 637243980Salfred va_start(ap, fmt); 638243980Salfred (void)vsnprintf(buf, sizeof(buf), fmt, ap); 639243980Salfred va_end(ap); 640243980Salfred 641243980Salfred /* 642243980Salfred * panic if we're not just warning, or if we've exceeded 643243980Salfred * kassert_log_panic_at warnings. 644243980Salfred */ 645243980Salfred if (!kassert_warn_only || 646243980Salfred (kassert_log_panic_at > 0 && 647243980Salfred kassert_warnings >= kassert_log_panic_at)) { 648243980Salfred va_start(ap, fmt); 649243980Salfred vpanic(fmt, ap); 650243980Salfred /* NORETURN */ 651243980Salfred } 652243980Salfred#ifdef KTR 653243980Salfred if (kassert_do_ktr) 654243980Salfred CTR0(ktr_mask, buf); 655243980Salfred#endif /* KTR */ 656243980Salfred /* 657243980Salfred * log if we've not yet met the mute limit. 658243980Salfred */ 659243980Salfred if (kassert_do_log && 660243980Salfred (kassert_log_mute_at == 0 || 661243980Salfred kassert_warnings < kassert_log_mute_at)) { 662243980Salfred static struct timeval lasterr; 663243980Salfred static int curerr; 664243980Salfred 665243980Salfred if (ppsratecheck(&lasterr, &curerr, kassert_log_pps_limit)) { 666243980Salfred printf("KASSERT failed: %s\n", buf); 667243980Salfred kdb_backtrace(); 668243980Salfred } 669243980Salfred } 670244099Salfred#ifdef KDB 671244099Salfred if (kassert_do_kdb) { 672244099Salfred kdb_enter(KDB_WHY_KASSERT, buf); 673244099Salfred } 674244099Salfred#endif 675243980Salfred atomic_add_int(&kassert_warnings, 1); 676243980Salfred} 677243980Salfred#endif 678243980Salfred 679243980Salfred/* 68017658Sjulian * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 68117658Sjulian * and then reboots. If we are called twice, then we avoid trying to sync 68217658Sjulian * the disks as this often leads to recursive panics. 68317658Sjulian */ 68417658Sjulianvoid 685130164Sphkpanic(const char *fmt, ...) 68617658Sjulian{ 687243980Salfred va_list ap; 688243980Salfred 689243980Salfred va_start(ap, fmt); 690243980Salfred vpanic(fmt, ap); 691243980Salfred} 692243980Salfred 693281915Smarkjvoid 694243980Salfredvpanic(const char *fmt, va_list ap) 695243980Salfred{ 696213648Savg#ifdef SMP 697228424Savg cpuset_t other_cpus; 698213648Savg#endif 699100209Sgallatin struct thread *td = curthread; 700103647Sjhb int bootopt, newpanic; 70138874Sache static char buf[256]; 70217658Sjulian 703243515Savg spinlock_enter(); 704228424Savg 70565557Sjasone#ifdef SMP 70682115Sjhb /* 707243515Savg * stop_cpus_hard(other_cpus) should prevent multiple CPUs from 708243515Savg * concurrently entering panic. Only the winner will proceed 709243515Savg * further. 71082115Sjhb */ 711243515Savg if (panicstr == NULL && !kdb_active) { 712243515Savg other_cpus = all_cpus; 713243515Savg CPU_CLR(PCPU_GET(cpuid), &other_cpus); 714243515Savg stop_cpus_hard(other_cpus); 715243515Savg } 716228424Savg 717243515Savg /* 718282332Smarkj * Ensure that the scheduler is stopped while panicking, even if panic 719282332Smarkj * has been entered from kdb. 720243515Savg */ 721243515Savg td->td_stopsched = 1; 72265557Sjasone#endif 72365557Sjasone 724222865Sattilio bootopt = RB_AUTOBOOT; 725103647Sjhb newpanic = 0; 72617658Sjulian if (panicstr) 72717658Sjulian bootopt |= RB_NOSYNC; 728103647Sjhb else { 729222865Sattilio bootopt |= RB_DUMP; 73017658Sjulian panicstr = fmt; 731103647Sjhb newpanic = 1; 732103647Sjhb } 73317658Sjulian 734116398Siedowse if (newpanic) { 735116398Siedowse (void)vsnprintf(buf, sizeof(buf), fmt, ap); 73638874Sache panicstr = buf; 737228632Savg cngrab(); 738130164Sphk printf("panic: %s\n", buf); 739116398Siedowse } else { 740116398Siedowse printf("panic: "); 741116398Siedowse vprintf(fmt, ap); 742130164Sphk printf("\n"); 743116398Siedowse } 74426100Sfsmp#ifdef SMP 745134089Sjhb printf("cpuid = %d\n", PCPU_GET(cpuid)); 74626100Sfsmp#endif 74717658Sjulian 748131927Smarcel#ifdef KDB 749103647Sjhb if (newpanic && trace_on_panic) 750131927Smarcel kdb_backtrace(); 75117658Sjulian if (debugger_on_panic) 752174898Srwatson kdb_enter(KDB_WHY_PANIC, "panic"); 75317658Sjulian#endif 754170307Sjeff /*thread_lock(td); */ 755100209Sgallatin td->td_flags |= TDF_INPANIC; 756170307Sjeff /* thread_unlock(td); */ 75785202Speter if (!sync_on_panic) 75885202Speter bootopt |= RB_NOSYNC; 759214004Smarcel kern_reboot(bootopt); 76017658Sjulian} 76117658Sjulian 76217768Sjulian/* 76343436Smsmith * Support for poweroff delay. 764197071Sn_hibma * 765197071Sn_hibma * Please note that setting this delay too short might power off your machine 766197071Sn_hibma * before the write cache on your hard disk has been flushed, leading to 767197071Sn_hibma * soft-updates inconsistencies. 76843436Smsmith */ 76954248Smsmith#ifndef POWEROFF_DELAY 77054248Smsmith# define POWEROFF_DELAY 5000 77154248Smsmith#endif 77254248Smsmithstatic int poweroff_delay = POWEROFF_DELAY; 77354248Smsmith 77443436SmsmithSYSCTL_INT(_kern_shutdown, OID_AUTO, poweroff_delay, CTLFLAG_RW, 775228449Seadler &poweroff_delay, 0, "Delay before poweroff to write disk caches (msec)"); 77643436Smsmith 777110859Salfredstatic void 77850107Smsmithpoweroff_wait(void *junk, int howto) 77943436Smsmith{ 780110859Salfred 781110859Salfred if (!(howto & RB_POWEROFF) || poweroff_delay <= 0) 78243436Smsmith return; 78343436Smsmith DELAY(poweroff_delay * 1000); 78443436Smsmith} 78555539Sluoqi 78655539Sluoqi/* 78755539Sluoqi * Some system processes (e.g. syncer) need to be stopped at appropriate 78855539Sluoqi * points in their main loops prior to a system shutdown, so that they 78955539Sluoqi * won't interfere with the shutdown process (e.g. by holding a disk buf 79055539Sluoqi * to cause sync to fail). For each of these system processes, register 79155539Sluoqi * shutdown_kproc() as a handler for one of shutdown events. 79255539Sluoqi */ 79355539Sluoqistatic int kproc_shutdown_wait = 60; 79455539SluoqiSYSCTL_INT(_kern_shutdown, OID_AUTO, kproc_shutdown_wait, CTLFLAG_RW, 795228449Seadler &kproc_shutdown_wait, 0, "Max wait time (sec) to stop for each process"); 79655539Sluoqi 79755539Sluoqivoid 79870063Sjhbkproc_shutdown(void *arg, int howto) 79955539Sluoqi{ 80055539Sluoqi struct proc *p; 80155539Sluoqi int error; 80255539Sluoqi 80355539Sluoqi if (panicstr) 80455539Sluoqi return; 80555539Sluoqi 80655539Sluoqi p = (struct proc *)arg; 807301040Strasz printf("Waiting (max %d seconds) for system process `%s' to stop... ", 808198408Sjhb kproc_shutdown_wait, p->p_comm); 809172836Sjulian error = kproc_suspend(p, kproc_shutdown_wait * hz); 81055539Sluoqi 81155539Sluoqi if (error == EWOULDBLOCK) 812132866Snjl printf("timed out\n"); 81355539Sluoqi else 814132866Snjl printf("done\n"); 81555539Sluoqi} 81693496Sphk 817173004Sjulianvoid 818173004Sjuliankthread_shutdown(void *arg, int howto) 819173004Sjulian{ 820173004Sjulian struct thread *td; 821173004Sjulian int error; 822173004Sjulian 823173004Sjulian if (panicstr) 824173004Sjulian return; 825173004Sjulian 826173004Sjulian td = (struct thread *)arg; 827301040Strasz printf("Waiting (max %d seconds) for system thread `%s' to stop... ", 828198408Sjhb kproc_shutdown_wait, td->td_name); 829173004Sjulian error = kthread_suspend(td, kproc_shutdown_wait * hz); 830173004Sjulian 831173004Sjulian if (error == EWOULDBLOCK) 832173004Sjulian printf("timed out\n"); 833173004Sjulian else 834173004Sjulian printf("done\n"); 835173004Sjulian} 836173004Sjulian 837242439Salfredstatic char dumpdevname[sizeof(((struct cdev*)NULL)->si_name)]; 838242439SalfredSYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD, 839242439Salfred dumpdevname, 0, "Device for kernel dumps"); 840242439Salfred 84193496Sphk/* Registration of dumpers */ 84293496Sphkint 843274366Spjdset_dumper(struct dumperinfo *di, const char *devname, struct thread *td) 84493496Sphk{ 845242489Salfred size_t wantcopy; 846274366Spjd int error; 847110859Salfred 848274366Spjd error = priv_check(td, PRIV_SETDUMPER); 849274366Spjd if (error != 0) 850274366Spjd return (error); 851274366Spjd 85293496Sphk if (di == NULL) { 853298076Scem if (dumper.blockbuf != NULL) 854298076Scem free(dumper.blockbuf, M_DUMPER); 855298076Scem bzero(&dumper, sizeof(dumper)); 856242439Salfred dumpdevname[0] = '\0'; 85793496Sphk return (0); 85893496Sphk } 85993496Sphk if (dumper.dumper != NULL) 86093496Sphk return (EBUSY); 86193496Sphk dumper = *di; 862242489Salfred wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname)); 863242489Salfred if (wantcopy >= sizeof(dumpdevname)) { 864242439Salfred printf("set_dumper: device name truncated from '%s' -> '%s'\n", 865242439Salfred devname, dumpdevname); 866242439Salfred } 867298076Scem dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO); 86893496Sphk return (0); 86993496Sphk} 87093496Sphk 871175768Sru/* Call dumper with bounds checking. */ 872175768Sruint 873175768Srudump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, 874175768Sru off_t offset, size_t length) 875175768Sru{ 876175768Sru 877175768Sru if (length != 0 && (offset < di->mediaoffset || 878175768Sru offset - di->mediaoffset + length > di->mediasize)) { 879225516Sattilio printf("Attempt to write outside dump device boundaries.\n" 880225516Sattilio "offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n", 881225516Sattilio (intmax_t)offset, (intmax_t)di->mediaoffset, 882225516Sattilio (uintmax_t)length, (intmax_t)di->mediasize); 883225516Sattilio return (ENOSPC); 884175768Sru } 885175768Sru return (di->dumper(di->priv, virtual, physical, offset, length)); 886175768Sru} 887175768Sru 888298076Scem/* Call dumper with bounds checking. */ 889298076Scemint 890298076Scemdump_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical, 891298076Scem off_t offset, size_t length, size_t *size) 892298076Scem{ 893298076Scem char *temp; 894298076Scem int ret; 895298076Scem 896298076Scem if (length > di->blocksize) 897298076Scem return (ENOMEM); 898298076Scem 899298076Scem *size = di->blocksize; 900298076Scem if (length == di->blocksize) 901298076Scem temp = virtual; 902298076Scem else { 903298076Scem temp = di->blockbuf; 904298076Scem memset(temp + length, 0, di->blocksize - length); 905298076Scem memcpy(temp, virtual, length); 906298076Scem } 907298076Scem ret = dump_write(di, temp, physical, offset, *size); 908298076Scem 909298076Scem return (ret); 910298076Scem} 911298076Scem 912298076Scem 91393496Sphkvoid 914183527Spetermkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, 915183527Speter uint64_t dumplen, uint32_t blksz) 916183527Speter{ 917183527Speter 918183527Speter bzero(kdh, sizeof(*kdh)); 919283115Sasomers strlcpy(kdh->magic, magic, sizeof(kdh->magic)); 920283115Sasomers strlcpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture)); 921183527Speter kdh->version = htod32(KERNELDUMPVERSION); 922183527Speter kdh->architectureversion = htod32(archver); 923183527Speter kdh->dumplength = htod64(dumplen); 924183527Speter kdh->dumptime = htod64(time_second); 925183527Speter kdh->blocksize = htod32(blksz); 926283115Sasomers strlcpy(kdh->hostname, prison0.pr_hostname, sizeof(kdh->hostname)); 927283115Sasomers strlcpy(kdh->versionstring, version, sizeof(kdh->versionstring)); 928183527Speter if (panicstr != NULL) 929283115Sasomers strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); 930183527Speter kdh->parity = kerneldump_parity(kdh); 931183527Speter} 932301522Sbz 933301522Sbz#ifdef DDB 934301522SbzDB_SHOW_COMMAND(panic, db_show_panic) 935301522Sbz{ 936301522Sbz 937301522Sbz if (panicstr == NULL) 938301522Sbz db_printf("panicstr not set\n"); 939301522Sbz else 940301522Sbz db_printf("panic: %s\n", panicstr); 941301522Sbz} 942301522Sbz#endif 943