Exemplo n.º 1
0
int entry(unsigned int cpu_id, struct per_cpu *cpu_data)
{
	static volatile bool activate;
	bool master = false;

	cpu_data->cpu_id = cpu_id;

	spin_lock(&init_lock);

	if (master_cpu_id == -1) {
		master = true;
		init_early(cpu_id);
	}

	if (!error)
		cpu_init(cpu_data);

	spin_unlock(&init_lock);

	while (!error && initialized_cpus < hypervisor_header.online_cpus)
		cpu_relax();

	if (!error && master) {
		init_late(cpu_data);
		if (!error) {
			/*
			 * Make sure everything was committed before we signal
			 * the other CPUs that they can continue.
			 */
			memory_barrier();
			activate = true;
		}
	} else {
		while (!error && !activate)
			cpu_relax();
	}

	if (error) {
		if (master)
			arch_shutdown();
		arch_cpu_restore(cpu_data);
		return error;
	}

	if (master)
		printk("Activating hypervisor\n");

	/* point of no return */
	arch_cpu_activate_vmm(cpu_data);
}
Exemplo n.º 2
0
static int init_chain(const char* target)
{
	init_early();
	prepare_block_devices();
	load_fstab();
	if ( atexit(init_chain_atexit) != 0 )
		fatal("atexit: %m");
	if ( !mkdtemp(chain_location) )
		fatal("mkdtemp: /tmp/fs.XXXXXX: %m");
	chain_location_made = true;
	bool found_root = false;
	for ( size_t i = 0; i < mountpoints_used; i++ )
	{
		struct mountpoint* mountpoint = &mountpoints[i];
		if ( !strcmp(mountpoint->entry.fs_file, "/") )
			found_root = true;
		char* absolute = join_paths(chain_location, mountpoint->absolute);
		free(mountpoint->absolute);
		mountpoint->absolute = absolute;
	}
	if ( !found_root )
		fatal("/etc/fstab: Root filesystem not found in filesystem table");
	if ( atexit(mountpoints_unmount) != 0 )
		fatal("atexit: %m");
	mountpoints_mount(true);
	snprintf(chain_location_dev, sizeof(chain_location_dev), "%s/dev",
	         chain_location);
	if ( mkdir(chain_location_dev, 755) < 0 && errno != EEXIST )
		fatal("mkdir: %s: %m", chain_location_dev);
	int old_dev_fd = open("/dev", O_DIRECTORY | O_RDONLY);
	if ( old_dev_fd < 0 )
		fatal("%s: %m", "/dev");
	int new_dev_fd = open(chain_location_dev, O_DIRECTORY | O_RDONLY);
	if ( new_dev_fd < 0 )
		fatal("%s: %m", chain_location_dev);
	if ( fsm_fsbind(old_dev_fd, new_dev_fd, 0) < 0 )
		fatal("mount: `%s' onto `%s': %m", "/dev", chain_location_dev);
	close(new_dev_fd);
	close(old_dev_fd);
	int result;
	while ( true )
	{
		pid_t child_pid = fork();
		if ( child_pid < 0 )
			fatal("fork: %m");
		if ( !child_pid )
		{
			if ( chroot(chain_location) < 0 )
				fatal("chroot: %s: %m", chain_location);
			if ( chdir("/") < 0 )
				fatal("chdir: %s: %m", chain_location);
			if ( !strcmp(target, "chain-merge") )
			{
				const char* argv[] = { "sysmerge", "--booting", NULL };
				execv("/sysmerge/sbin/sysmerge", (char* const*) argv);
				fatal("Failed to run automatic update: %s: %m", argv[0]);
			}
			else
			{
				unsetenv("INIT_PID");
				const char* argv[] = { "init", NULL };
				execv("/sbin/init", (char* const*) argv);
				fatal("Failed to load chain init: %s: %m", argv[0]);
			}
		}
		int status;
		if ( waitpid(child_pid, &status, 0) < 0 )
			fatal("waitpid");
		const char* back = ": Trying to bring it back up again";
		if ( !strcmp(target, "chain-merge") )
		{
			if ( WIFEXITED(status) && WEXITSTATUS(status) == 0 )
			{
				target = "chain";
				continue;
			}
			if ( WIFEXITED(status) )
				fatal("Automatic upgrade failed: Exit status %i",
				      WEXITSTATUS(status));
			else if ( WIFSIGNALED(status) )
				fatal("Automatic upgrade failed: %s",
				      strsignal(WTERMSIG(status)));
			else
				fatal("Automatic upgrade failed: Unexpected unusual termination");
		}
		if ( WIFEXITED(status) )
		{
			result = WEXITSTATUS(status);
			break;
		}
		else if ( WIFSIGNALED(status) )
			note("chain init: %s%s", strsignal(WTERMSIG(status)), back);
		else
			note("chain init: Unexpected unusual termination%s", back);
	}
	mountpoints_unmount();
	init_chain_atexit();
	return result;
}
Exemplo n.º 3
0
static int init(const char* target)
{
	init_early();
	set_hostname();
	set_kblayout();
	set_videomode();
	prepare_block_devices();
	load_fstab();
	if ( atexit(mountpoints_unmount) != 0 )
		fatal("atexit: %m");
	mountpoints_mount(false);
	sigset_t oldset, sigttou;
	sigemptyset(&sigttou);
	sigaddset(&sigttou, SIGTTOU);
	int result;
	while ( true )
	{
		struct termios tio;
		if ( tcgetattr(0, &tio) )
			fatal("tcgetattr: %m");
		pid_t child_pid = fork();
		if ( child_pid < 0 )
			fatal("fork: %m");
		if ( !child_pid )
		{
			uid_t uid = getuid();
			pid_t pid = getpid();
			pid_t ppid = getppid();
			if ( setpgid(0, 0) < 0 )
				fatal("setpgid: %m");
			sigprocmask(SIG_BLOCK, &sigttou, &oldset);
			if ( tcsetpgrp(0, pid) < 0 )
				fatal("tcsetpgrp: %m");
			sigprocmask(SIG_SETMASK, &oldset, NULL);
			struct passwd* pwd = getpwuid(uid);
			if ( !pwd )
				fatal("looking up user by uid %" PRIuUID ": %m", uid);
			const char* home = pwd->pw_dir[0] ? pwd->pw_dir : "/";
			const char* shell = pwd->pw_shell[0] ? pwd->pw_shell : "sh";
			char ppid_str[sizeof(pid_t) * 3];
			snprintf(ppid_str, sizeof(ppid_str), "%" PRIiPID, ppid);
			if ( setenv("INIT_PID", ppid_str, 1) < 0 ||
			     setenv("LOGNAME", pwd->pw_name, 1) < 0 ||
			     setenv("USER", pwd->pw_name, 1) < 0 ||
			     setenv("HOME", home, 1) < 0 ||
			     setenv("SHELL", shell, 1) < 0 )
				fatal("setenv: %m");
			if ( chdir(home) < 0 )
				warning("chdir: %s: %m", home);
			const char* program = "login";
			bool activate_terminal = false;
			if ( !strcmp(target, "single-user") )
			{
				activate_terminal = true;
				program = shell;
			}
			if ( !strcmp(target, "sysinstall") )
			{
				activate_terminal = true;
				program = "sysinstall";
			}
			if ( !strcmp(target, "sysupgrade") )
			{
				program = "sysupgrade";
				activate_terminal = true;
			}
			if ( activate_terminal )
			{
				tio.c_cflag |= CREAD;
				if ( tcsetattr(0, TCSANOW, &tio) )
					fatal("tcgetattr: %m");
			}
			const char* argv[] = { program, NULL };
			execvp(program, (char* const*) argv);
			fatal("%s: %m", program);
		}
		int status;
		if ( waitpid(child_pid, &status, 0) < 0 )
			fatal("waitpid");
		sigprocmask(SIG_BLOCK, &sigttou, &oldset);
		if ( tcsetattr(0, TCSAFLUSH, &tio) )
			fatal("tcgetattr: %m");
		if ( tcsetpgrp(0, getpgid(0)) < 0 )
			fatal("tcsetpgrp: %m");
		sigprocmask(SIG_SETMASK, &oldset, NULL);
		const char* back = ": Trying to bring it back up again";
		if ( WIFEXITED(status) )
		{
			result = WEXITSTATUS(status);
			break;
		}
		else if ( WIFSIGNALED(status) )
			note("session: %s%s", strsignal(WTERMSIG(status)), back);
		else
			note("session: Unexpected unusual termination%s", back);
	}
	mountpoints_unmount();
	return result;
}