#include "prototype.h" #define __USE_GNU #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #define STACKSIZE (1024 * 1024) static char child_stack[STACKSIZE]; /** * child_exec is the func that will be executed as the result of clone */ int child_exec(void *stuff) { container_t *c = (container_t *)stuff; struct clone_args *cloneArgs = &c->cloneArgs; if (sethostname(cloneArgs->hostname, strlen(cloneArgs->hostname)) != 0) { container_error_handler(c, "fail to set new hostname"); } if (execvp(cloneArgs->argv[0], cloneArgs->argv) != 0) { container_error_handler(c, "failed to execvp arguments\n"); } // we should never reach here! exit(EXIT_FAILURE); } /** * container constructor initialize container_t object */ container_t *initialize_container(struct clone_args cloneArgs) { container_t *c = (container_t *)malloc(sizeof(container_t)); // in order new net ns, new mount ns, new hostname ns, new pid ns, child ns c->_cloneFlags = CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | SIGCHLD; c->cloneArgs = cloneArgs; return c; } /** * launch command into container */ pid_t run(container_t *c) { // the result of this call is that our child_exec will be run in another // process returning it's pid pid_t pid = clone(child_exec, child_stack + STACKSIZE, c->_cloneFlags, c); if (pid < 0) { container_error_handler(c, "failed to run clone"); } // lets wait on our child process here before we, the parent, exits if (waitpid(pid, NULL, 0) == -1) { container_error_handler(c, "failed to wait pid %d", pid); exit(EXIT_FAILURE); } return pid; } /** * handle error occured during container creation * this methode permit to call container_destroy * before printing error * take at last parameter variadic argument */ void container_error_handler(container_t *c, const char *error_msg, ...) { va_list arg; va_start(arg, error_msg); destroy_container(c); error(error_msg, arg); va_end(arg); } /** * container destructor */ void destroy_container(container_t *c) { free(c); }