1/*- 2 * Copyright (c) 1986, 1988, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94
|
40 */ 41 42#include "opt_ddb.h" 43#include "opt_hw_wdog.h" 44#include "opt_panic.h" 45#include "opt_show_busybufs.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/buf.h> 50#include <sys/reboot.h> 51#include <sys/proc.h> 52#include <sys/vnode.h> 53#include <sys/malloc.h> 54#include <sys/kernel.h> 55#include <sys/mount.h> 56#include <sys/queue.h> 57#include <sys/sysctl.h> 58#include <sys/conf.h> 59#include <sys/sysproto.h> 60 61#include <machine/pcb.h> 62#include <machine/clock.h> 63#include <machine/cons.h> 64#include <machine/md_var.h> 65#ifdef SMP 66#include <machine/smp.h> /* smp_active, cpuid */ 67#endif 68 69#include <sys/signalvar.h> 70 71#ifndef PANIC_REBOOT_WAIT_TIME 72#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ 73#endif 74 75/* 76 * Note that stdarg.h and the ANSI style va_start macro is used for both 77 * ANSI and traditional C compilers. 78 */ 79#include <machine/stdarg.h> 80 81#ifdef DDB 82#ifdef DDB_UNATTENDED 83int debugger_on_panic = 0; 84#else 85int debugger_on_panic = 1; 86#endif 87SYSCTL_INT(_debug, OID_AUTO, debugger_on_panic, CTLFLAG_RW, 88 &debugger_on_panic, 0, "Run debugger on kernel panic"); 89#endif 90 91SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW, 0, "Shutdown environment"); 92 93#ifdef HW_WDOG 94/* 95 * If there is a hardware watchdog, point this at the function needed to 96 * hold it off. 97 * It's needed when the kernel needs to do some lengthy operations. 98 * e.g. in wd.c when dumping core.. It's most annoying to have 99 * your precious core-dump only half written because the wdog kicked in. 100 */ 101watchdog_tickle_fn wdog_tickler = NULL; 102#endif /* HW_WDOG */ 103 104/* 105 * Variable panicstr contains argument to first call to panic; used as flag 106 * to indicate that the kernel has already called panic. 107 */ 108const char *panicstr; 109 110/* 111 * callout list for things to do a shutdown 112 */ 113typedef struct shutdown_list_element { 114 LIST_ENTRY(shutdown_list_element) links; 115 bootlist_fn function; 116 void *arg; 117 int priority; 118} *sle_p; 119 120/* 121 * There are three shutdown lists. Some things need to be shut down 122 * earlier than others. 123 */ 124LIST_HEAD(shutdown_list, shutdown_list_element); 125 126static struct shutdown_list shutdown_lists[SHUTDOWN_FINAL + 1]; 127 128static void boot __P((int)) __dead2; 129static void dumpsys __P((void)); 130 131#ifndef _SYS_SYSPROTO_H_ 132struct reboot_args { 133 int opt; 134}; 135#endif 136/* ARGSUSED */ 137 138/* 139 * The system call that results in a reboot 140 */ 141int 142reboot(p, uap) 143 struct proc *p; 144 struct reboot_args *uap; 145{ 146 int error; 147 148 if ((error = suser(p))) 149 return (error); 150 151 boot(uap->opt); 152 return (0); 153} 154 155/* 156 * Called by events that want to shut down.. e.g <CTL><ALT><DEL> on a PC 157 */ 158void 159shutdown_nice() 160{ 161 /* Send a signal to init(8) and have it shutdown the world */ 162 if (initproc != NULL) { 163 psignal(initproc, SIGINT); 164 } else { 165 /* No init(8) running, so simply reboot */ 166 boot(RB_NOSYNC); 167 } 168 return; 169} 170static int waittime = -1; 171static struct pcb dumppcb; 172 173/* 174 * Go through the rigmarole of shutting down.. 175 * this used to be in machdep.c but I'll be dammned if I could see 176 * anything machine dependant in it. 177 */ 178static void 179boot(howto) 180 int howto; 181{ 182 sle_p ep; 183 184#ifdef SMP 185 if (smp_active) { 186 printf("boot() called on cpu#%d\n", cpuid); 187 } 188#endif 189 /* 190 * Do any callouts that should be done BEFORE syncing the filesystems. 191 */ 192 LIST_FOREACH(ep, &shutdown_lists[SHUTDOWN_PRE_SYNC], links) 193 (*ep->function)(howto, ep->arg); 194 195 /* 196 * Now sync filesystems 197 */ 198 if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) { 199 register struct buf *bp; 200 int iter, nbusy; 201 202 waittime = 0; 203 printf("\nsyncing disks... "); 204 205 sync(&proc0, NULL); 206 207 /* 208 * With soft updates, some buffers that are 209 * written will be remarked as dirty until other 210 * buffers are written. 211 */ 212 for (iter = 0; iter < 20; iter++) { 213 nbusy = 0; 214 for (bp = &buf[nbuf]; --bp >= buf; ) { 215 if ((bp->b_flags & (B_BUSY | B_INVAL)) 216 == B_BUSY) { 217 nbusy++; 218 } else if ((bp->b_flags & (B_DELWRI | B_INVAL)) 219 == B_DELWRI) { 220 /* bawrite(bp);*/ 221 nbusy++; 222 } 223 } 224 if (nbusy == 0) 225 break; 226 printf("%d ", nbusy); 227 sync(&proc0, NULL); 228 DELAY(50000 * iter); 229 } 230 /* 231 * Count only busy local buffers to prevent forcing 232 * a fsck if we're just a client of a wedged NFS server 233 */ 234 nbusy = 0; 235 for (bp = &buf[nbuf]; --bp >= buf; ) {
|
243 244 245 } 246 if (nbusy) { 247 /* 248 * Failed to sync all blocks. Indicate this and don't 249 * unmount filesystems (thus forcing an fsck on reboot). 250 */ 251 printf("giving up\n"); 252#ifdef SHOW_BUSYBUFS 253 nbusy = 0; 254 for (bp = &buf[nbuf]; --bp >= buf; ) { 255 if ((bp->b_flags & (B_BUSY | B_INVAL)) 256 == B_BUSY) { 257 nbusy++; 258 printf( 259 "%d: dev:%08lx, flags:%08lx, blkno:%ld, lblkno:%ld\n", 260 nbusy, (u_long)bp->b_dev, 261 bp->b_flags, (long)bp->b_blkno, 262 (long)bp->b_lblkno); 263 } 264 } 265 DELAY(5000000); /* 5 seconds */ 266#endif 267 } else { 268 printf("done\n"); 269 /* 270 * Unmount filesystems 271 */ 272 if (panicstr == 0) 273 vfs_unmountall(); 274 } 275 DELAY(100000); /* wait for console output to finish */ 276 } 277 278 /* 279 * Ok, now do things that assume all filesystem activity has 280 * been completed. 281 */ 282 LIST_FOREACH(ep, &shutdown_lists[SHUTDOWN_POST_SYNC], links) 283 (*ep->function)(howto, ep->arg); 284 splhigh(); 285 if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold) { 286 savectx(&dumppcb); 287#ifdef __i386__ 288 dumppcb.pcb_cr3 = rcr3(); 289#endif 290 dumpsys(); 291 } 292 293 /* Now that we're going to really halt the system... */ 294 LIST_FOREACH(ep, &shutdown_lists[SHUTDOWN_FINAL], links) 295 (*ep->function)(howto, ep->arg); 296 297 if (howto & RB_HALT) { 298 printf("\n"); 299 printf("The operating system has halted.\n"); 300 printf("Please press any key to reboot.\n\n"); 301 switch (cngetc()) { 302 case -1: /* No console, just die */ 303 cpu_halt(); 304 /* NOTREACHED */ 305 default: 306 howto &= ~RB_HALT; 307 break; 308 } 309 } else if (howto & RB_DUMP) { 310 /* System Paniced */ 311 312 if (PANIC_REBOOT_WAIT_TIME != 0) { 313 if (PANIC_REBOOT_WAIT_TIME != -1) { 314 int loop; 315 printf("Automatic reboot in %d seconds - " 316 "press a key on the console to abort\n", 317 PANIC_REBOOT_WAIT_TIME); 318 for (loop = PANIC_REBOOT_WAIT_TIME * 10; 319 loop > 0; --loop) { 320 DELAY(1000 * 100); /* 1/10th second */ 321 /* Did user type a key? */ 322 if (cncheckc() != -1) 323 break; 324 } 325 if (!loop) 326 goto die; 327 } 328 } else { /* zero time specified - reboot NOW */ 329 goto die; 330 } 331 printf("--> Press a key on the console to reboot <--\n"); 332 cngetc(); 333 } 334die: 335 printf("Rebooting...\n"); 336 DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 337 /* cpu_boot(howto); */ /* doesn't do anything at the moment */ 338 cpu_reset(); 339 for(;;) ; 340 /* NOTREACHED */ 341} 342 343/* 344 * Magic number for savecore 345 * 346 * exported (symorder) and used at least by savecore(8) 347 * 348 */ 349static u_long const dumpmag = 0x8fca0101UL; 350 351static int dumpsize = 0; /* also for savecore */ 352 353static int dodump = 1; 354SYSCTL_INT(_machdep, OID_AUTO, do_dump, CTLFLAG_RW, 355 &dodump, 0, "Do coredump on kernel panic"); 356 357/* ARGSUSED */ 358static void dump_conf __P((void *dummy)); 359static void 360dump_conf(dummy) 361 void *dummy; 362{ 363 cpu_dumpconf(); 364} 365SYSINIT(dump_conf, SI_SUB_DUMP_CONF, SI_ORDER_FIRST, dump_conf, NULL) 366 367/* 368 * Doadump comes here after turning off memory management and 369 * getting on the dump stack, either when called above, or by 370 * the auto-restart code. 371 */ 372static void 373dumpsys(void) 374{ 375 376 if (!dodump) 377 return; 378 if (dumpdev == NODEV) 379 return; 380 if (!(bdevsw[major(dumpdev)])) 381 return; 382 if (!(bdevsw[major(dumpdev)]->d_dump)) 383 return; 384 dumpsize = Maxmem; 385 printf("\ndumping to dev %lx, offset %ld\n", (u_long)dumpdev, dumplo); 386 printf("dump "); 387 switch ((*bdevsw[major(dumpdev)]->d_dump)(dumpdev)) { 388 389 case ENXIO: 390 printf("device bad\n"); 391 break; 392 393 case EFAULT: 394 printf("device not ready\n"); 395 break; 396 397 case EINVAL: 398 printf("area improper\n"); 399 break; 400 401 case EIO: 402 printf("i/o error\n"); 403 break; 404 405 case EINTR: 406 printf("aborted from console\n"); 407 break; 408 409 default: 410 printf("succeeded\n"); 411 break; 412 } 413} 414 415/* 416 * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 417 * and then reboots. If we are called twice, then we avoid trying to sync 418 * the disks as this often leads to recursive panics. 419 */ 420void 421panic(const char *fmt, ...) 422{ 423 int bootopt; 424 va_list ap; 425 static char buf[256]; 426 427 bootopt = RB_AUTOBOOT | RB_DUMP; 428 if (panicstr) 429 bootopt |= RB_NOSYNC; 430 else 431 panicstr = fmt; 432 433 va_start(ap, fmt); 434 (void)vsnprintf(buf, sizeof(buf), fmt, ap); 435 if (panicstr == fmt) 436 panicstr = buf; 437 va_end(ap); 438 printf("panic: %s\n", buf); 439#ifdef SMP 440 /* three seperate prints in case of an unmapped page and trap */ 441 printf("mp_lock = %08x; ", mp_lock); 442 printf("cpuid = %d; ", cpuid); 443 printf("lapic.id = %08x\n", lapic.id); 444#endif 445 446#if defined(DDB) 447 if (debugger_on_panic) 448 Debugger ("panic"); 449#endif 450 boot(bootopt); 451} 452 453/* 454 * Three routines to handle adding/deleting items on the 455 * shutdown callout lists 456 * 457 * at_shutdown(): 458 * Take the arguments given and put them onto the shutdown callout list. 459 * However first make sure that it's not already there. 460 * returns 0 on success. 461 */ 462int 463at_shutdown(bootlist_fn function, void *arg, int queue) 464{ 465 return(at_shutdown_pri(function, arg, queue, SHUTDOWN_PRI_DEFAULT)); 466} 467 468/* 469 * at_shutdown_pri(): 470 * Take the arguments given and put them onto the shutdown callout list 471 * with the given execution priority. 472 * returns 0 on success. 473 */ 474int 475at_shutdown_pri(bootlist_fn function, void *arg, int queue, int pri) 476{ 477 sle_p op, ep, ip; 478 479 if (queue < SHUTDOWN_PRE_SYNC 480 || queue > SHUTDOWN_FINAL) { 481 printf("at_shutdown: bad exit callout queue %d specified\n", 482 queue); 483 return (EINVAL); 484 } 485 if (rm_at_shutdown(function, arg)) 486 printf("at_shutdown: exit callout entry was already present\n"); 487 ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT); 488 if (ep == NULL) 489 return (ENOMEM); 490 ep->function = function; 491 ep->arg = arg; 492 ep->priority = pri; 493 494 /* Sort into list of items on this queue */ 495 ip = LIST_FIRST(&shutdown_lists[queue]); 496 if (ip == NULL) { 497 LIST_INSERT_HEAD(&shutdown_lists[queue], ep, links); 498 } else { 499 for (; ip != NULL; op = ip, ip = LIST_NEXT(ip, links)) { 500 if (ep->priority < ip->priority) { 501 LIST_INSERT_BEFORE(ip, ep, links); 502 ep = NULL; 503 break; 504 } 505 } 506 if (ep != NULL) 507 LIST_INSERT_AFTER(op, ep, links); 508 } 509 return (0); 510} 511 512/* 513 * Scan the exit callout lists for the given items and remove them. 514 * Returns the number of items removed. 515 */ 516int 517rm_at_shutdown(bootlist_fn function, void *arg) 518{ 519 sle_p ep; 520 int count; 521 int queue; 522 523 count = 0; 524 for (queue = SHUTDOWN_PRE_SYNC; queue < SHUTDOWN_FINAL; queue++) { 525 LIST_FOREACH(ep, &shutdown_lists[queue], links) { 526 if ((ep->function == function) && (ep->arg == arg)) { 527 LIST_REMOVE(ep, links); 528 free(ep, M_TEMP); 529 count++; 530 } 531 } 532 } 533 return (count); 534} 535 536/* 537 * Support for poweroff delay. 538 */ 539static int poweroff_delay = 0; 540SYSCTL_INT(_kern_shutdown, OID_AUTO, poweroff_delay, CTLFLAG_RW, 541 &poweroff_delay, 0, ""); 542 543static void poweroff_wait(int howto, void *unused) 544{ 545 if(!(howto & RB_POWEROFF) || poweroff_delay <= 0) 546 return; 547 DELAY(poweroff_delay * 1000); 548} 549 550/* 551 * XXX OK? This implies I know SHUTDOWN_PRI_LAST > SHUTDOWN_PRI_FIRST 552 */ 553static void poweroff_conf(void *unused) 554{ 555 at_shutdown_pri(poweroff_wait, NULL, SHUTDOWN_FINAL, SHUTDOWN_PRI_FIRST); 556} 557 558SYSINIT(poweroff_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, poweroff_conf, NULL)
|