Skip to content

Instantly share code, notes, and snippets.

@gordinmitya
Last active June 25, 2018 16:17
Show Gist options
  • Save gordinmitya/82eca13dbe54b02e5b7109bc59991194 to your computer and use it in GitHub Desktop.
Save gordinmitya/82eca13dbe54b02e5b7109bc59991194 to your computer and use it in GitHub Desktop.
super tiny linux container via copy mechanism with cgroup restrictions, internet between container and host and loop device
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#define STACK_SIZE (1024 * 1024)
#include <sys/types.h>
#include <unistd.h>
static char child_stack[STACK_SIZE];
static int child_fn() {
// setup network internaly
printf("Clone internal PID: %ld\n", (long) getpid());
system("ifconfig veth1 10.1.1.2/24 up");
printf("Guest network namespace:\n");
system("ip link");
// proc
system("mount -t proc proc /proc --make-private");
// fs
system("dd if=/dev/zero of=image.img bs=1k count=4096");
system("losetup /dev/loop0 image.img");
system("mkfs -t ext4 /dev/loop0");
system("mkdir /mnt/mycontainer && mount -t ext4 /dev/loop0 /mnt/mycontainer");
pid_t child_pid = fork();
if (child_pid == 0) {
char argv[100], env[100];
execve("/bin/bash", &argv, &env);
} else {
// enable cgroups
char cmd[256];
snprintf(cmd, sizeof(cmd), "DIR=/sys/fs/cgroup/cpu/demo && mkdir $DIR && echo 50000 > $DIR/cpu.cfs_quota_us && echo 100000 > $DIR/cpu.cfs_period_us && echo %d > $DIR/tasks", child_pid);
system(cmd);
// working in parallel process...
waitpid(child_pid, NULL, 0);
// disable cgroups
system("rmdir /sys/fs/cgroup/cpu/demo");
// proc
system("umount /proc");
// fs
system("umount /dev/loop0");
system("losetup -d /dev/loop0");
system("rmdir /mnt/mycontainer");
}
return EXIT_SUCCESS;
}
int main() {
pid_t child_pid = clone(child_fn, child_stack + STACK_SIZE,
CLONE_NEWPID
| CLONE_NEWNET
| CLONE_NEWNS
| SIGCHLD,
NULL);
printf("clone() = %ld\n", (long) child_pid);
char cmd[100];
// create network between host and guest
snprintf(cmd, sizeof(cmd), "ip link add name veth0 type veth peer name veth1 netns %d", child_pid);
system(cmd);
system("ifconfig veth0 10.1.1.1/24 up");
waitpid(child_pid, NULL, 0);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment