[libvirt] [PATCH v3 16/16] Replace LXC cgroup mount code with call to virCgroupIsolateMount

Daniel P. Berrange berrange at redhat.com
Wed Apr 10 10:08:25 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

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 at redhat.com>
---
 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




More information about the libvir-list mailing list