Commit 5b27808f by David Ward Committed by Stéphane Graber

Allow autodev without a rootfs

A container without a rootfs is useful for running a collection of processes in separate namespaces (to provide separate networking as an example), while sharing the host filesystem (except for specific paths that are re-mounted as needed). For multiple processes to run automatically when such a container is started, it can be launched using lxc-start, and a separate instance of systemd can manage just the processes inside the container. (This assumes that the path to the systemd unit files is re-mounted and only contains the services that should run inside the container.) For this use case, autodev should be permitted for a container that does not have a rootfs. Signed-off-by: 's avatarDavid Ward <david.ward@ll.mit.edu> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 1e9fd6b0
...@@ -1411,7 +1411,7 @@ static char *mk_devtmpfs(const char *name, char *path, const char *lxcpath) ...@@ -1411,7 +1411,7 @@ static char *mk_devtmpfs(const char *name, char *path, const char *lxcpath)
* Do we want to add options for max size of /dev and a file to * Do we want to add options for max size of /dev and a file to
* specify which devices to create? * specify which devices to create?
*/ */
static int mount_autodev(const char *name, char *root, const char *lxcpath) static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, const char *lxcpath)
{ {
int ret; int ret;
struct stat s; struct stat s;
...@@ -1419,13 +1419,13 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath) ...@@ -1419,13 +1419,13 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath)
char host_path[MAXPATHLEN]; char host_path[MAXPATHLEN];
char devtmpfs_path[MAXPATHLEN]; char devtmpfs_path[MAXPATHLEN];
INFO("Mounting /dev under %s", root); INFO("Mounting container /dev");
ret = snprintf(host_path, MAXPATHLEN, "%s/%s/rootfs.dev", lxcpath, name); ret = snprintf(host_path, MAXPATHLEN, "%s/%s/rootfs.dev", lxcpath, name);
if (ret < 0 || ret > MAXPATHLEN) if (ret < 0 || ret > MAXPATHLEN)
return -1; return -1;
ret = snprintf(path, MAXPATHLEN, "%s/dev", root); ret = snprintf(path, MAXPATHLEN, "%s/dev", rootfs->path ? rootfs->mount : "");
if (ret < 0 || ret > MAXPATHLEN) if (ret < 0 || ret > MAXPATHLEN)
return -1; return -1;
...@@ -1459,10 +1459,10 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath) ...@@ -1459,10 +1459,10 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath)
} }
} }
if (ret) { if (ret) {
SYSERROR("Failed to mount /dev at %s", root); SYSERROR("Failed to mount container /dev");
return -1; return -1;
} }
ret = snprintf(path, MAXPATHLEN, "%s/dev/pts", root); ret = snprintf(path, MAXPATHLEN, "%s/dev/pts", rootfs->path ? rootfs->mount : "");
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return -1; return -1;
/* /*
...@@ -1477,7 +1477,7 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath) ...@@ -1477,7 +1477,7 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath)
} }
} }
INFO("Mounted /dev under %s", root); INFO("Mounted container /dev");
return 0; return 0;
} }
...@@ -1498,26 +1498,26 @@ static const struct lxc_devs lxc_devs[] = { ...@@ -1498,26 +1498,26 @@ static const struct lxc_devs lxc_devs[] = {
{ "console", S_IFCHR | S_IRUSR | S_IWUSR, 5, 1 }, { "console", S_IFCHR | S_IRUSR | S_IWUSR, 5, 1 },
}; };
static int setup_autodev(const char *root) static int setup_autodev(const struct lxc_rootfs *rootfs)
{ {
int ret; int ret;
char path[MAXPATHLEN]; char path[MAXPATHLEN];
int i; int i;
mode_t cmask; mode_t cmask;
INFO("Creating initial consoles under %s/dev", root); INFO("Creating initial consoles under container /dev");
ret = snprintf(path, MAXPATHLEN, "%s/dev", root); ret = snprintf(path, MAXPATHLEN, "%s/dev", rootfs->path ? rootfs->mount : "");
if (ret < 0 || ret >= MAXPATHLEN) { if (ret < 0 || ret >= MAXPATHLEN) {
ERROR("Error calculating container /dev location"); ERROR("Error calculating container /dev location");
return -1; return -1;
} }
INFO("Populating /dev under %s", root); INFO("Populating container /dev");
cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH); cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH);
for (i = 0; i < sizeof(lxc_devs) / sizeof(lxc_devs[0]); i++) { for (i = 0; i < sizeof(lxc_devs) / sizeof(lxc_devs[0]); i++) {
const struct lxc_devs *d = &lxc_devs[i]; const struct lxc_devs *d = &lxc_devs[i];
ret = snprintf(path, MAXPATHLEN, "%s/dev/%s", root, d->name); ret = snprintf(path, MAXPATHLEN, "%s/dev/%s", rootfs->path ? rootfs->mount : "", d->name);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return -1; return -1;
ret = mknod(path, d->mode, makedev(d->maj, d->min)); ret = mknod(path, d->mode, makedev(d->maj, d->min));
...@@ -1528,7 +1528,7 @@ static int setup_autodev(const char *root) ...@@ -1528,7 +1528,7 @@ static int setup_autodev(const char *root)
} }
umask(cmask); umask(cmask);
INFO("Populated /dev under %s", root); INFO("Populated container /dev");
return 0; return 0;
} }
...@@ -3887,7 +3887,7 @@ struct start_args { ...@@ -3887,7 +3887,7 @@ struct start_args {
#define MAX_SYMLINK_DEPTH 32 #define MAX_SYMLINK_DEPTH 32
static int check_autodev( const char *rootfs, void *data ) static int check_autodev( const struct lxc_rootfs *rootfs, void *data )
{ {
struct start_args *arg = data; struct start_args *arg = data;
int ret; int ret;
...@@ -3898,10 +3898,9 @@ static int check_autodev( const char *rootfs, void *data ) ...@@ -3898,10 +3898,9 @@ static int check_autodev( const char *rootfs, void *data )
char abs_path[MAXPATHLEN]; char abs_path[MAXPATHLEN];
char *command = "/sbin/init"; char *command = "/sbin/init";
if (rootfs == NULL || strlen(rootfs) == 0) if (!rootfs->path)
return -2; *absrootfs = '\0';
else if (!realpath(rootfs->mount, absrootfs))
if (!realpath(rootfs, absrootfs))
return -2; return -2;
if( arg && arg->argv[0] ) { if( arg && arg->argv[0] ) {
...@@ -4134,11 +4133,11 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -4134,11 +4133,11 @@ int lxc_setup(struct lxc_handler *handler)
} }
if (lxc_conf->autodev < 0) { if (lxc_conf->autodev < 0) {
lxc_conf->autodev = check_autodev(lxc_conf->rootfs.mount, data); lxc_conf->autodev = check_autodev(&lxc_conf->rootfs, data);
} }
if (lxc_conf->autodev > 0) { if (lxc_conf->autodev > 0) {
if (mount_autodev(name, lxc_conf->rootfs.mount, lxcpath)) { if (mount_autodev(name, &lxc_conf->rootfs, lxcpath)) {
ERROR("failed to mount /dev in the container"); ERROR("failed to mount /dev in the container");
return -1; return -1;
} }
...@@ -4185,7 +4184,7 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -4185,7 +4184,7 @@ int lxc_setup(struct lxc_handler *handler)
ERROR("failed to run autodev hooks for container '%s'.", name); ERROR("failed to run autodev hooks for container '%s'.", name);
return -1; return -1;
} }
if (setup_autodev(lxc_conf->rootfs.mount)) { if (setup_autodev(&lxc_conf->rootfs)) {
ERROR("failed to populate /dev in the container"); ERROR("failed to populate /dev in the container");
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment