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