2
0
mirror of git://github.com/lxc/lxc synced 2025-09-01 19:29:29 +00:00

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: David Ward <david.ward@ll.mit.edu>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
David Ward
2015-06-23 10:57:23 -04:00
committed by Serge Hallyn
parent cd2b3cfe37
commit 14221cbb7d

View File

@@ -1139,24 +1139,24 @@ fail:
* Just create a path for /dev under $lxcpath/$name and in rootfs * Just create a path for /dev under $lxcpath/$name and in rootfs
* If we hit an error, log it but don't fail yet. * If we hit an error, log it but don't fail yet.
*/ */
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;
size_t clen; size_t clen;
char *path; char *path;
INFO("Mounting /dev under %s", root); INFO("Mounting container /dev");
/* $(root) + "/dev/pts" + '\0' */ /* $(rootfs->mount) + "/dev/pts" + '\0' */
clen = strlen(root) + 9; clen = (rootfs->path ? strlen(rootfs->mount) : 0) + 9;
path = alloca(clen); path = alloca(clen);
ret = snprintf(path, clen, "%s/dev", root); ret = snprintf(path, clen, "%s/dev", rootfs->path ? rootfs->mount : "");
if (ret < 0 || ret >= clen) if (ret < 0 || ret >= clen)
return -1; return -1;
if (!dir_exists(path)) { if (!dir_exists(path)) {
WARN("No /dev on container rootfs."); WARN("No /dev in container.");
WARN("Proceeding without autodev setup"); WARN("Proceeding without autodev setup");
return 0; return 0;
} }
@@ -1168,7 +1168,7 @@ static int mount_autodev(const char *name, char *root, const char *lxcpath)
INFO("Mounted tmpfs onto %s", path); INFO("Mounted tmpfs onto %s", path);
ret = snprintf(path, clen, "%s/dev/pts", root); ret = snprintf(path, clen, "%s/dev/pts", rootfs->path ? rootfs->mount : "");
if (ret < 0 || ret >= clen) if (ret < 0 || ret >= clen)
return -1; return -1;
@@ -1184,7 +1184,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;
} }
@@ -1205,16 +1205,16 @@ 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 fill_autodev(const char *root) static int fill_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;
@@ -1223,11 +1223,11 @@ static int fill_autodev(const char *root)
if (!dir_exists(path)) // ignore, just don't try to fill in if (!dir_exists(path)) // ignore, just don't try to fill in
return 0; return 0;
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));
@@ -1255,7 +1255,7 @@ static int fill_autodev(const char *root)
} }
umask(cmask); umask(cmask);
INFO("Populated /dev under %s", root); INFO("Populated container /dev");
return 0; return 0;
} }
@@ -3725,7 +3725,7 @@ int lxc_setup(struct lxc_handler *handler)
} }
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;
} }
@@ -3775,7 +3775,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 (fill_autodev(lxc_conf->rootfs.mount)) { if (fill_autodev(&lxc_conf->rootfs)) {
ERROR("failed to populate /dev in the container"); ERROR("failed to populate /dev in the container");
return -1; return -1;
} }