]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
fix pivot_root temporary directory
authorDaniel Lezcano <daniel.lezcano@free.fr>
Mon, 10 May 2010 09:50:09 +0000 (11:50 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Mon, 10 May 2010 09:50:09 +0000 (11:50 +0200)
First of all, when trying to start a container in a read-only root
lxc-start complains:
  lxc-start: Read-only file system - can't make temporary mountpoint

This is in conf.c:setup_rootfs_pivot_root() function.  That function
uses optional parameter "lxc.pivotdir", or creates (and later removes)
a temporary directory for pivot_root.  Obviously there's no way to
create a directory in a read-only filesystem.

But lxc.pivotdir does not work either. In the function mentioned above
it is used with leading dot (eg. if I specify "lxc.pivotdir=pivot" in
the config file the pivot_root() syscall will be made to ".pivot" with
leading dot, not to "pivot"), but later on it is used without that dot,
and fails:

  lxc-start: No such file or directory - failed to open /pivot/proc/mounts
  lxc-start: No such file or directory - failed to read or parse mount list '/pivot/proc/mounts'
  lxc-start: failed to pivot_root to '/stage/t'

(that's with "lxc.pivotdir = pivot" in the config file).  After symlinking
pivot to .pivot it still fails:

  lxc-start: Device or resource busy - could not unmount old rootfs
  lxc-start: failed to pivot_root to '/stage/t'

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

index b27a11d14ea91ea6b1abb039316aa1f1b32c3426..d6dd2e20a9d1d16876f8b93f8e96cc35a03d4b4b 100644 (file)
 #include "error.h"
 #include "parse.h"
 #include "config.h"
-
-#include <lxc/conf.h>
-#include <lxc/log.h>
-#include <lxc/lxc.h>   /* for lxc_cgroup_set() */
+#include "utils.h"
+#include "conf.h"
+#include "log.h"
+#include "lxc.h"       /* for lxc_cgroup_set() */
 
 lxc_log_define(lxc_conf, lxc);
 
@@ -488,12 +488,21 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
                }
 
                pivotdir_is_temp = 1;
-       }
-       else {
-               snprintf(path, sizeof(path), ".%s", pivotdir);
+       } else {
+
+               snprintf(path, sizeof(path), "%s/%s", rootfs, pivotdir);
+
+               if (access(path, F_OK)) {
+                       if (mkdir_p(path, 0755)) {
+                               SYSERROR("failed to create pivotdir '%s'", path);
+                               return -1;
+                       }
+
+                       DEBUG("created '%s' directory", path);
+               }
        }
 
-       DEBUG("temporary mountpoint for old rootfs is '%s'", path);
+       DEBUG("mountpoint for old rootfs is '%s'", path);
 
        /* pivot_root into our new root fs */
 
index 5f3745c7884f3bce7834ada3a76a6a4f5b74b8a9..6279d77b5437807fcde679713b9dee8c488b32a4 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/mount.h>
 #include <dirent.h>
 #include <fcntl.h>
+#include <libgen.h>
 
 #include "log.h"
 
@@ -163,3 +164,30 @@ extern int get_u16(ushort *val, const char *arg, int base)
        return 0;
 }
 
+extern int mkdir_p(char *dir, mode_t mode)
+{
+        int ret;
+        char *d;
+
+        if (!strcmp(dir, "/"))
+                return 0;
+
+        d = strdup(dir);
+        if (!d)
+                return -1;
+
+        ret = mkdir_p(dirname(d), mode);
+        free(d);
+        if (ret)
+                return -1;
+
+        if (!access(dir, F_OK))
+                return 0;
+
+        if (mkdir(dir, mode)) {
+                SYSERROR("failed to create directory '%s'\n", dir);
+                return -1;
+        }
+
+        return 0;
+}
index 9fd5815b5c7bb184fb807dd0297c05b18c7b80c9..114b6688baa7e7dfd4c419cdb2940766b0de7833 100644 (file)
@@ -53,3 +53,4 @@
 extern int lxc_copy_file(const char *src, const char *dst);
 extern int lxc_setup_fs(void);
 extern int get_u16(ushort *val, const char *arg, int base);
+extern int mkdir_p(const char *dir, mode_t mode);