Deleted Added
full compact
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