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 39 * $Id: kern_shutdown.c,v 1.16 1997/06/15 02:03:03 wollman Exp $ 40 */ 41 42 #include "opt_ddb.h" 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/reboot.h> 47 #include <sys/msgbuf.h> 48 #include <sys/proc.h> 49 #include <sys/vnode.h> 50 #include <sys/tty.h> 51 #include <sys/tprintf.h> 52 #include <sys/syslog.h> 53 #include <sys/malloc.h> 54 #include <sys/kernel.h> 55 #include <sys/mount.h> 56 #include <sys/sysctl.h> 57 #include <sys/conf.h> 58 #include <sys/sysproto.h> 59 60 #include <machine/pcb.h> 61 #include <machine/clock.h> 62 #include <machine/cons.h> 63 #include <machine/md_var.h> 64 #ifdef SMP 65 #include <machine/smp.h> /* smp_active, cpuid */ 66 #endif 67 68 #include <sys/utsname.h> 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 #if defined(DDB) 82 #ifdef DDB_UNATTENDED 83 static int debugger_on_panic = 0; 84 #else 85 static int debugger_on_panic = 1; 86 #endif 87 88 SYSCTL_INT(_debug, OID_AUTO, debugger_on_panic, CTLFLAG_RW, 89 &debugger_on_panic, 0, ""); 90 #endif 91 92 93 /* 94 * Variable panicstr contains argument to first call to panic; used as flag 95 * to indicate that the kernel has already called panic. 96 */ 97 const char *panicstr; 98 99 /* 100 * callout list for things to do a shutdown 101 */ 102 typedef struct shutdown_list_element { 103 struct shutdown_list_element *next; 104 bootlist_fn function; 105 void *arg; 106 } *sle_p; 107 108 /* 109 * there are two shutdown lists. Some things need to be shut down 110 * Earlier than others. 111 */ 112 static sle_p shutdown_list1; 113 static sle_p shutdown_list2; 114 115 116 static void dumpsys(void); 117 118 #ifndef _SYS_SYSPROTO_H_ 119 struct reboot_args { 120 int opt; 121 }; 122 #endif 123 /* ARGSUSED */ 124 125 /* 126 * The system call that results in a reboot 127 */ 128 int 129 reboot(p, uap, retval) 130 struct proc *p; 131 struct reboot_args *uap; 132 int *retval; 133 { 134 int error; 135 136 if ((error = suser(p->p_ucred, &p->p_acflag))) 137 return (error); 138 139 boot(uap->opt); 140 return (0); 141 } 142 143 /* 144 * Called by events that want to shut down.. e.g <CTL><ALT><DEL> on a PC 145 */ 146 void 147 shutdown_nice(void) 148 { 149 /* Send a signal to init(8) and have it shutdown the world */ 150 if (initproc != NULL) { 151 psignal(initproc, SIGINT); 152 } else { 153 /* No init(8) running, so simply reboot */ 154 boot(RB_NOSYNC); 155 } 156 return; 157 } 158 static int waittime = -1; 159 static struct pcb dumppcb; 160 161 /* 162 * Go through the rigmarole of shutting down.. 163 * this used to be in machdep.c but I'll be dammned if I could see 164 * anything machine dependant in it. 165 */ 166 void 167 boot(howto) 168 int howto; 169 { 170 sle_p ep; 171 172 #ifdef SMP 173 int c, spins; 174 175 /* don't accidently start it */ 176 if (smp_active) { 177 smp_active = 1; 178 179 spins = 100; 180 181 printf("boot() called on cpu#%d\n", cpuid); 182 while ((c = cpuid) != 0) { 183 if (spins-- < 1) { 184 printf("timeout waiting for cpu #0!\n"); 185 break; 186 } 187 printf("oops, I'm on cpu#%d, I need to be on cpu#0!\n", 188 c); 189 tsleep((caddr_t)&smp_active, PZERO, "cpu0wt", 10); 190 } 191 } 192 #endif 193 ep = shutdown_list1; 194 while (ep) { 195 shutdown_list1 = ep->next; 196 (*ep->function)(howto, ep->arg); 197 ep = ep->next; 198 } 199 if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) { 200 register struct buf *bp; 201 int iter, nbusy; 202 203 waittime = 0; 204 printf("\nsyncing disks... "); 205 206 sync(&proc0, NULL, NULL); 207 208 for (iter = 0; iter < 20; iter++) { 209 nbusy = 0; 210 for (bp = &buf[nbuf]; --bp >= buf; ) { 211 if ((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) { 212 nbusy++; 213 } 214 } 215 if (nbusy == 0) 216 break; 217 printf("%d ", nbusy); 218 DELAY(40000 * iter); 219 } 220 if (nbusy) { 221 /* 222 * Failed to sync all blocks. Indicate this and don't 223 * unmount filesystems (thus forcing an fsck on reboot). 224 */ 225 printf("giving up\n"); 226 #ifdef SHOW_BUSYBUFS 227 nbusy = 0; 228 for (bp = &buf[nbuf]; --bp >= buf; ) { 229 if ((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) { 230 nbusy++; 231 printf("%d: dev:%08x, flags:%08x, blkno:%d, lblkno:%d\n", nbusy, bp->b_dev, bp->b_flags, bp->b_blkno, bp->b_lblkno); 232 } 233 } 234 DELAY(5000000); /* 5 seconds */ 235 #endif 236 } else { 237 printf("done\n"); 238 /* 239 * Unmount filesystems 240 */ 241 if (panicstr == 0) 242 vfs_unmountall(); 243 } 244 DELAY(100000); /* wait for console output to finish */ 245 } 246 ep = shutdown_list2; 247 while (ep) { 248 shutdown_list2 = ep->next; 249 (*ep->function)(howto, ep->arg); 250 ep = ep->next; 251 } 252 splhigh(); 253 if (howto & RB_HALT) { 254 cpu_power_down(); 255 printf("\n"); 256 printf("The operating system has halted.\n"); 257 printf("Please press any key to reboot.\n\n"); 258 switch (cngetc()) { 259 case -1: /* No console, just die */ 260 cpu_halt(); 261 /* NOTREACHED */ 262 default: 263 break; 264 } 265 } else { 266 if (howto & RB_DUMP) { 267 if (!cold) { 268 savectx(&dumppcb); 269 dumppcb.pcb_cr3 = rcr3(); 270 dumpsys(); 271 } 272 273 if (PANIC_REBOOT_WAIT_TIME != 0) { 274 if (PANIC_REBOOT_WAIT_TIME != -1) { 275 int loop; 276 printf("Automatic reboot in %d seconds - press a key on the console to abort\n", 277 PANIC_REBOOT_WAIT_TIME); 278 for (loop = PANIC_REBOOT_WAIT_TIME * 10; loop > 0; --loop) { 279 DELAY(1000 * 100); /* 1/10th second */ 280 /* Did user type a key? */ 281 if (cncheckc() != -1) 282 break; 283 } 284 if (!loop) 285 goto die; 286 } 287 } else { /* zero time specified - reboot NOW */ 288 goto die; 289 } 290 printf("--> Press a key on the console to reboot <--\n"); 291 cngetc(); 292 } 293 } 294 die: 295 printf("Rebooting...\n"); 296 DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 297 /* cpu_boot(howto); */ /* doesn't do anything at the moment */ 298 cpu_reset(); 299 for(;;) ; 300 /* NOTREACHED */ 301 } 302 303 /* 304 * Magic number for savecore 305 * 306 * exported (symorder) and used at least by savecore(8) 307 * 308 */ 309 static u_long const dumpmag = 0x8fca0101UL; 310 311 static int dumpsize = 0; /* also for savecore */ 312 313 static int dodump = 1; 314 SYSCTL_INT(_machdep, OID_AUTO, do_dump, CTLFLAG_RW, &dodump, 0, ""); 315 316 /* 317 * Doadump comes here after turning off memory management and 318 * getting on the dump stack, either when called above, or by 319 * the auto-restart code. 320 */ 321 static void 322 dumpsys(void) 323 { 324 325 if (!dodump) 326 return; 327 if (dumpdev == NODEV) 328 return; 329 if ((minor(dumpdev)&07) != 1) 330 return; 331 if (!(bdevsw[major(dumpdev)])) 332 return; 333 if (!(bdevsw[major(dumpdev)]->d_dump)) 334 return; 335 dumpsize = Maxmem; 336 printf("\ndumping to dev %lx, offset %ld\n", dumpdev, dumplo); 337 printf("dump "); 338 switch ((*bdevsw[major(dumpdev)]->d_dump)(dumpdev)) { 339 340 case ENXIO: 341 printf("device bad\n"); 342 break; 343 344 case EFAULT: 345 printf("device not ready\n"); 346 break; 347 348 case EINVAL: 349 printf("area improper\n"); 350 break; 351 352 case EIO: 353 printf("i/o error\n"); 354 break; 355 356 case EINTR: 357 printf("aborted from console\n"); 358 break; 359 360 default: 361 printf("succeeded\n"); 362 break; 363 } 364 } 365 366 /* 367 * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 368 * and then reboots. If we are called twice, then we avoid trying to sync 369 * the disks as this often leads to recursive panics. 370 */ 371 void 372 panic(const char *fmt, ...) 373 { 374 int bootopt; 375 va_list ap; 376 377 bootopt = RB_AUTOBOOT | RB_DUMP; 378 if (panicstr) 379 bootopt |= RB_NOSYNC; 380 else 381 panicstr = fmt; 382 383 printf("panic: "); 384 va_start(ap, fmt); 385 vprintf(fmt, ap); 386 va_end(ap); 387 printf("\n"); 388 #ifdef SMP 389 printf(" cpuid %d\n", cpuid); 390 #endif 391 392 #if defined(DDB) 393 if (debugger_on_panic) 394 Debugger ("panic"); 395 #endif 396 boot(bootopt); 397 } 398 399 /* 400 * Two routines to handle adding/deleting items on the 401 * shutdown callout lists 402 * 403 * at_shutdown(): 404 * Take the arguments given and put them onto the shutdown callout list. 405 * However first make sure that it's not already there. 406 * returns 0 on success. 407 */ 408 int 409 at_shutdown(bootlist_fn function, void *arg, int position) 410 { 411 sle_p ep, *epp; 412 413 switch(position) { 414 case SHUTDOWN_PRE_SYNC: 415 epp = &shutdown_list1; 416 break; 417 case SHUTDOWN_POST_SYNC: 418 epp = &shutdown_list2; 419 break; 420 default: 421 printf("bad exit callout list specified\n"); 422 return (EINVAL); 423 } 424 if (rm_at_shutdown(function, arg)) 425 printf("exit callout entry already present\n"); 426 ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT); 427 if (ep == NULL) 428 return (ENOMEM); 429 ep->next = *epp; 430 ep->function = function; 431 ep->arg = arg; 432 *epp = ep; 433 return (0); 434 } 435 436 /* 437 * Scan the exit callout lists for the given items and remove them. 438 * Returns the number of items removed. 439 */ 440 int 441 rm_at_shutdown(bootlist_fn function, void *arg) 442 { 443 sle_p *epp, ep; 444 int count; 445 446 count = 0; 447 epp = &shutdown_list1; 448 ep = *epp; 449 while (ep) { 450 if ((ep->function == function) && (ep->arg == arg)) { 451 *epp = ep->next; 452 free(ep, M_TEMP); 453 count++; 454 } else { 455 epp = &ep->next; 456 } 457 ep = *epp; 458 } 459 epp = &shutdown_list2; 460 ep = *epp; 461 while (ep) { 462 if ((ep->function == function) && (ep->arg == arg)) { 463 *epp = ep->next; 464 free(ep, M_TEMP); 465 count++; 466 } else { 467 epp = &ep->next; 468 } 469 ep = *epp; 470 } 471 return (count); 472 } 473 474