Skip to content

Instantly share code, notes, and snippets.

@insom
Created June 10, 2013 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insom/5749718 to your computer and use it in GitHub Desktop.
Save insom/5749718 to your computer and use it in GitHub Desktop.
/*
* Copyright (C) 2013 Aaron Brady
* Copyright (C) 2008-2012 Red Hat, Inc.
* Copyright (C) 2008 IBM Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <mntent.h>
#include <string.h>
#include <strings.h>
#ifdef __dietlibc__
#include "/usr/include/linux/sched.h"
#endif
extern int pivot_root(const char * new_root,const char * put_old);
static int lxcContainerChildMountSort(const void *a, const void *b) {
const char **sa = (const char**)a;
const char **sb = (const char**)b;
/* Deliberately reversed args - we need to unmount deepest
children first */
return strcmp(*sb, *sa);
}
void unmount_old(void) {
struct mntent *mntent;
char **mounts = NULL;
int nmounts = 0;
FILE *procmnt;
int i;
int saveErrno;
const char *failedUmount = NULL;
int ret = -1;
procmnt = setmntent("/proc/mounts", "r");
mounts = malloc(250);
while (mntent = getmntent(procmnt)) {
if (strncmp(mntent->mnt_dir, "/.old", 4) != 0)
continue;
mounts[nmounts++] = strdup(mntent->mnt_dir);
}
if (mounts)
qsort(mounts, nmounts, sizeof(mounts[0]),
lxcContainerChildMountSort);
for (i = 0 ; i < nmounts ; i++) {
umount(mounts[i]);
}
umount("/.old");
}
int child(void *n) {
char buf[BUFSIZ] = {0};
char buf2[BUFSIZ] = {0};
snprintf(buf, BUFSIZ, "/lxc/%s/.old", n);
mkdir(buf, 0700);
snprintf(buf2, BUFSIZ, "/lxc/%s", n);
pivot_root(buf2, buf);
chdir("/");
mount("/proc", "/proc", "proc", 0, NULL);
close(2);
close(1);
close(0);
unmount_old();
mount("devpts", "/dev/pts", "devpts", 0, "newinstance,ptmxmode=0666,mode=0620,gid=5");
execl("/sbin/init", "/sbin/init", (char *)NULL);
perror(NULL);
return 0;
}
void main(int c, char **v) {
int cflags;
int stacksize = getpagesize() * 4;
char *stack, *stacktop;
char buf[BUFSIZ] = {0}; // Bless me Father, for I have sinned.
int ptmx;
int unlock = 0;
int ptyno;
pid_t pid;
void *pointer;
int val;
cflags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD|CLONE_NEWNET;
stack = (char *)malloc(stacksize);
stacktop = stack + stacksize;
pointer = malloc(BUFSIZ);
bzero(pointer, BUFSIZ);
strcpy(pointer, v[1]);
snprintf(buf, BUFSIZ, "ip link add name %s type veth peer name slave", v[1]);
system(buf);
snprintf(buf, BUFSIZ, "ip link set dev %s up", v[1]);
system(buf);
snprintf(buf, BUFSIZ, "brctl addif br1 %s", v[1]);
system(buf);
sleep(5); // Give the bridge a chance to spin up
pid = clone(child, stacktop, cflags, pointer);
snprintf(buf, BUFSIZ, "ip link set slave netns %d", pid);
system(buf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment