lxcsu userspace package
Sapan Bhatia [Thu, 30 Aug 2012 13:05:57 +0000 (09:05 -0400)]
Makefile [new file with mode: 0644]
lxcsu [new file with mode: 0755]
setns.c [new file with mode: 0644]
setup.py [new file with mode: 0644]
vsh.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..9e0efe7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
+all:
+       gcc -I/usr/include/python2.7 -c setns.c -o setns.o
diff --git a/lxcsu b/lxcsu
new file mode 100755 (executable)
index 0000000..67a6974
--- /dev/null
+++ b/lxcsu
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+
+import setns
+import os
+
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.add_option("-n", "--net",
+                  action="store_true", dest="netns", default=False,
+                  help="Enter network namespace")
+parser.add_option("-m", "--mnt",
+                  action="store_true", dest="mntns", default=False,
+                  help="Enter mount namespace")
+
+(options, args) = parser.parse_args()
+
+try:
+       slice_name = args[0]
+except IndexError:
+       print "You must specify a vm name"
+       exit(1)
+
+
+try:
+       cmd = 'grep %s /proc/*/cgroup | grep freezer'%slice_name
+       output = os.popen(cmd).readlines()
+except:
+       print "Error finding slice %s"%slice_name
+       exit(1)
+
+slice_spec = None
+for e in output:
+       try:
+               l = e.rstrip()
+               path = l.split(':')[0]  
+               comp = l.rsplit(':')[-1]
+               slice_name_check = comp.rsplit('/')[-1]
+
+               if (slice_name_check == slice_name):
+                       slice_path = path
+                       pid = slice_path.split('/')[2]
+                       cmdline = open('/proc/%s/cmdline'%pid).read().rstrip('\n\x00')
+                       if (cmdline == '/sbin/init'):
+                               slice_spec = slice_path
+                               break
+       except:
+               break
+
+if (not slice_spec):
+       print "Could not find any processes associated with %s"%slice_name
+
+
+#os.closerange(0,1024)
+
+r1 = setns.chcontext('/proc/%s/ns/utc'%pid)
+r2 = setns.chcontext('/proc/%s/ns/ipc'%pid)
+path = '/proc/%s/ns/net'%pid
+r3 = setns.chcontext(path)
+os.system('whoami')
+open('/proc/lxcsu','w').write(pid)
+os.system('mount none -t proc /proc')
+os.execv('/bin/sh',['/bin/sh'])
diff --git a/setns.c b/setns.c
new file mode 100644 (file)
index 0000000..323825a
--- /dev/null
+++ b/setns.c
@@ -0,0 +1,67 @@
+#include <Python.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <asm-generic/unistd.h>
+
+static PyObject *
+chfscontext(PyObject *self, PyObject *args)
+{
+    const char *filepath;
+    int sts;
+
+    if (!PyArg_ParseTuple(args, "s", &filepath))
+        return NULL;
+
+    int fd = open(filepath, O_RDONLY);
+    if (fd < 0) {
+       printf("Could not open ns file\n");
+        sts = -1;
+        goto out;
+    }
+    
+    if (setns(fd, 666)) {
+        sts = -1;
+    }
+    close(fd);
+
+out:
+    return Py_BuildValue("i", sts);
+}
+static PyObject *
+chcontext(PyObject *self, PyObject *args)
+{
+    const char *filepath;
+    int sts;
+
+    if (!PyArg_ParseTuple(args, "s", &filepath))
+        return NULL;
+
+    int fd = open(filepath, O_RDONLY);
+    if (fd < 0) {
+       printf("Could not open ns file\n");
+        sts = -1;
+        goto out;
+    }
+    
+    if (setns(fd, 0)) {
+        sts = -1;
+    }
+    close(fd);
+
+out:
+    return Py_BuildValue("i", sts);
+}
+
+static PyMethodDef SetnsMethods[] =
+{
+         {"chcontext", chcontext, METH_VARARGS, "Switch into an lxc container."},
+         {"chfscontext", chfscontext, METH_VARARGS, "Switch into an lxc container."},
+              {NULL, NULL, 0, NULL}
+};
+PyMODINIT_FUNC
+initsetns(void)
+{
+         (void) Py_InitModule("setns", SetnsMethods);
+}
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..ea9a8b8
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,8 @@
+from distutils.core import setup, Extension
+module1 = Extension('setns', sources = ['setns.c'])
+setup (name = 'Setns',
+        version = '1.0',
+        description = 'Enter an lxc container',
+        ext_modules = [module1])
diff --git a/vsh.c b/vsh.c
new file mode 100644 (file)
index 0000000..76deb8b
--- /dev/null
+++ b/vsh.c
@@ -0,0 +1,83 @@
+/* Version 3 of vsh. Basically a wrapper around 'lxcsu -n -m <slicename>' - Sapan */
+
+#include <unistd.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define VSH_PATH    "/usr/sbin/vsh"
+#ifndef PATH_MAX
+#define PATH_MAX    4096
+#endif
+
+#define LXCSU_PATH  "/usr/sbin/lxcsu"
+
+char* get_current_username (unsigned int uid)
+{
+    struct passwd *passwd_entry;
+    if ((passwd_entry = getpwuid(uid)) == NULL) {
+        fprintf(stderr, "Could not look up user record for %d\n", uid);
+        return NULL; 
+    }
+
+    return (strdup(passwd_entry->pw_name));
+}
+
+char **extend_argv(int argc, char **argv, int num_extra_args) {
+    int argc2, i;
+    char **argv2;
+
+    argc2 = argc + num_extra_args;
+    argv2 = (char **) malloc((argc2 + 1) * sizeof(char *));
+
+    if (!argv2)
+        return (char **) NULL;
+
+    for (i=0; i<argc; i++) {
+        argv2[i+num_extra_args]=strdup(argv[i]); 
+    }
+    argv2[argc2]=NULL;
+
+    return argv2;
+}
+
+#define NUM_LXCSU_EXEC_ARGS 3
+
+int main(int argc, char **argv, char **envp)
+{
+    char *slice_name;
+    char **argv2;
+    int argc2;
+    char slice_id_str[256];
+    unsigned int slice_xid;
+
+    slice_xid = getuid();
+    slice_name = get_current_username(slice_xid);
+    if (!slice_name) {
+        fprintf(stderr,"Could not look up slice name\n");
+        goto out_exception;
+    }
+    
+    argv2 = extend_argv(argc, argv, NUM_LXCSU_EXEC_ARGS);
+    if (!argv2) goto out_exception;
+        
+    
+    // Populate arguments
+    snprintf(slice_id_str, 255, "%u", slice_xid);
+    argv2[0] = strdup(LXCSU_PATH);
+    argv2[1] = strdup("-n");
+    argv2[2] = strdup("-m");
+    argv2[3] = strdup(slice_name);
+
+    if (setuid(geteuid())) goto out_exception;
+
+    execve(LXCSU_PATH, argv2, envp);
+
+out_exception:
+    printf("%s\n", strerror(errno));
+    return errno;
+}