fix pivot_root temporary directory

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>
This commit is contained in:
Daniel Lezcano 2010-05-10 11:50:09 +02:00 committed by Daniel Lezcano
parent 5c2940600e
commit 1b09f2c057
3 changed files with 46 additions and 8 deletions

View File

@ -51,10 +51,10 @@
#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 */

View 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;
}

View 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);