|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Writing containers in Linux" |
| 4 | +excerpt: "Literate programming attempt of writing containers" |
| 5 | +date: 2020-10-01 10:28:45 +0530 |
| 6 | +categories: articles |
| 7 | +tags: [linux, containers] |
| 8 | +author: santosh |
| 9 | +--- |
| 10 | + |
| 11 | +## Creating Containers |
| 12 | +A basic contianer can be created with minimal amount of code. |
| 13 | + |
| 14 | +### Container |
| 15 | + |
| 16 | +```c |
| 17 | +struct container { |
| 18 | + char *name; |
| 19 | + char *rootfs; |
| 20 | + char *cmd; |
| 21 | + void *stack; |
| 22 | +}; |
| 23 | + |
| 24 | +struct container *new_container(char *name, char *rootfs, char *cmd) |
| 25 | +{ |
| 26 | + struct container *c; |
| 27 | + |
| 28 | + c = calloc(sizeof(struct container), 1); |
| 29 | + if (!c) |
| 30 | + err(errno, "Container"); |
| 31 | + |
| 32 | + c->name = strdup(name); |
| 33 | + c->rootfs = strdup(rootfs); |
| 34 | + c->cmd = strdup(cmd); |
| 35 | + |
| 36 | + if (!c->name || !c->rootfs || !c->cmd) |
| 37 | + err(errno, "Container"); |
| 38 | + |
| 39 | + return c; |
| 40 | +} |
| 41 | +``` |
| 42 | +
|
| 43 | +### Cloning Process |
| 44 | +
|
| 45 | +Clone process using the \`clone\` system call with the appropriate namespace |
| 46 | +flags to create a new namespace for the contianer. |
| 47 | +
|
| 48 | +```c |
| 49 | +#define STACK_SIZE (1024 * 1024) |
| 50 | +
|
| 51 | +int run_container(struct container *c) |
| 52 | +{ |
| 53 | + int pid; |
| 54 | +
|
| 55 | + /* We will add the network namespace later */ |
| 56 | + int cloneflags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC; |
| 57 | + cloneflags |= SIGCHLD; |
| 58 | +
|
| 59 | + c->stack = malloc(STACK_SIZE); |
| 60 | + if (!c->stack) |
| 61 | + err(errno, "Stack creation"); |
| 62 | +
|
| 63 | + printf("Cloning\n"); |
| 64 | + pid = clone(_container_exec, c->stack + STACK_SIZE, cloneflags, (void *) c); |
| 65 | + if (pid == -1) |
| 66 | + err(errno, "Clone"); |
| 67 | +
|
| 68 | + printf("Cloned\n"); |
| 69 | +
|
| 70 | + return pid; |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +### Change root filesystem |
| 75 | + |
| 76 | +```c |
| 77 | + if (chroot(c->rootfs) == -1) |
| 78 | + err(errno, "chroot"); |
| 79 | + |
| 80 | + if (chdir(c->rootfs) == -1) |
| 81 | + err(errno, "chdir"); |
| 82 | + |
| 83 | + /* mount proc so we can run `ps` etc */ |
| 84 | + if (mount("proc", "/proc", "proc", 0, NULL) == -1) |
| 85 | + err(errno, "mount"); |
| 86 | +``` |
| 87 | +
|
| 88 | +<!-- ### Change memory, cpu, network limits using cgroups --> |
| 89 | +
|
| 90 | +
|
| 91 | +<!-- ### Execute the main container process --> |
| 92 | +
|
0 commit comments