Beispiel #1
0
static int slirp_open(void *data)
{
	struct slirp_data *pri = data;
	int fds[2], pid, err;

	err = os_pipe(fds, 1, 1);
	if (err)
		return err;

	err = slirp_tramp(pri->argw.argv, fds[1]);
	if (err < 0) {
		printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err);
		goto out;
	}
	pid = err;

	pri->slave = fds[1];
	pri->slip.pos = 0;
	pri->slip.esc = 0;
	pri->pid = err;

	return fds[0];
out:
	close(fds[0]);
	close(fds[1]);
	return err;
}
static int change_tramp(char **argv, char *output, int output_len)
{
	int pid, fds[2], err;
	struct change_pre_exec_data pe_data;

	err = os_pipe(fds, 1, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n",
		       -err);
		return err;
	}
	pe_data.close_me = fds[0];
	pe_data.stdout = fds[1];
	pid = run_helper(change_pre_exec, &pe_data, argv);

	if (pid > 0)	/* Avoid hang as we won't get data in failure case. */
		read_output(fds[0], output, output_len);

	close(fds[0]);
	close(fds[1]);

	if (pid > 0)
		helper_wait(pid);
	return pid;
}
int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
		   unsigned long stack_top, struct task_struct * p, 
		   struct pt_regs *regs)
{
	int (*tramp)(void *);
	int new_pid, err;
	unsigned long stack;
	
	if(current->thread.forking)
		tramp = fork_tramp;
	else {
		tramp = new_thread_proc;
		p->thread.request.u.thread = current->thread.request.u.thread;
	}

	err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
	if(err < 0){
		printk("copy_thread : pipe failed, err = %d\n", -err);
		return(err);
	}

	stack = alloc_stack(0, 0);
	if(stack == 0){
		printk(KERN_ERR "copy_thread : failed to allocate "
		       "temporary stack\n");
		return(-ENOMEM);
	}

	clone_flags &= CLONE_VM;
	p->thread.temp_stack = stack;
	new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp);
	if(new_pid < 0){
		printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
		       -new_pid);
		return(new_pid);
	}

	if(current->thread.forking){
		sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(&regs->regs));
		SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
		if(sp != 0)
			SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
	}
	p->thread.mode.tt.extern_pid = new_pid;

	current->thread.request.op = OP_FORK;
	current->thread.request.u.fork.pid = new_pid;
	os_usr1_process(os_getpid());

	/* Enable the signal and then disable it to ensure that it is handled
	 * here, and nowhere else.
	 */
	change_sig(SIGUSR1, 1);

	change_sig(SIGUSR1, 0);
	err = 0;
	return(err);
}
static int etap_open(void *data)
{
	struct ethertap_data *pri = data;
	char *output;
	int data_fds[2], control_fds[2], err, output_len;

	err = tap_open_common(pri->dev, pri->gate_addr);
	if(err) return(err);

	err = os_pipe(data_fds, 0, 0);
	if(err < 0){
		printk("data os_pipe failed - err = %d\n", -err);
		return(err);
	}

	err = os_pipe(control_fds, 1, 0);
	if(err < 0){
		printk("control os_pipe failed - err = %d\n", -err);
		return(err);
	}
	
	err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 
			 control_fds[1], data_fds[0], data_fds[1]);
	output_len = page_size();
	output = um_kmalloc(output_len);
	read_output(control_fds[0], output, output_len);

	if(output == NULL)
		printk("etap_open : failed to allocate output buffer\n");
	else {
		printk("%s", output);
		kfree(output);
	}

	if(err < 0){
		printk("etap_tramp failed - err = %d\n", -err);
		return(err);
	}

	pri->data_fd = data_fds[0];
	pri->control_fd = control_fds[0];
	iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
	return(data_fds[0]);
}
void set_init_pid(int pid)
{
	int err;

	init_task.thread.mode.tt.extern_pid = pid;
	err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
	if(err)
		panic("Can't create switch pipe for init_task, errno = %d",
		      -err);
}
Beispiel #6
0
static int slip_tramp(char **argv, int fd)
{
	struct slip_pre_exec_data pe_data;
	char *output;
	int status, pid, fds[2], err, output_len;

	err = os_pipe(fds, 1, 0);
	if(err < 0){
		printk("slip_tramp : pipe failed, err = %d\n", -err);
		goto out;
	}

	err = 0;
	pe_data.stdin = fd;
	pe_data.stdout = fds[1];
	pe_data.close_me = fds[0];
	err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
	if(err < 0)
		goto out_close;
	pid = err;

	output_len = page_size();
	output = um_kmalloc(output_len);
	if(output == NULL){
		printk("slip_tramp : failed to allocate output buffer\n");
		os_kill_process(pid, 1);
		err = -ENOMEM;
		goto out_free;
	}

	os_close_file(fds[1]);
	read_output(fds[0], output, output_len);
	printk("%s", output);

	CATCH_EINTR(err = waitpid(pid, &status, 0));
	if(err < 0)
		err = errno;
	else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
		printk("'%s' didn't exit with status 0\n", argv[0]);
		err = -EINVAL;
	}
	else err = 0;

	os_close_file(fds[0]);

out_free:
	kfree(output);
	return err;

out_close:
	os_close_file(fds[0]);
	os_close_file(fds[1]);
out:
	return err;
}
Beispiel #7
0
static void setup_tracer_winch(void)
{
	int err;

	err = os_pipe(tracer_winch, 1, 1);
	if(err < 0){
		printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
		return;
	}
	signal(SIGWINCH, tracer_winch_handler);
}
Beispiel #8
0
static int slip_tramp(char **argv, int fd)
{
	struct slip_pre_exec_data pe_data;
	char *output;
	int pid, fds[2], err, output_len;

	err = os_pipe(fds, 1, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
		       -err);
		goto out;
	}

	err = 0;
	pe_data.stdin = fd;
	pe_data.stdout = fds[1];
	pe_data.close_me = fds[0];
	err = run_helper(slip_pre_exec, &pe_data, argv);
	if (err < 0)
		goto out_close;
	pid = err;

	output_len = UM_KERN_PAGE_SIZE;
	output = kmalloc(output_len, UM_GFP_KERNEL);
	if (output == NULL) {
		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
		       "buffer\n");
		os_kill_process(pid, 1);
		err = -ENOMEM;
		goto out_free;
	}

	close(fds[1]);
	read_output(fds[0], output, output_len);
	printk("%s", output);

	err = helper_wait(pid, 0, argv[0]);
	close(fds[0]);

out_free:
	kfree(output);
	return err;

out_close:
	close(fds[0]);
	close(fds[1]);
out:
	return err;
}
Beispiel #9
0
static int change_tramp(char **argv, char *output, int output_len)
{
	int pid, fds[2], err;
	struct change_pre_exec_data pe_data;

	err = os_pipe(fds, 1, 0);
	if(err){
		printk("change_tramp - pipe failed, errno = %d\n", -err);
		return(err);
	}
	pe_data.close_me = fds[0];
	pe_data.stdout = fds[1];
	pid = run_helper(change_pre_exec, &pe_data, argv, NULL);

	close(fds[1]);
	read_output(fds[0], output, output_len);
	waitpid(pid, NULL, 0);	
	return(pid);
}
Beispiel #10
0
static int idle_proc(void *cpup)
{
	int cpu = (int) cpup, err;

	err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
	if (err < 0)
		panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);

	os_set_fd_async(cpu_data[cpu].ipi_pipe[0]);

	wmb();
	if (cpu_test_and_set(cpu, cpu_callin_map)) {
		printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
		BUG();
	}

	while (!cpu_isset(cpu, smp_commenced_mask))
		cpu_relax();

	notify_cpu_starting(cpu);
<<<<<<< HEAD
Beispiel #11
0
static int slip_tramp(char **argv, int fd)
{
	struct slip_pre_exec_data pe_data;
	char *output;
	int status, pid, fds[2], err, output_len;

	err = os_pipe(fds, 1, 0);
	if(err){
		printk("slip_tramp : pipe failed, errno = %d\n", -err);
		return(err);
	}

	err = 0;
	pe_data.stdin = fd;
	pe_data.stdout = fds[1];
	pe_data.close_me = fds[0];
	pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);

	if(pid < 0) err = pid;
	else {
		output_len = page_size();
		output = um_kmalloc(output_len);
		if(output == NULL)
			printk("slip_tramp : failed to allocate output "
			       "buffer\n");

		close(fds[1]);
		read_output(fds[0], output, output_len);
		if(output != NULL){
			printk("%s", output);
			kfree(output);
		}
		if(waitpid(pid, &status, 0) < 0) err = errno;
		else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
			printk("'%s' didn't exit with status 0\n", argv[0]);
			err = EINVAL;
		}
	}
	return(err);
}
Beispiel #12
0
int start_io_thread(unsigned long sp, int *fd_out)
{
	int pid, fds[2], err;

	err = os_pipe(fds, 1, 1);
	if(err < 0){
		printk("start_io_thread - os_pipe failed, err = %d\n", -err);
		goto out;
	}

	kernel_fd = fds[0];
	*fd_out = fds[1];

	err = os_set_fd_block(*fd_out, 0);
	if (err) {
		printk("start_io_thread - failed to set nonblocking I/O.\n");
		goto out_close;
	}

	pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM, NULL);
	if(pid < 0){
		err = -errno;
		printk("start_io_thread - clone failed : errno = %d\n", errno);
		goto out_close;
	}

	return(pid);

 out_close:
	os_close_file(fds[0]);
	os_close_file(fds[1]);
	kernel_fd = -1;
	*fd_out = -1;
 out:
	return err;
}
int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
{
	struct dog_data data;
	int in_fds[2], out_fds[2], pid, n, err;
	char pid_buf[sizeof("nnnnn\0")], c;
	char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
	char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
				  NULL };
	char **args = NULL;

	err = os_pipe(in_fds, 1, 0);
	if (err < 0) {
		printk("harddog_open - os_pipe failed, err = %d\n", -err);
		goto out;
	}

	err = os_pipe(out_fds, 1, 0);
	if (err < 0) {
		printk("harddog_open - os_pipe failed, err = %d\n", -err);
		goto out_close_in;
	}

	data.stdin = out_fds[0];
	data.stdout = in_fds[1];
	data.close_me[0] = out_fds[1];
	data.close_me[1] = in_fds[0];

	if (sock != NULL) {
		mconsole_args[2] = sock;
		args = mconsole_args;
	}
	else {
		/* XXX The os_getpid() is not SMP correct */
		sprintf(pid_buf, "%d", os_getpid());
		args = pid_args;
	}

	pid = run_helper(pre_exec, &data, args);

	close(out_fds[0]);
	close(in_fds[1]);

	if (pid < 0) {
		err = -pid;
		printk("harddog_open - run_helper failed, errno = %d\n", -err);
		goto out_close_out;
	}

	n = read(in_fds[0], &c, sizeof(c));
	if (n == 0) {
		printk("harddog_open - EOF on watchdog pipe\n");
		helper_wait(pid);
		err = -EIO;
		goto out_close_out;
	}
	else if (n < 0) {
		printk("harddog_open - read of watchdog pipe failed, "
		       "err = %d\n", errno);
		helper_wait(pid);
		err = n;
		goto out_close_out;
	}
	*in_fd_ret = in_fds[0];
	*out_fd_ret = out_fds[1];
	return 0;

 out_close_in:
	close(in_fds[0]);
	close(in_fds[1]);
 out_close_out:
	close(out_fds[0]);
	close(out_fds[1]);
 out:
	return err;
}
Beispiel #14
0
int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
	       unsigned long *stack_out)
{
	struct helper_data data;
	unsigned long stack, sp;
	int pid, fds[2], err, n;

	if((stack_out != NULL) && (*stack_out != 0))
		stack = *stack_out;
	else stack = alloc_stack(0, um_in_interrupt());
	if(stack == 0)
		return(-ENOMEM);

	err = os_pipe(fds, 1, 0);
	if(err < 0){
		printk("run_helper : pipe failed, err = %d\n", -err);
		goto out_free;
	}

	err = os_set_exec_close(fds[1], 1);
	if(err < 0){
		printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
		       -err);
		goto out_close;
	}

	sp = stack + page_size() - sizeof(void *);
	data.pre_exec = pre_exec;
	data.pre_data = pre_data;
	data.argv = argv;
	data.fd = fds[1];
	pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
	if(pid < 0){
		printk("run_helper : clone failed, errno = %d\n", errno);
		err = -errno;
		goto out_close;
	}

	os_close_file(fds[1]);
	n = os_read_file(fds[0], &err, sizeof(err));
	if(n < 0){
		printk("run_helper : read on pipe failed, err = %d\n", -n);
		err = n;
		goto out_kill;
	}
	else if(n != 0){
		CATCH_EINTR(n = waitpid(pid, NULL, 0));
		pid = -errno;
	}

	if(stack_out == NULL) free_stack(stack, 0);
        else *stack_out = stack;
	return(pid);

 out_kill:
	os_kill_process(pid, 1);
 out_close:
	os_close_file(fds[0]);
	os_close_file(fds[1]);
 out_free:
	free_stack(stack, 0);
	return(err);
}