Esempio n. 1
0
int main(int argc, char **argv)
{
	struct ct_arg cta;
	int p[2], status;
	libct_session_t s;
	ct_handler_t ct;
	ct_process_desc_t pd;
	ct_process_t pr, epr;

	test_init();

	if (pipe(p))
		return tst_perr("Unable to create pipe");
	cta.mark = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
			MAP_SHARED | MAP_ANON, 0, 0);
	cta.mark[0] = 0;
	cta.mark[1] = 0;
	cta.wait_fd = p[0];

	s = libct_session_open_local();
	ct = libct_container_create(s, "test");
	libct_container_set_nsmask(ct, CLONE_NEWPID);
	pd = libct_process_desc_create(s);
	pr = libct_container_spawn_cb(ct, pd, set_ct_alive, &cta);
	if (libct_handle_is_err(pr)) {
		return fail("Unable to start CT");
	}

	epr = libct_container_enter_cb(ct, pd, set_ct_enter, &cta);
	if (libct_handle_is_err(epr))
		return fail("Unable to enter into CT");

	if (kill(libct_process_get_pid(pr), SIGKILL))
		return fail("Unable to send a signal to the init process");

	if (libct_process_wait(epr, &status))
		return fail("Unable to wait a process");
	if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL)
		return fail("Unexpected status %x\n", status);

	if (libct_process_wait(pr, &status))
		return fail("Unable to wait a process");
	if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL)
		return fail("Unexpected status %x\n", status);


	libct_container_wait(ct);
	libct_container_destroy(ct);
	libct_process_desc_destroy(pd);
	libct_process_destroy(epr);
	libct_session_close(s);

	return pass("CT is created and entered");
}
Esempio n. 2
0
int main(int argc, char **argv)
{
	int fd, p[2], status;
	struct ct_arg cta;
	libct_session_t s;
	ct_handler_t ct;
	ct_process_desc_t pd;
	ct_process_t pr;

	pipe(p);

	mkdir(FS_ROOT, 0600);
	fd = open(FS_ROOT "/" FS_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0600);
	if (fd < 0) {
		tst_perr("Can't create file");
		return 2;
	}

	write(fd, FS_DATA, sizeof(FS_DATA));
	close(fd);

	cta.fs_data = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
			MAP_SHARED | MAP_ANON, 0, 0);
	cta.fs_data[0] = '\0';
	cta.fs_data[ENTER_DOFF] = '\0';
	cta.wait_fd = p[0];

	s = libct_session_open_local();
	ct = libct_container_create(s, "test");
	pd = libct_process_desc_create(s);
	libct_fs_set_root(ct, FS_ROOT);
	libct_container_spawn_cb(ct, pd, ct_main_fn, &cta);
	pr = libct_container_enter_cb(ct, pd, ct_enter_fn, &cta);
	if (libct_handle_is_err(pr))
		fail("Unable to enter into CT");
	libct_process_wait(pr, &status);
	write(p[1], "a", 1);
	libct_container_wait(ct);
	libct_container_destroy(ct);
	libct_session_close(s);

	unlink(FS_ROOT "/" FS_FILE);
	rmdir(FS_ROOT);

	if (strcmp(cta.fs_data, FS_DATA))
		return fail("FS not accessed");

	if (strcmp(cta.fs_data + ENTER_DOFF, FS_DATA))
		return fail("FS not entered");

	return pass("FS is created and entered");
}
Esempio n. 3
0
File: ct.c Progetto: mkatkar/libct
static int local_ct_wait(ct_handler_t h)
{
	struct container *ct = cth2ct(h);
	int ret, status;

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

	if (ct->p.pid > 0) {
		ret = libct_process_wait(&ct->p.h, &status);
		if (ret < 0)
			return -1;
	}

	fs_umount(ct);
	cgroups_destroy(ct); /* FIXME -- can be held accross restarts */
	net_stop(ct);

	ct->state = CT_STOPPED;
	return 0;
}
Esempio n. 4
0
File: ct.c Progetto: 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);
}