From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> The LXC driver currently has code to detect cgroups mounts and then re-mount them inside the new root filesystem. Replace this fragile code with a call to virCgroupIsolateMount. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/lxc/lxc_container.c | 237 ++---------------------------------------------- 1 file changed, 8 insertions(+), 229 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index ab27a92..b0367e4 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1735,227 +1735,6 @@ static int lxcContainerSetupAllHostdevs(virDomainDefPtr vmDef, } -struct lxcContainerCGroup { - const char *dir; - const char *linkDest; -}; - - -static void lxcContainerCGroupFree(struct lxcContainerCGroup *mounts, - size_t nmounts) -{ - size_t i; - - if (!mounts) - return; - - for (i = 0 ; i < nmounts ; i++) { - VIR_FREE(mounts[i].dir); - VIR_FREE(mounts[i].linkDest); - } - VIR_FREE(mounts); -} - - -static int lxcContainerIdentifyCGroups(struct lxcContainerCGroup **mountsret, - size_t *nmountsret, - char **root) -{ - FILE *procmnt = NULL; - struct mntent mntent; - struct dirent *dent; - char mntbuf[1024]; - int ret = -1; - struct lxcContainerCGroup *mounts = NULL; - size_t nmounts = 0; - DIR *dh = NULL; - char *path = NULL; - - *mountsret = NULL; - *nmountsret = 0; - *root = NULL; - - VIR_DEBUG("Finding cgroups mount points of type cgroup"); - - if (!(procmnt = setmntent("/proc/mounts", "r"))) { - virReportSystemError(errno, "%s", - _("Failed to read /proc/mounts")); - return -1; - } - - while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) { - VIR_DEBUG("Got %s", mntent.mnt_dir); - if (STRNEQ(mntent.mnt_type, "cgroup")) - continue; - - if (!*root) { - char *tmp; - if (!(*root = strdup(mntent.mnt_dir))) { - virReportOOMError(); - goto cleanup; - } - tmp = strrchr(*root, '/'); - *tmp = '\0'; - } else if (!STRPREFIX(mntent.mnt_dir, *root)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cgroup %s is not mounted under %s"), - mntent.mnt_dir, *root); - goto cleanup; - } - - /* Skip named mounts with no controller since they're - * for application use only ie systemd */ - if (strstr(mntent.mnt_opts, "name=")) - continue; - - if (VIR_EXPAND_N(mounts, nmounts, 1) < 0) { - virReportOOMError(); - goto cleanup; - } - if (!(mounts[nmounts-1].dir = strdup(mntent.mnt_dir))) { - virReportOOMError(); - goto cleanup; - } - VIR_DEBUG("Grabbed '%s'", mntent.mnt_dir); - } - - if (!*root) { - VIR_DEBUG("No mounted cgroups found"); - ret = 0; - goto cleanup; - } - - VIR_DEBUG("Checking for symlinks in %s", *root); - if (!(dh = opendir(*root))) { - virReportSystemError(errno, - _("Unable to read directory %s"), - *root); - goto cleanup; - } - - while ((dent = readdir(dh)) != NULL) { - ssize_t rv; - /* The cgroups links are just relative to the local - * dir so we don't need a large buf */ - char linkbuf[100]; - - if (dent->d_name[0] == '.') - continue; - - VIR_DEBUG("Checking entry %s", dent->d_name); - if (virAsprintf(&path, "%s/%s", *root, dent->d_name) < 0) { - virReportOOMError(); - goto cleanup; - } - - if ((rv = readlink(path, linkbuf, sizeof(linkbuf)-1)) < 0) { - if (errno != EINVAL) { - virReportSystemError(errno, - _("Unable to resolve link %s"), - path); - VIR_FREE(path); - goto cleanup; - } - /* Ok not a link */ - VIR_FREE(path); - } else { - linkbuf[rv] = '\0'; - VIR_DEBUG("Got a link %s to %s", path, linkbuf); - if (VIR_EXPAND_N(mounts, nmounts, 1) < 0) { - virReportOOMError(); - goto cleanup; - } - if (!(mounts[nmounts-1].linkDest = strdup(linkbuf))) { - virReportOOMError(); - goto cleanup; - } - mounts[nmounts-1].dir = path; - path = NULL; - } - } - - *mountsret = mounts; - *nmountsret = nmounts; - ret = 0; - -cleanup: - closedir(dh); - endmntent(procmnt); - VIR_FREE(path); - - if (ret < 0) { - lxcContainerCGroupFree(mounts, nmounts); - VIR_FREE(*root); - } - return ret; -} - - -static int lxcContainerMountCGroups(struct lxcContainerCGroup *mounts, - size_t nmounts, - const char *root, - char *sec_mount_options) -{ - size_t i; - char *opts = NULL; - - VIR_DEBUG("Mounting cgroups at '%s'", root); - - if (virFileMakePath(root) < 0) { - virReportSystemError(errno, - _("Unable to create directory %s"), - root); - return -1; - } - - if (virAsprintf(&opts, - "mode=755,size=65536%s", sec_mount_options) < 0) { - virReportOOMError(); - return -1; - } - - if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { - VIR_FREE(opts); - virReportSystemError(errno, - _("Failed to mount %s on %s type %s"), - "tmpfs", root, "tmpfs"); - return -1; - } - VIR_FREE(opts); - - for (i = 0 ; i < nmounts ; i++) { - if (mounts[i].linkDest) { - VIR_DEBUG("Link mount point '%s' to '%s'", - mounts[i].dir, mounts[i].linkDest); - if (symlink(mounts[i].linkDest, mounts[i].dir) < 0) { - virReportSystemError(errno, - _("Unable to symlink directory %s to %s"), - mounts[i].dir, mounts[i].linkDest); - return -1; - } - } else { - VIR_DEBUG("Create mount point '%s'", mounts[i].dir); - if (virFileMakePath(mounts[i].dir) < 0) { - virReportSystemError(errno, - _("Unable to create directory %s"), - mounts[i].dir); - return -1; - } - - if (mount("cgroup", mounts[i].dir, "cgroup", - 0, mounts[i].dir + strlen(root) + 1) < 0) { - virReportSystemError(errno, - _("Failed to mount cgroup on '%s'"), - mounts[i].dir); - return -1; - } - } - } - - return 0; -} - - /* Got a FS mapped to /, we're going the pivot_root * approach to do a better-chroot-than-chroot * this is based on this thread http://lkml.org/lkml/2008/3/5/29 @@ -1966,10 +1745,9 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, size_t nttyPaths, virSecurityManagerPtr securityDriver) { - struct lxcContainerCGroup *mounts = NULL; - size_t nmounts = 0; + virCgroupPtr cgroup = NULL; + int rc; int ret = -1; - char *cgroupRoot = NULL; char *sec_mount_options; if (!(sec_mount_options = virSecurityManagerGetMountOptions(securityDriver, vmDef))) @@ -1977,8 +1755,11 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, /* Before pivoting we need to identify any * cgroups controllers that are mounted */ - if (lxcContainerIdentifyCGroups(&mounts, &nmounts, &cgroupRoot) < 0) + if ((rc = virCgroupNewSelf(&cgroup)) != 0) { + virReportSystemError(-rc, "%s", + _("Cannot identify cgroup placement")); goto cleanup; + } /* Ensure the root filesystem is mounted */ if (lxcContainerPrepareRoot(vmDef, root) < 0) @@ -2017,8 +1798,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, /* Now we can re-mount the cgroups controllers in the * same configuration as before */ - if (lxcContainerMountCGroups(mounts, nmounts, - cgroupRoot, sec_mount_options) < 0) + if (virCgroupIsolateMount(cgroup, "/.oldroot/", sec_mount_options) < 0) goto cleanup; /* Mounts /dev/pts */ @@ -2048,8 +1828,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, ret = 0; cleanup: - lxcContainerCGroupFree(mounts, nmounts); - VIR_FREE(cgroupRoot); + virCgroupFree(&cgroup); VIR_FREE(sec_mount_options); return ret; } -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list