kern_shutdown.c (93467) | kern_shutdown.c (93496) |
---|---|
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. --- 22 unchanged lines hidden (view full) --- 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 | 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. --- 22 unchanged lines hidden (view full) --- 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 |
39 * $FreeBSD: head/sys/kern/kern_shutdown.c 93467 2002-03-31 07:15:28Z phk $ | 39 * $FreeBSD: head/sys/kern/kern_shutdown.c 93496 2002-03-31 22:37:00Z phk $ |
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> --- 11 unchanged lines hidden (view full) --- 59#include <sys/proc.h> 60#include <sys/reboot.h> 61#include <sys/resourcevar.h> 62#include <sys/smp.h> /* smp_active */ 63#include <sys/sysctl.h> 64#include <sys/sysproto.h> 65#include <sys/vnode.h> 66 | 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> --- 11 unchanged lines hidden (view full) --- 59#include <sys/proc.h> 60#include <sys/reboot.h> 61#include <sys/resourcevar.h> 62#include <sys/smp.h> /* smp_active */ 63#include <sys/sysctl.h> 64#include <sys/sysproto.h> 65#include <sys/vnode.h> 66 |
67#include <machine/pcb.h> | |
68#include <machine/md_var.h> 69#include <machine/smp.h> 70 71#include <sys/signalvar.h> 72#ifdef DDB 73#include <ddb/ddb.h> 74#endif 75 --- 35 unchanged lines hidden (view full) --- 111#endif /* HW_WDOG */ 112 113/* 114 * Variable panicstr contains argument to first call to panic; used as flag 115 * to indicate that the kernel has already called panic. 116 */ 117const char *panicstr; 118 | 67#include <machine/md_var.h> 68#include <machine/smp.h> 69 70#include <sys/signalvar.h> 71#ifdef DDB 72#include <ddb/ddb.h> 73#endif 74 --- 35 unchanged lines hidden (view full) --- 110#endif /* HW_WDOG */ 111 112/* 113 * Variable panicstr contains argument to first call to panic; used as flag 114 * to indicate that the kernel has already called panic. 115 */ 116const char *panicstr; 117 |
119int dumping; /* system is dumping */ 120dev_t dumpdev = NODEV; | 118int dumping; /* system is dumping */ 119static struct dumperinfo dumper; /* our selected dumper */ |
121 122static void boot(int) __dead2; | 120 121static void boot(int) __dead2; |
123static void dumpsys(void); | |
124static void poweroff_wait(void *, int); 125static void shutdown_halt(void *junk, int howto); 126static void shutdown_panic(void *junk, int howto); 127static void shutdown_reset(void *junk, int howto); 128 129/* register various local shutdown events */ 130static void 131shutdown_conf(void *unused) --- 41 unchanged lines hidden (view full) --- 173 PROC_UNLOCK(initproc); 174 } else { 175 /* No init(8) running, so simply reboot */ 176 boot(RB_NOSYNC); 177 } 178 return; 179} 180static int waittime = -1; | 122static void poweroff_wait(void *, int); 123static void shutdown_halt(void *junk, int howto); 124static void shutdown_panic(void *junk, int howto); 125static void shutdown_reset(void *junk, int howto); 126 127/* register various local shutdown events */ 128static void 129shutdown_conf(void *unused) --- 41 unchanged lines hidden (view full) --- 171 PROC_UNLOCK(initproc); 172 } else { 173 /* No init(8) running, so simply reboot */ 174 boot(RB_NOSYNC); 175 } 176 return; 177} 178static int waittime = -1; |
181static struct pcb dumppcb; | |
182 183static void 184print_uptime(void) 185{ 186 int f; 187 struct timespec ts; 188 189 getnanouptime(&ts); --- 139 unchanged lines hidden (view full) --- 329 print_uptime(); 330 331 /* 332 * Ok, now do things that assume all filesystem activity has 333 * been completed. 334 */ 335 EVENTHANDLER_INVOKE(shutdown_post_sync, howto); 336 splhigh(); | 179 180static void 181print_uptime(void) 182{ 183 int f; 184 struct timespec ts; 185 186 getnanouptime(&ts); --- 139 unchanged lines hidden (view full) --- 326 print_uptime(); 327 328 /* 329 * Ok, now do things that assume all filesystem activity has 330 * been completed. 331 */ 332 EVENTHANDLER_INVOKE(shutdown_post_sync, howto); 333 splhigh(); |
337 if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold) 338 dumpsys(); | 334 if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && 335 !cold && dumper.dumper != NULL && !dumping) { 336 dumping++; 337 dumpsys(&dumper); 338 } |
339 340 /* Now that we're going to really halt the system... */ 341 EVENTHANDLER_INVOKE(shutdown_final, howto); 342 343 for(;;) ; /* safety against shutdown_reset not working */ 344 /* NOTREACHED */ 345} 346 --- 60 unchanged lines hidden (view full) --- 407{ 408 printf("Rebooting...\n"); 409 DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 410 /* cpu_boot(howto); */ /* doesn't do anything at the moment */ 411 cpu_reset(); 412 /* NOTREACHED */ /* assuming reset worked */ 413} 414 | 339 340 /* Now that we're going to really halt the system... */ 341 EVENTHANDLER_INVOKE(shutdown_final, howto); 342 343 for(;;) ; /* safety against shutdown_reset not working */ 344 /* NOTREACHED */ 345} 346 --- 60 unchanged lines hidden (view full) --- 407{ 408 printf("Rebooting...\n"); 409 DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 410 /* cpu_boot(howto); */ /* doesn't do anything at the moment */ 411 cpu_reset(); 412 /* NOTREACHED */ /* assuming reset worked */ 413} 414 |
415/* 416 * Magic number for savecore 417 * 418 * exported (symorder) and used at least by savecore(8) 419 * 420 */ 421static u_long const dumpmag = 0x8fca0101UL; 422 423static int dumpsize = 0; /* also for savecore */ 424 425static int dodump = 1; 426 427SYSCTL_INT(_machdep, OID_AUTO, do_dump, CTLFLAG_RW, &dodump, 0, 428 "Try to perform coredump on kernel panic"); 429 430static int 431setdumpdev(dev_t dev) 432{ 433 int psize; 434 long newdumplo; 435 436 if (dev == NODEV) { 437 dumpdev = dev; 438 return (0); 439 } 440 if (devsw(dev) == NULL) 441 return (ENXIO); /* XXX is this right? */ 442 if (devsw(dev)->d_psize == NULL) 443 return (ENXIO); /* XXX should be ENODEV ? */ 444 psize = devsw(dev)->d_psize(dev); 445 if (psize == -1) 446 return (ENXIO); /* XXX should be ENODEV ? */ 447 /* 448 * XXX should clean up checking in dumpsys() to be more like this. 449 */ 450 newdumplo = psize - Maxmem * (PAGE_SIZE / DEV_BSIZE); 451 if (newdumplo <= LABELSECTOR) 452 return (ENOSPC); 453 dumpdev = dev; 454 dumplo = newdumplo; 455 return (0); 456} 457 458 459/* ARGSUSED */ 460static void 461dump_conf(void *dummy) 462{ 463 char *path; 464 dev_t dev; 465 466 path = malloc(MNAMELEN, M_TEMP, M_WAITOK); 467 if (TUNABLE_STR_FETCH("dumpdev", path, MNAMELEN) != 0) { 468 dev = getdiskbyname(path); 469 if (dev != NODEV) 470 dumpdev = dev; 471 } 472 free(path, M_TEMP); 473 if (setdumpdev(dumpdev) != 0) 474 dumpdev = NODEV; 475} 476 477SYSINIT(dump_conf, SI_SUB_DUMP_CONF, SI_ORDER_FIRST, dump_conf, NULL) 478 479static int 480sysctl_kern_dumpdev(SYSCTL_HANDLER_ARGS) 481{ 482 int error; 483 udev_t ndumpdev; 484 485 ndumpdev = dev2udev(dumpdev); 486 error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); 487 if (error == 0 && req->newptr != NULL) 488 error = setdumpdev(udev2dev(ndumpdev, 0)); 489 return (error); 490} 491 492SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW, 493 0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", ""); 494 495/* 496 * Doadump comes here after turning off memory management and 497 * getting on the dump stack, either when called above, or by 498 * the auto-restart code. 499 */ 500static void 501dumpsys(void) 502{ 503 int error; 504 505 savectx(&dumppcb); 506 if (!dodump) 507 return; 508 if (dumpdev == NODEV) 509 return; 510 if (!(devsw(dumpdev))) 511 return; 512 if (!(devsw(dumpdev)->d_dump)) 513 return; 514 if (dumping++) { 515 dumping--; 516 printf("Dump already in progress, bailing...\n"); 517 return; 518 } 519 dumpsize = Maxmem; 520 printf("\ndumping to dev %s, offset %ld\n", devtoname(dumpdev), dumplo); 521 printf("dump "); 522 error = (*devsw(dumpdev)->d_dump)(dumpdev); 523 dumping--; 524 if (error == 0) { 525 printf("succeeded\n"); 526 return; 527 } 528 printf("failed, reason: "); 529 switch (error) { 530 case ENODEV: 531 printf("device doesn't support a dump routine\n"); 532 break; 533 534 case ENXIO: 535 printf("device bad\n"); 536 break; 537 538 case EFAULT: 539 printf("device not ready\n"); 540 break; 541 542 case EINVAL: 543 printf("area improper\n"); 544 break; 545 546 case EIO: 547 printf("i/o error\n"); 548 break; 549 550 case EINTR: 551 printf("aborted from console\n"); 552 break; 553 554 default: 555 printf("unknown, error = %d\n", error); 556 break; 557 } 558} 559 560int 561dumpstatus(vm_offset_t addr, off_t count) 562{ 563 int c; 564 565 if (addr % (1024 * 1024) == 0) { 566#ifdef HW_WDOG 567 if (wdog_tickler) 568 (*wdog_tickler)(); 569#endif 570 printf("%ld ", (long)(count / (1024 * 1024))); 571 } 572 573 if ((c = cncheckc()) == 0x03) 574 return -1; 575 else if (c != -1) 576 printf("[CTRL-C to abort] "); 577 578 return 0; 579} 580 | |
581#ifdef SMP 582static u_int panic_cpu = NOCPU; 583#endif 584 585/* 586 * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 587 * and then reboots. If we are called twice, then we avoid trying to sync 588 * the disks as this often leads to recursive panics. --- 103 unchanged lines hidden (view full) --- 692 kproc_shutdown_wait, p->p_comm); 693 error = kthread_suspend(p, kproc_shutdown_wait * hz); 694 695 if (error == EWOULDBLOCK) 696 printf("timed out\n"); 697 else 698 printf("stopped\n"); 699} | 415#ifdef SMP 416static u_int panic_cpu = NOCPU; 417#endif 418 419/* 420 * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 421 * and then reboots. If we are called twice, then we avoid trying to sync 422 * the disks as this often leads to recursive panics. --- 103 unchanged lines hidden (view full) --- 526 kproc_shutdown_wait, p->p_comm); 527 error = kthread_suspend(p, kproc_shutdown_wait * hz); 528 529 if (error == EWOULDBLOCK) 530 printf("timed out\n"); 531 else 532 printf("stopped\n"); 533} |
534 535/* Registration of dumpers */ 536int 537set_dumper(struct dumperinfo *di) 538{ 539 if (di == NULL) { 540 bzero(&dumper, sizeof dumper); 541 return (0); 542 } 543 if (dumper.dumper != NULL) 544 return (EBUSY); 545 dumper = *di; 546 return (0); 547} 548 549#ifndef __i386__ 550void 551dumpsys(struct dumperinfo *di __unused) 552{ 553 554 printf("Kernel dumps not implemented on this architecture\n"); 555} 556#endif |
|