Ejemplo n.º 1
0
int
boot(int paniced, int howto, char *command)
{
	struct proc *p = current_proc();	/* XXX */
	int hostboot_option=0;

	if (!OSCompareAndSwap(0, 1, &system_inshutdown)) {
		if ( (howto&RB_QUICK) == RB_QUICK)
			goto force_reboot;
		return (EBUSY);
	}
	/*
	 * Temporary hack to notify the power management root domain
	 * that the system will shut down.
	 */
	IOSystemShutdownNotification();

	md_prepare_for_shutdown(paniced, howto, command);

	if ((howto&RB_QUICK)==RB_QUICK) {
		printf("Quick reboot...\n");
		if ((howto&RB_NOSYNC)==0) {
			sync(p, (void *)NULL, (int *)NULL);
		}
	}
	else if ((howto&RB_NOSYNC)==0) {
		int iter, nbusy;

		printf("syncing disks... ");

		/*
		 * Release vnodes held by texts before sync.
		 */

		/* handle live procs (deallocate their root and current directories). */		
		proc_shutdown();

#if CONFIG_AUDIT
		audit_shutdown();
#endif

		if (unmountroot_pre_hook != NULL)
			unmountroot_pre_hook();

		sync(p, (void *)NULL, (int *)NULL);

		/*
		 * Now that all processes have been terminated and system is
		 * sync'ed up, suspend init
		 */
			
		if (initproc && p != initproc)
			task_suspend(initproc->task);

		if (kdebug_enable)
			kdbg_dump_trace_to_file("/var/log/shutdown/shutdown.trace");

		/*
		 * Unmount filesystems
		 */
		vfs_unmountall();

		/* Wait for the buffer cache to clean remaining dirty buffers */
		for (iter = 0; iter < 100; iter++) {
			nbusy = count_busy_buffers();
			if (nbusy == 0)
				break;
			printf("%d ", nbusy);
			delay_for_interval( 1 * nbusy, 1000 * 1000);
		}
		if (nbusy)
			printf("giving up\n");
		else
			printf("done\n");
	}
#if NETWORKING
	/*
	 * Can't just use an splnet() here to disable the network
	 * because that will lock out softints which the disk
	 * drivers depend on to finish DMAs.
	 */
	if_down_all();
#endif /* NETWORKING */

force_reboot:
	if (howto & RB_POWERDOWN)
		hostboot_option = HOST_REBOOT_HALT;
	if (howto & RB_HALT)
		hostboot_option = HOST_REBOOT_HALT;
	if (paniced == RB_PANIC)
		hostboot_option = HOST_REBOOT_HALT;

	if (howto & RB_UPSDELAY) {
		hostboot_option = HOST_REBOOT_UPSDELAY;
	}

	host_reboot(host_priv_self(), hostboot_option);
	/*
	 * should not be reached
	 */
	return (0);
}
Ejemplo n.º 2
0
int
reboot_kernel(int howto, char *message)
{
	int hostboot_option=0;

	if (!OSCompareAndSwap(0, 1, &system_inshutdown)) {
		if ( (howto&RB_QUICK) == RB_QUICK)
			goto force_reboot;
		return (EBUSY);
	}
	/*
	 * Temporary hack to notify the power management root domain
	 * that the system will shut down.
	 */
	IOSystemShutdownNotification();

	if ((howto&RB_QUICK)==RB_QUICK) {
		printf("Quick reboot...\n");
		if ((howto&RB_NOSYNC)==0) {
			sync((proc_t)NULL, (void *)NULL, (int *)NULL);
		}
	}
	else if ((howto&RB_NOSYNC)==0) {
		int iter, nbusy;

		printf("syncing disks... ");

		/*
		 * Release vnodes held by texts before sync.
		 */

		/* handle live procs (deallocate their root and current directories), suspend initproc */
		proc_shutdown();

#if CONFIG_AUDIT
		audit_shutdown();
#endif

		if (unmountroot_pre_hook != NULL)
			unmountroot_pre_hook();

		sync((proc_t)NULL, (void *)NULL, (int *)NULL);

		if (kdebug_enable)
			kdbg_dump_trace_to_file("/var/log/shutdown/shutdown.trace");

		/*
		 * Unmount filesystems
		 */

#if DEVELOPMENT || DEBUG
		if (!(howto & RB_PANIC) || !kdp_has_polled_corefile())
#endif /* DEVELOPMENT || DEBUG */
		{
			vfs_unmountall();
		}

		/* Wait for the buffer cache to clean remaining dirty buffers */
		for (iter = 0; iter < 100; iter++) {
			nbusy = count_busy_buffers();
			if (nbusy == 0)
				break;
			printf("%d ", nbusy);
			delay_for_interval( 1 * nbusy, 1000 * 1000);
		}
		if (nbusy)
			printf("giving up\n");
		else
			printf("done\n");
	}
#if NETWORKING
	/*
	 * Can't just use an splnet() here to disable the network
	 * because that will lock out softints which the disk
	 * drivers depend on to finish DMAs.
	 */
	if_down_all();
#endif /* NETWORKING */

force_reboot:

	if (howto & RB_PANIC) {
		if (strncmp(message, "Kernel memory has exceeded limits", 33) == 0) {
			kernel_hwm_panic_info();
		}
		panic ("userspace panic: %s", message);
	}

	if (howto & RB_POWERDOWN)
		hostboot_option = HOST_REBOOT_HALT;
	if (howto & RB_HALT)
		hostboot_option = HOST_REBOOT_HALT;

	if (howto & RB_UPSDELAY) {
		hostboot_option = HOST_REBOOT_UPSDELAY;
	}

	host_reboot(host_priv_self(), hostboot_option);
	/*
	 * should not be reached
	 */
	return (0);
}