Example #1
0
static uint8_t wait_domain_id(domainid_t domainid)
{
    uint8_t exitcode;
    errval_t err = spawn_wait(domainid, &exitcode, false);
    if(err_is_fail(err)) {
        USER_PANIC_ERR(err, "spawn_wait");
    }
    return exitcode;
}
Example #2
0
File: ct.c Project: mkatkar/libct
static ct_process_t __local_enter_cb(ct_handler_t h, ct_process_desc_t ph, int (*cb)(void *), void *arg, bool is_exec)
{
	struct container *ct = cth2ct(h);
	struct process_desc *p = prh2pr(ph);
	struct process *pr;
	int aux = -1, pid;
	int wait_pipe[2];

	if (ct->state != CT_RUNNING)
		return ERR_PTR(-LCTERR_BADCTSTATE);

	if (ct->nsmask & CLONE_NEWPID) {
		if (switch_ns(ct->p.pid, &pid_ns, &aux))
			return ERR_PTR(-LCTERR_INVARG);
	}

	pr = xmalloc(sizeof(struct process));
	if (pr == NULL)
		return ERR_PTR(-1);

	local_process_init(pr);

	if (pipe(wait_pipe)) {
		xfree(pr);
		return ERR_PTR(-1);
	}

	pid = fork();
	if (pid == 0) {
		struct ns_desc *ns;

		close(wait_pipe[0]);

		if (p->fds) {
			p->fds[p->fdn] = wait_pipe[1];

			if (setup_fds(p->fds, p->fdn + 1))
				exit(-1);

			wait_pipe[1] = p->fdn;
		}

		for (aux = 0; namespaces[aux]; aux++) {
			ns = namespaces[aux];

			if (ns->cflag == CLONE_NEWPID)
				continue;
			if (!(ns->cflag & ct->nsmask))
				continue;

			if (switch_ns(ct->p.pid, ns, NULL))
				exit(-1);
		}

		if (cgroups_attach(ct))
			exit(-1);

		if (ct->root_path && !(ct->nsmask & CLONE_NEWNS)) {
			char nroot[128];

			/*
			 * Otherwise switched by setns()
			 */

			snprintf(nroot, sizeof(nroot), "/proc/%d/root", ct->p.pid);
			if (set_current_root(nroot))
				exit(-1);
		}

		if (apply_creds(p))
			exit(-1);

		if (is_exec)
			spawn_wake_and_cloexec(wait_pipe, 0);
		else
			spawn_wake_and_close(wait_pipe, 0);

		aux = cb(arg);

		if (is_exec)
			spawn_wake_and_close(wait_pipe, -1);
		exit(aux);
	}

	close(wait_pipe[1]);

	if (aux >= 0)
		restore_ns(aux, &pid_ns);

	if (spawn_wait(wait_pipe))
		goto err;

	if (spawn_wait_and_close(wait_pipe) != INT_MIN)
		goto err;

	pr->pid = pid;

	return &pr->h;
err:
	xfree(pr);
	close(wait_pipe[0]);
	waitpid(pid, NULL, 0);
	return ERR_PTR(-1);
}
Example #3
0
File: ct.c Project: mkatkar/libct
static ct_process_t __local_spawn_cb(ct_handler_t h, ct_process_desc_t ph, int (*cb)(void *), void *arg, bool is_exec)
{
	struct container *ct = cth2ct(h);
	struct process_desc *p = prh2pr(ph);
	int ret = -1, pid, aux;
	struct ct_clone_arg ca;

	if (ct->state != CT_STOPPED)
		return ERR_PTR(-LCTERR_BADCTSTATE);

	ret = fs_mount(ct);
	if (ret)
		return ERR_PTR(ret);

	if ((ct->flags & CT_KILLABLE) && !(ct->nsmask & CLONE_NEWPID)) {
		if (add_service_controller(ct))
			goto err_cg;
	}

	ret = cgroups_create(ct);
	if (ret)
		goto err_cg;

	ret = -1;
	if (pipe(ca.child_wait_pipe))
		goto err_pipe;
	if (pipe(ca.parent_wait_pipe))
		goto err_pipe2;

	ca.cb = cb;
	ca.arg = arg;
	ca.ct = ct;
	ca.p = p;
	ca.is_exec = is_exec;
	pid = clone(ct_clone, &ca.stack_ptr, ct->nsmask | SIGCHLD, &ca);
	if (pid < 0)
		goto err_clone;

	ct->p.pid = pid;

	close(ca.child_wait_pipe[0]);
	close(ca.parent_wait_pipe[1]);

	if (ct->nsmask & CLONE_NEWUSER) {
		if (write_id_mappings(pid, &ct->uid_map, "uid_map"))
			goto err_net;

		if (write_id_mappings(pid, &ct->gid_map, "gid_map"))
			goto err_net;
	}

	if (net_start(ct))
		goto err_net;

	spawn_wake_and_close(ca.child_wait_pipe, 0);

	aux = spawn_wait(ca.parent_wait_pipe);
	if (aux != 0) {
		ret = aux;
		goto err_ch;
	}

	aux = spawn_wait_and_close(ca.parent_wait_pipe);
	if (aux != INT_MIN) {
		ret = -1;
		goto err_ch;
	}

	ct->state = CT_RUNNING;
	return &ct->p.h;

err_ch:
	net_stop(ct);
err_net:
	spawn_wake_and_close(ca.child_wait_pipe, -1);
	libct_process_wait(&ct->p.h, NULL);
err_clone:
	close(ca.parent_wait_pipe[0]);
	close(ca.parent_wait_pipe[1]);
err_pipe2:
	close(ca.child_wait_pipe[0]);
	close(ca.child_wait_pipe[1]);
err_pipe:
	cgroups_destroy(ct);
err_cg:
	fs_umount(ct);
	return ERR_PTR(ret);
}