When creating an unprivileged container, you must have a cgroup
fs mounted named lxc.  For instance

        mkdir /sys/fs/cgroup/lxc
        mount -t cgroup -o none,name=lxc none /sys/fs/cgroup/lxc
        mkdir /sys/fs/cgroup/lxc/$USER
        chown -R $USER /sys/fs/cgroup/lxc/$USER

You could also compose the freezer subsystem with the lxc one to
not lose freezer support.  When I tested that I was able to do
unprivileged lxc-freeze and lxc-unfreeze of my own containers.

Unprivileged containers will ONLY enter a per-container cgroup for
the lxc cgroup.  If you wish to set other limits, you need privilege
to do so anyway, so you can do so out of band with a separate
(privileged) set of utilities.  For instance you can confine the
whole user to a cpuset with pam_cgroup, or allow the user to
create and enter cgroups of certain subsystems if it makes sense.

(For reference, this is done in response to upstream cgroup kernel
maintainer specifically recmomending against delegating cgroup
administration to users.  It is safe for some but not all cgroups,
and it does not fit in with the future plans)

Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
---
 src/lxc/cgroup.c | 58 ++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
index 654e55a..ff3a090 100644
--- a/src/lxc/cgroup.c
+++ b/src/lxc/cgroup.c
@@ -579,6 +579,24 @@ static int record_visited(char *opts, char **visitedp, 
char *allcgroups)
        return 0;
 }
 
+static inline bool filter_cgroup_mntent(struct mntent *m)
+{
+       if (strcmp(m->mnt_type, "cgroup") != 0)
+               return false;
+       /*
+        * if we are unprivileged, then only use one named 'lxc'
+        * otherwise, use all the ones which have subsystems
+        */
+       if (geteuid() == 0) {
+               if (!mount_has_subsystem(m))
+                       return false;
+       } else {
+               if (!hasmntopt(m, "name=lxc"))
+                       return false;
+       }
+       return true;
+}
+
 /*
  * Make sure the 'cgroup group' exists, so that we don't have to worry about
  * that later.
@@ -605,10 +623,7 @@ static int create_lxcgroups(const char *lxcgroup)
        }
 
        while ((getmntent_r(file, &mntent_r, buf, sizeof(buf)))) {
-
-               if (strcmp(mntent_r.mnt_type, "cgroup"))
-                       continue;
-               if (!mount_has_subsystem(&mntent_r))
+               if (!filter_cgroup_mntent(&mntent_r))
                        continue;
 
                /*
@@ -698,9 +713,7 @@ again:
 
        while ((getmntent_r(file, &mntent_r, buf, sizeof(buf)))) {
 
-               if (strcmp(mntent_r.mnt_type, "cgroup"))
-                       continue;
-               if (!mount_has_subsystem(&mntent_r))
+               if (!filter_cgroup_mntent(&mntent_r))
                        continue;
 
                /* make sure we haven't checked this subsystem already */
@@ -771,10 +784,9 @@ int lxc_cgroup_enter(const char *cgpath, pid_t pid)
        }
 
        while ((getmntent_r(file, &mntent_r, buf, sizeof(buf)))) {
-               if (strcmp(mntent_r.mnt_type, "cgroup"))
-                       continue;
-               if (!mount_has_subsystem(&mntent_r))
+               if (!filter_cgroup_mntent(&mntent_r))
                        continue;
+
                ret = snprintf(path, MAXPATHLEN, "%s/%s/tasks",
                               mntent_r.mnt_dir, cgpath);
                if (ret < 0 || ret >= MAXPATHLEN) {
@@ -881,9 +893,7 @@ int lxc_cgroup_destroy(const char *cgpath)
        }
 
        while ((getmntent_r(file, &mntent_r, buf, sizeof(buf)))) {
-               if (strcmp(mntent_r.mnt_type, "cgroup"))
-                       continue;
-               if (!mount_has_subsystem(&mntent_r))
+               if (!filter_cgroup_mntent(&mntent_r))
                        continue;
 
                err = lxc_one_cgroup_destroy(&mntent_r, cgpath);
@@ -951,14 +961,13 @@ bool is_in_subcgroup(int pid, const char *subsystem, 
const char *cgpath)
 
 /*
  * Return cgroup of current task.
- * This assumes that task is in the same cgroup for each controller.  This
- * may or may not *always* be a reasonable assumption - it generally is,
- * and handling or at least checking for this condition is a TODO.
+ * If we are root, then return the 'devices' cgroup.
+ * If we are not, then return the 'name=lxc' cgroup.
  */
 int lxc_curcgroup(char *cgroup, int inlen)
 {
        FILE *f;
-       char *line = NULL, *p, *p2;
+       char *line = NULL, *p, *p2, *needle;
        int ret = 0;
        size_t len;
 
@@ -967,12 +976,19 @@ int lxc_curcgroup(char *cgroup, int inlen)
                return -1;
 
        while (getline(&line, &len, f) != -1) {
-               if (strstr(line, ":freezer:") == NULL && strstr(line, 
":devices:") == NULL)
-                       continue;
-               p = rindex(line, ':');
+               p = index(line, ':');
                if (!p)
                        continue;
-               p++;
+               p2 = index(p+1, ':');
+               if (!p2)
+                       continue;
+               if (geteuid() == 0)
+                       needle = strstr(p, "devices");
+               else
+                       needle = strstr(p, "name=lxc");
+               if (needle == NULL || needle > p2)
+                       continue;
+               p = p2 + 1;
                len = strlen(p) + 1;
                p2 = p + len - 2;
                while (*p2 == '\n') { len--; *p2 = '\0'; p2--; }
-- 
1.8.3.2


------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to