A basic contianer can be created with minimal amount of code.
struct container {
char *name;
char *rootfs;
char *cmd;
void *stack;
};
struct container *new_container(char *name, char *rootfs, char *cmd)
{
struct container *c;
c = calloc(sizeof(struct container), 1);
if (!c)
err(errno, "Container");
c->name = strdup(name);
c->rootfs = strdup(rootfs);
c->cmd = strdup(cmd);
if (!c->name || !c->rootfs || !c->cmd)
err(errno, "Container");
return c;
}
Clone process using the `clone` system call with the appropriate namespace flags to create a new namespace for the contianer.
#define STACK_SIZE (1024 * 1024)
int run_container(struct container *c)
{
int pid;
/* We will add the network namespace later */
int cloneflags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC;
cloneflags |= SIGCHLD;
c->stack = malloc(STACK_SIZE);
if (!c->stack)
err(errno, "Stack creation");
printf("Cloning\n");
pid = clone(_container_exec, c->stack + STACK_SIZE, cloneflags, (void *) c);
if (pid == -1)
err(errno, "Clone");
printf("Cloned\n");
return pid;
}
if (chroot(c->rootfs) == -1)
err(errno, "chroot");
if (chdir(c->rootfs) == -1)
err(errno, "chdir");
/* mount proc so we can run `ps` etc */
if (mount("proc", "/proc", "proc", 0, NULL) == -1)
err(errno, "mount");
Site design and logo and content © fossix.org