Ejemplo n.º 1
0
void
shutdown_nice(int howto)
{

	shutdown_howto = howto;

	/* Send a signal to init(8) and have it shutdown the world */
	if (initproc != NULL) {
		PROC_LOCK(initproc);
		kern_psignal(initproc, SIGINT);
		PROC_UNLOCK(initproc);
	} else {
		/* No init(8) running, so simply reboot */
		kern_reboot(RB_NOSYNC);
	}
	return;
}
Ejemplo n.º 2
0
/* ARGSUSED */
int
sys_reboot(struct thread *td, struct reboot_args *uap)
{
	int error;

	error = 0;
#ifdef MAC
	error = mac_system_check_reboot(td->td_ucred, uap->opt);
#endif
	if (error == 0)
		error = priv_check(td, PRIV_REBOOT);
	if (error == 0) {
		mtx_lock(&Giant);
		kern_reboot(uap->opt);
		mtx_unlock(&Giant);
	}
	return (error);
}
Ejemplo n.º 3
0
/*
 * Called by events that want to shut down.. e.g  <CTL><ALT><DEL> on a PC
 */
void
shutdown_nice(int howto)
{

	if (initproc != NULL) {
		/* Send a signal to init(8) and have it shutdown the world. */
		PROC_LOCK(initproc);
		if (howto & RB_POWEROFF)
			kern_psignal(initproc, SIGUSR2);
		else if (howto & RB_HALT)
			kern_psignal(initproc, SIGUSR1);
		else
			kern_psignal(initproc, SIGINT);
		PROC_UNLOCK(initproc);
	} else {
		/* No init(8) running, so simply reboot. */
		kern_reboot(howto | RB_NOSYNC);
	}
}
Ejemplo n.º 4
0
void
vpanic(const char *fmt, va_list ap)
{
#ifdef SMP
	cpuset_t other_cpus;
#endif
	struct thread *td = curthread;
	int bootopt, newpanic;
	static char buf[256];

	spinlock_enter();

#ifdef SMP
	/*
	 * stop_cpus_hard(other_cpus) should prevent multiple CPUs from
	 * concurrently entering panic.  Only the winner will proceed
	 * further.
	 */
	if (panicstr == NULL && !kdb_active) {
		other_cpus = all_cpus;
		CPU_CLR(PCPU_GET(cpuid), &other_cpus);
		stop_cpus_hard(other_cpus);
	}

	/*
	 * Ensure that the scheduler is stopped while panicking, even if panic
	 * has been entered from kdb.
	 */
	td->td_stopsched = 1;
#endif

	bootopt = RB_AUTOBOOT;
	newpanic = 0;
	if (panicstr)
		bootopt |= RB_NOSYNC;
	else {
		bootopt |= RB_DUMP;
		panicstr = fmt;
		newpanic = 1;
	}

	if (newpanic) {
		(void)vsnprintf(buf, sizeof(buf), fmt, ap);
		panicstr = buf;
		cngrab();
		printf("panic: %s\n", buf);
	} else {
		printf("panic: ");
		vprintf(fmt, ap);
		printf("\n");
	}
#ifdef SMP
	printf("cpuid = %d\n", PCPU_GET(cpuid));
#endif

#ifdef KDB
	if (newpanic && trace_on_panic)
		kdb_backtrace();
	if (debugger_on_panic)
		kdb_enter(KDB_WHY_PANIC, "panic");
#endif
	/*thread_lock(td); */
	td->td_flags |= TDF_INPANIC;
	/* thread_unlock(td); */
	if (!sync_on_panic)
		bootopt |= RB_NOSYNC;
	kern_reboot(bootopt);
}
Ejemplo n.º 5
0
static int
vfs_mountroot_parse(struct sbuf *sb, struct mount *mpdevfs)
{
	struct mount *mp;
	char *conf;
	int error;

	root_mount_mddev = -1;

retry:
	conf = sbuf_data(sb);
	mp = TAILQ_NEXT(mpdevfs, mnt_list);
	error = (mp == NULL) ? 0 : EDOOFUS;
	root_mount_onfail = A_CONTINUE;
	while (mp == NULL) {
		error = parse_skipto(&conf, CC_NONWHITESPACE);
		if (error == PE_EOL) {
			parse_advance(&conf);
			continue;
		}
		if (error < 0)
			break;
		switch (parse_peek(&conf)) {
		case '#':
			error = parse_skipto(&conf, '\n');
			break;
		case '.':
			error = parse_directive(&conf);
			break;
		default:
			error = parse_mount(&conf);
			break;
		}
		if (error < 0)
			break;
		/* Ignore any trailing garbage on the line. */
		if (parse_peek(&conf) != '\n') {
			printf("mountroot: advancing to next directive...\n");
			(void)parse_skipto(&conf, '\n');
		}
		mp = TAILQ_NEXT(mpdevfs, mnt_list);
	}
	if (mp != NULL)
		return (0);

	/*
	 * We failed to mount (a new) root.
	 */
	switch (root_mount_onfail) {
	case A_CONTINUE:
		break;
	case A_PANIC:
		panic("mountroot: unable to (re-)mount root.");
		/* NOTREACHED */
	case A_RETRY:
		goto retry;
	case A_REBOOT:
		kern_reboot(RB_NOSYNC);
		/* NOTREACHED */
	}

	return (error);
}
Ejemplo n.º 6
0
/*
 * Panic is called on unresolvable fatal errors.  It prints "panic: mesg",
 * and then reboots.  If we are called twice, then we avoid trying to sync
 * the disks as this often leads to recursive panics.
 */
void
panic(const char *fmt, ...)
{
#ifdef SMP
	static volatile u_int panic_cpu = NOCPU;
#endif
	struct thread *td = curthread;
	int bootopt, newpanic;
	va_list ap;
	static char buf[256];

	critical_enter();
#ifdef SMP
	/*
	 * We don't want multiple CPU's to panic at the same time, so we
	 * use panic_cpu as a simple spinlock.  We have to keep checking
	 * panic_cpu if we are spinning in case the panic on the first
	 * CPU is canceled.
	 */
	if (panic_cpu != PCPU_GET(cpuid))
		while (atomic_cmpset_int(&panic_cpu, NOCPU,
		    PCPU_GET(cpuid)) == 0)
			while (panic_cpu != NOCPU)
				; /* nothing */
#endif

	bootopt = RB_AUTOBOOT;
	newpanic = 0;
	if (panicstr)
		bootopt |= RB_NOSYNC;
	else {
		bootopt |= RB_DUMP;
		panicstr = fmt;
		newpanic = 1;
	}

	va_start(ap, fmt);
	if (newpanic) {
		(void)vsnprintf(buf, sizeof(buf), fmt, ap);
		panicstr = buf;
		printf("panic: %s\n", buf);
	} else {
		printf("panic: ");
		vprintf(fmt, ap);
		printf("\n");
	}
	va_end(ap);
#ifdef SMP
	printf("cpuid = %d\n", PCPU_GET(cpuid));
#endif

#ifdef KDB
	if (newpanic && trace_on_panic)
		kdb_backtrace();
	if (debugger_on_panic)
		kdb_enter(KDB_WHY_PANIC, "panic");
#endif
	/*thread_lock(td); */
	td->td_flags |= TDF_INPANIC;
	/* thread_unlock(td); */
	if (!sync_on_panic)
		bootopt |= RB_NOSYNC;
	critical_exit();
	kern_reboot(bootopt);
}
Ejemplo n.º 7
0
/*
 * Panic is called on unresolvable fatal errors.  It prints "panic: mesg",
 * and then reboots.  If we are called twice, then we avoid trying to sync
 * the disks as this often leads to recursive panics.
 */
void
panic(const char *fmt, ...)
{
#ifdef SMP
	static volatile u_int panic_cpu = NOCPU;
	cpuset_t other_cpus;
#endif
	struct thread *td = curthread;
	int bootopt, newpanic;
	va_list ap;
	static char buf[256];

	if (stop_scheduler_on_panic)
		spinlock_enter();
	else
		critical_enter();

#ifdef SMP
	/*
	 * We don't want multiple CPU's to panic at the same time, so we
	 * use panic_cpu as a simple spinlock.  We have to keep checking
	 * panic_cpu if we are spinning in case the panic on the first
	 * CPU is canceled.
	 */
	if (panic_cpu != PCPU_GET(cpuid))
		while (atomic_cmpset_int(&panic_cpu, NOCPU,
		    PCPU_GET(cpuid)) == 0)
			while (panic_cpu != NOCPU)
				; /* nothing */

	if (stop_scheduler_on_panic) {
		if (panicstr == NULL && !kdb_active) {
			other_cpus = all_cpus;
			CPU_CLR(PCPU_GET(cpuid), &other_cpus);
			stop_cpus_hard(other_cpus);
		}

		/*
		 * We set stop_scheduler here and not in the block above,
		 * because we want to ensure that if panic has been called and
		 * stop_scheduler_on_panic is true, then stop_scheduler will
		 * always be set.  Even if panic has been entered from kdb.
		 */
		td->td_stopsched = 1;
	}
#endif

	bootopt = RB_AUTOBOOT;
	newpanic = 0;
	if (panicstr)
		bootopt |= RB_NOSYNC;
	else {
		bootopt |= RB_DUMP;
		panicstr = fmt;
		newpanic = 1;
	}

	va_start(ap, fmt);
	if (newpanic) {
		(void)vsnprintf(buf, sizeof(buf), fmt, ap);
		panicstr = buf;
		cngrab();
		printf("panic: %s\n", buf);
	} else {
		printf("panic: ");
		vprintf(fmt, ap);
		printf("\n");
	}
	va_end(ap);
#ifdef SMP
	printf("cpuid = %d\n", PCPU_GET(cpuid));
#endif

#ifdef KDB
	if (newpanic && trace_on_panic)
		kdb_backtrace();
	if (debugger_on_panic)
		kdb_enter(KDB_WHY_PANIC, "panic");
#endif
	/*thread_lock(td); */
	td->td_flags |= TDF_INPANIC;
	/* thread_unlock(td); */
	if (!sync_on_panic)
		bootopt |= RB_NOSYNC;
	if (!stop_scheduler_on_panic)
		critical_exit();
	kern_reboot(bootopt);
}