]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Make mount paths relative to rootfs
authorMichael Tokarev <mjt@tls.msk.ru>
Fri, 17 Dec 2010 10:43:36 +0000 (11:43 +0100)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Fri, 17 Dec 2010 10:43:36 +0000 (11:43 +0100)
Why not chdir into the root of container right when
the root filesystem is (bind-)mounted, and let all
mount entries to be relative to the container root?

Even more, to warn if lxc.mount[.entry] contains
absolute path for the destination directory (or a
variation of this, absolute and does not start with
container root mount point)?

This way, all mounts will look much more sane, and
it will be much easier to move/clone containers -
by changing only lxc.rootfs.

I do it this way locally since the beginning, by
chdir'ing to the proper directory (rootfs) before
running lxc-start (in a startup script), but this
is now broken in 0.7.3 which bind-mounts rootfs
somewhere in /usr/lib/lxc.

Signed-off-by: Michael Tokarev<mjt@tls.msk.ru>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/conf.c

index 73913c2123ce4de1fa80bcfb9fe4d4590233d729..49361c426d7df2243007287617205fd118608c03 100644 (file)
@@ -910,12 +910,14 @@ static int parse_mntopts(struct mntent *mntent, unsigned long *mntflags,
        return 0;
 }
 
-static int mount_file_entries(FILE *file)
+static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file)
 {
        struct mntent *mntent;
        int ret = -1;
        unsigned long mntflags;
        char *mntdata;
+       char path[MAXPATHLEN];
+       const char *mntdir, *mntroot;
 
        while ((mntent = getmntent(file))) {
 
@@ -927,7 +929,34 @@ static int mount_file_entries(FILE *file)
                        goto out;
                }
 
-               if (mount(mntent->mnt_fsname, mntent->mnt_dir,
+               /* now figure out where to mount it to. */
+               mntdir =  mntent->mnt_dir;
+               mntroot = NULL;
+               if (!rootfs->path) {
+                       /* if we use system root fs,
+                        * the mount is relative to / and can be absolute */
+                       if (mntdir[0] != '/')
+                               mntroot = ""; /* this is "/" */
+               }
+               else {
+                       /* else we have a separate root, mounts are
+                        * relative to it, and absolute paths are risky */
+                       if (mntdir[0] != '/')
+                               /* relative too root mount point */
+                               mntroot = rootfs->mount;
+                       else if (strncmp(mntdir, rootfs->mount, strlen(rootfs->mount)))
+                               WARN("mount target directory '%s' is outside container root",
+                                       mntdir);
+                       else
+                               WARN("mount target directory '%s' is not relative to container root",
+                                       mntdir);
+               }
+               if (mntroot) {
+                       /* make it relative to mntroot */
+                       snprintf(path, sizeof(path), "%s/%s", mntroot, mntdir);
+                       mntdir = path;
+               }
+               if (mount(mntent->mnt_fsname, mntdir,
                          mntent->mnt_type, mntflags & ~MS_REMOUNT, mntdata)) {
                        SYSERROR("failed to mount '%s' on '%s'",
                                         mntent->mnt_fsname, mntent->mnt_dir);
@@ -963,7 +992,7 @@ out:
        return ret;
 }
 
-static int setup_mount(const char *fstab)
+static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab)
 {
        FILE *file;
        int ret;
@@ -977,13 +1006,13 @@ static int setup_mount(const char *fstab)
                return -1;
        }
 
-       ret = mount_file_entries(file);
+       ret = mount_file_entries(rootfs, file);
 
        endmntent(file);
        return ret;
 }
 
-static int setup_mount_entries(struct lxc_list *mount)
+static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount)
 {
        FILE *file;
        struct lxc_list *iterator;
@@ -1003,7 +1032,7 @@ static int setup_mount_entries(struct lxc_list *mount)
 
        rewind(file);
 
-       ret = mount_file_entries(file);
+       ret = mount_file_entries(rootfs, file);
 
        fclose(file);
        return ret;
@@ -1607,12 +1636,12 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
                return -1;
        }
 
-       if (setup_mount(lxc_conf->fstab)) {
+       if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab)) {
                ERROR("failed to setup the mounts for '%s'", name);
                return -1;
        }
 
-       if (setup_mount_entries(&lxc_conf->mount_list)) {
+       if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list)) {
                ERROR("failed to setup the mount entries for '%s'", name);
                return -1;
        }