diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index d4faf3c78516d948d5af3a6f13f3dec2d2025be5..d9734b50ff7a4c8e1c679b54fa3d28054707c8d4 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -683,7 +683,7 @@ err: } -static int lxcContainerMountBasicFS(char *sec_mount_options) +static int lxcContainerMountBasicFS(void) { const struct { const char *src; @@ -709,9 +709,8 @@ static int lxcContainerMountBasicFS(char *sec_mount_options) #endif }; int i, rc = -1; - char *opts = NULL; - VIR_DEBUG("Mounting basic filesystems sec_mount_options=%s", sec_mount_options); + VIR_DEBUG("Mounting basic filesystems"); for (i = 0; i < ARRAY_CARDINALITY(mnts); i++) { const char *srcpath = NULL; @@ -750,31 +749,10 @@ static int lxcContainerMountBasicFS(char *sec_mount_options) } } - /* - * tmpfs is limited to 64kb, since we only have device nodes in there - * and don't want to DOS the entire OS RAM usage - */ - - if (virAsprintf(&opts, - "mode=755,size=65536%s", sec_mount_options) < 0) { - virReportOOMError(); - goto cleanup; - } - - VIR_DEBUG("Mount devfs on /dev type=tmpfs flags=%x, opts=%s", - MS_NOSUID, opts); - if (mount("devfs", "/dev", "tmpfs", MS_NOSUID, opts) < 0) { - virReportSystemError(errno, - _("Failed to mount %s on %s type %s (%s)"), - "devfs", "/dev", "tmpfs", opts); - goto cleanup; - } - rc = 0; cleanup: VIR_DEBUG("rc=%d", rc); - VIR_FREE(opts); return rc; } @@ -811,6 +789,30 @@ static int lxcContainerMountProcFuse(virDomainDefPtr def ATTRIBUTE_UNUSED, } #endif +static int lxcContainerMountFSDev(virDomainDefPtr def, + const char *stateDir) +{ + int ret; + char *path = NULL; + + VIR_DEBUG("Mount /dev/ stateDir=%s", stateDir); + + if ((ret = virAsprintf(&path, "/.oldroot/%s/%s.dev", + stateDir, def->name)) < 0) + return ret; + + VIR_DEBUG("Tring to move %s to /dev", path); + + if ((ret = mount(path, "/dev", NULL, MS_MOVE, NULL)) < 0) { + virReportSystemError(errno, + _("Failed to mount %s on /dev"), + path); + } + + VIR_FREE(path); + return ret; +} + static int lxcContainerMountFSDevPTS(virDomainDefPtr def, const char *stateDir) { @@ -847,21 +849,9 @@ cleanup: return ret; } -static int lxcContainerPopulateDevices(char **ttyPaths, size_t nttyPaths) +static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths) { size_t i; - const struct { - int maj; - int min; - mode_t mode; - const char *path; - } devs[] = { - { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL, 0666, "/dev/null" }, - { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO, 0666, "/dev/zero" }, - { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL, 0666, "/dev/full" }, - { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM, 0666, "/dev/random" }, - { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" }, - }; const struct { const char *src; const char *dst; @@ -872,18 +862,6 @@ static int lxcContainerPopulateDevices(char **ttyPaths, size_t nttyPaths) { "/proc/self/fd", "/dev/fd" }, }; - /* Populate /dev/ with a few important bits */ - for (i = 0; i < ARRAY_CARDINALITY(devs); i++) { - dev_t dev = makedev(devs[i].maj, devs[i].min); - if (mknod(devs[i].path, S_IFCHR, dev) < 0 || - chmod(devs[i].path, devs[i].mode)) { - virReportSystemError(errno, - _("Failed to make device %s"), - devs[i].path); - return -1; - } - } - for (i = 0; i < ARRAY_CARDINALITY(links); i++) { if (symlink(links[i].src, links[i].dst) < 0) { virReportSystemError(errno, @@ -1802,7 +1780,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, goto cleanup; /* Mounts the core /proc, /sys, etc filesystems */ - if (lxcContainerMountBasicFS(sec_mount_options) < 0) + if (lxcContainerMountBasicFS() < 0) goto cleanup; /* Mounts /proc/meminfo etc sysinfo */ @@ -1814,12 +1792,16 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, if (virCgroupIsolateMount(cgroup, "/.oldroot/", sec_mount_options) < 0) goto cleanup; + /* Mounts /dev */ + if (lxcContainerMountFSDev(vmDef, stateDir) < 0) + goto cleanup; + /* Mounts /dev/pts */ if (lxcContainerMountFSDevPTS(vmDef, stateDir) < 0) goto cleanup; - /* Populates device nodes in /dev/ */ - if (lxcContainerPopulateDevices(ttyPaths, nttyPaths) < 0) + /* Setup device nodes in /dev/ */ + if (lxcContainerSetupDevices(ttyPaths, nttyPaths) < 0) goto cleanup; /* Sets up any non-root mounts from guest config */ diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 0ba6a90e21547234e049a30985850672164b811e..be6f6ebbd14ac57573ca0a93f0f96f318283c9fa 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -1192,6 +1192,103 @@ cleanup: return ret; } +static int virLXCControllerSetupDev(virLXCControllerPtr ctrl) +{ + char *mount_options = NULL; + char *opts = NULL; + char *dev = NULL; + int ret = -1; + + VIR_DEBUG("Setting up /dev/ for container"); + + mount_options = virSecurityManagerGetMountOptions(ctrl->securityManager, + ctrl->def); + + if (virAsprintf(&dev, "/%s/%s.dev", + LXC_STATE_DIR, ctrl->def->name) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (virFileMakePath(dev) < 0) { + virReportSystemError(errno, + _("Failed to make path %s"), dev); + goto cleanup; + } + + /* + * tmpfs is limited to 64kb, since we only have device nodes in there + * and don't want to DOS the entire OS RAM usage + */ + + if (virAsprintf(&opts, + "mode=755,size=65536%s", mount_options) < 0) { + virReportOOMError(); + goto cleanup; + } + + VIR_DEBUG("Mount devfs on %s type=tmpfs flags=%x, opts=%s", + dev, MS_NOSUID, opts); + if (mount("devfs", dev, "tmpfs", MS_NOSUID, opts) < 0) { + virReportSystemError(errno, + _("Failed to mount devfs on %s type %s (%s)"), + dev, "tmpfs", opts); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FREE(opts); + VIR_FREE(mount_options); + VIR_FREE(dev); + return ret; +} + +static int virLXCControllerPopulateDevices(virLXCControllerPtr ctrl) +{ + size_t i; + int ret = -1; + char *path = NULL; + const struct { + int maj; + int min; + mode_t mode; + const char *path; + } devs[] = { + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL, 0666, "/null" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO, 0666, "/zero" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL, 0666, "/full" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM, 0666, "/random" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/urandom" }, + }; + + if (virLXCControllerSetupDev(ctrl) < 0) + goto cleanup; + + /* Populate /dev/ with a few important bits */ + for (i = 0; i < ARRAY_CARDINALITY(devs); i++) { + if (virAsprintf(&path, "/%s/%s.dev/%s", + LXC_STATE_DIR, ctrl->def->name, devs[i].path) < 0) { + virReportOOMError(); + goto cleanup; + } + + dev_t dev = makedev(devs[i].maj, devs[i].min); + if (mknod(path, S_IFCHR, dev) < 0 || + chmod(path, devs[i].mode)) { + virReportSystemError(errno, + _("Failed to make device %s"), + path); + goto cleanup; + } + VIR_FREE(path); + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} /** @@ -1594,6 +1691,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl) if (virLXCControllerSetupDevPTS(ctrl) < 0) goto cleanup; + if (virLXCControllerPopulateDevices(ctrl) < 0) + goto cleanup; + if (virLXCControllerSetupFuse(ctrl) < 0) goto cleanup;