On Mon, Mar 05, 2012 at 02:07:45PM -0500, Chris wrote:
> On Mon, Mar 05, 2012 at 04:55:31PM +0100, Roberto De Ioris wrote:
> > 
> > > I added the option to recursively bind mount the directory given to the
> > > --namespace option, which fixed one problem.  I hit another though when it
> > > tried to clean up the tmp mount for pivot_root.  It was unmounting all the
> > > bind
> > > mounts, so this was worked around by making it a little more picky about
> > > what
> > > it unmounted.
> > >
> > 
> > I think we need a way to better define bind-mounts in jails (or for the
> > --unshare option)
> > 
> > Something like
> > 
> > uwsgi --unshare mount --bind-mount /foo=/bar --bind-mount /one=/two
> > --root-mount /jail001/myroot
> > 
> > could be an enough-generic solution
> > 
> 
> Letting people specify a file with fstab entries or add them as multiple 
> config
> options might be nice too.  That would also allow people to handle things 
> other
> than bind mounts.  LXC does something similar, and builds the root file system
> for you.  
> http://www.linuxcertif.com/man/5/lxc.conf/#MOUNT_POINTS_116h

I had some time today to try this, and it seems to work ok.  Here is a patch
(which includes the previous one) to do some mounts in the new namespace.  It's
pretty simple.  You can specify a file filled with fstab entries, or put them
on the command line.

Something like this:
uwsgi -s :3031 -M -p 1 --uid test --nsfstab /somewhere/uwsgi.fstab --nsmount \
'/etc   /home/test/etc none ro,bind 0 0'

and in /somewhere/uwsgi.fstab you could do something like this:
/bin   /home/test/bin none ro,bind 0 0
/usr   /home/test/usr none ro,bind 0 0
/lib   /home/test/lib none ro,bind 0 0
etc...

The last two digits (frequency and pass number) can be left off if you want,
they're ignored anway.

Chris


diff --git a/lib/linux_ns.c b/lib/linux_ns.c
index 361d72d..b1dc83f 100644
--- a/lib/linux_ns.c
+++ b/lib/linux_ns.c
@@ -1,4 +1,5 @@
 #include "../uwsgi.h"
+#include <mntent.h>
 
 
 extern struct uwsgi_server uwsgi;
@@ -19,6 +20,8 @@ extern struct uwsgi_server uwsgi;
 #define CLONE_NEWNET 0x40000000
 #endif
 
+#define TMP_NS_MOUNT "/.uwsgi_ns_tmp_mountpoint"
+
 void linux_namespace_start(void *argv) {
        for (;;) {
                char stack[PTHREAD_STACK_MIN];
@@ -92,19 +95,53 @@ void linux_namespace_jail() {
        int unmounted = 1;
        char *delim0, *delim1;
 
+       struct uwsgi_string_list *mounts = NULL;
+       struct mntent *entry;
+       FILE   *fstab;
+       if (uwsgi.nsfstab) {
+               fstab = setmntent(uwsgi.nsfstab, "r");
+               while( (entry = getmntent(fstab)) ) {
+                       snprintf(line, sizeof(line), "mount -o %s -t %s %s %s",
+                                       entry->mnt_opts,
+                                       entry->mnt_type,
+                                       entry->mnt_fsname,
+                                       entry->mnt_dir);
+                       uwsgi_log("%s", line);
+                       system(line);
+               }
+               endmntent(fstab);
+       } 
+
+       if (uwsgi.nsmount)
+               mounts = uwsgi.nsmount;
+
+       while(mounts) {
+               fstab = fmemopen(mounts->value, strlen(mounts->value) + 1, "r");
+               entry = getmntent(fstab);
+               snprintf(line, sizeof(line), "mount -o %s -t %s %s %s",
+                               entry->mnt_opts,
+                               entry->mnt_type,
+                               entry->mnt_fsname,
+                               entry->mnt_dir);
+               uwsgi_log("%s", line);
+               system(line);
+               fclose(fstab);
+               mounts = mounts->next;
+       }
+
        if (chdir(uwsgi.ns)) {
                uwsgi_error("chdir()");
                exit(1);
        }
 
        if (strcmp(uwsgi.ns, "/")) {
-               ns_tmp_mountpoint = uwsgi_concat2(uwsgi.ns, 
"/.uwsgi_ns_tmp_mountpoint");
+               ns_tmp_mountpoint = uwsgi_concat2(uwsgi.ns, TMP_NS_MOUNT);
                mkdir(ns_tmp_mountpoint, S_IRWXU);
 
-               ns_tmp_mountpoint2 = uwsgi_concat2(ns_tmp_mountpoint, 
"/.uwsgi_ns_tmp_mountpoint");
+               ns_tmp_mountpoint2 = uwsgi_concat2(ns_tmp_mountpoint, 
TMP_NS_MOUNT);
                mkdir(ns_tmp_mountpoint2, S_IRWXU);
 
-               if (mount(uwsgi.ns, ns_tmp_mountpoint, "none", MS_BIND, NULL)) {
+               if (mount(uwsgi.ns, ns_tmp_mountpoint, "none", MS_BIND|MS_REC, 
NULL)) {
                        uwsgi_error("mount()");
                }
                if (chdir(ns_tmp_mountpoint)) {
@@ -139,19 +176,19 @@ void linux_namespace_jail() {
                        delim0++;
                        delim1 = strchr(delim0, ' ');
                        *delim1 = 0;
-                       if (!strcmp(delim0, "/") || !strcmp(delim0, "/proc"))
-                               continue;
-                       if (!umount(delim0)) {
+                       if ( !strncmp(delim0, TMP_NS_MOUNT, 
strlen(TMP_NS_MOUNT)) 
+                               && !umount(delim0)) {
+
                                unmounted++;
                        }
                }
                fclose(procmounts);
        }
 
-       if (rmdir("/.uwsgi_ns_tmp_mountpoint/.uwsgi_ns_tmp_mountpoint")) {
+       if (rmdir(TMP_NS_MOUNT"/"TMP_NS_MOUNT)) {
                uwsgi_error("rmdir()");
        }
-       if (rmdir("/.uwsgi_ns_tmp_mountpoint")) {
+       if (rmdir(TMP_NS_MOUNT)) {
                uwsgi_error("rmdir()");
        }
 
diff --git a/uwsgi.c b/uwsgi.c
index 19f72d7..1d00dad 100644
--- a/uwsgi.c
+++ b/uwsgi.c
@@ -356,6 +356,8 @@ static struct uwsgi_option uwsgi_base_options[] = {
        {"cgroup-opt", required_argument, 0, "set value in specified cgroup 
option", uwsgi_opt_add_string_list, &uwsgi.cgroup_opt,0},
        {"namespace", required_argument, 0, "run in a new namespace under the 
specified rootfs", uwsgi_opt_set_str, &uwsgi.ns,0},
        {"ns", required_argument, 0, "run in a new namespace under the 
specified rootfs", uwsgi_opt_set_str, &uwsgi.ns,0},
+       {"nsmount", required_argument, 0, "entry in fstab format to be mounted 
in the new namespace", uwsgi_opt_add_string_list, &uwsgi.nsmount,0},
+       {"nsfstab", required_argument, 0, "file containing fstab entries to be 
mounted in the new namespace", uwsgi_opt_set_str, &uwsgi.nsfstab,0},
        {"namespace-net", required_argument, 0, "add network namespace", 
uwsgi_opt_set_str, &uwsgi.ns_net, 0},
        {"ns-net", required_argument, 0, "add network namespace", 
uwsgi_opt_set_str, &uwsgi.ns_net, 0},
 #endif
diff --git a/uwsgi.h b/uwsgi.h
index be23b4f..7a88a85 100644
--- a/uwsgi.h
+++ b/uwsgi.h
@@ -1444,6 +1444,8 @@ struct uwsgi_server {
 #ifdef __linux__
        struct uwsgi_string_list *cgroup;
        struct uwsgi_string_list *cgroup_opt;
+       struct uwsgi_string_list *nsmount;
+       char *nsfstab;
        char *ns;
        char *ns_net;
 #endif
_______________________________________________
uWSGI mailing list
[email protected]
http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi

Reply via email to