aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-04-14 13:32:19 -0400
committerTejun Heo <tj@kernel.org>2013-04-14 13:47:02 -0400
commitda1f296fd2bfd5ad3c53d72a1ece593e821cf374 (patch)
tree775d4cac346481dc310f2174f0a8a2c38ed60ccd /kernel/cgroup.c
parent26d5bbe5ba2073fc7ef9e69a55543b2376f5bad0 (diff)
cgroup: make cgroup_path() not print double slashes
While reimplementing cgroup_path(), 65dff759d2 ("cgroup: fix cgroup_path() vs rename() race") introduced a bug where the path of a non-root cgroup would have two slahses at the beginning, which is caused by treating the root cgroup which has the name '/' like non-root cgroups. $ grep systemd /proc/self/cgroup 1:name=systemd://user/root/1 Fix it by special casing root cgroup case and not looping over it in the normal path. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 678a22c75fdb..faf55f59646b 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1811,11 +1811,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
1811 int ret = -ENAMETOOLONG; 1811 int ret = -ENAMETOOLONG;
1812 char *start; 1812 char *start;
1813 1813
1814 if (!cgrp->parent) {
1815 if (strlcpy(buf, "/", buflen) >= buflen)
1816 return -ENAMETOOLONG;
1817 return 0;
1818 }
1819
1814 start = buf + buflen - 1; 1820 start = buf + buflen - 1;
1815 *start = '\0'; 1821 *start = '\0';
1816 1822
1817 rcu_read_lock(); 1823 rcu_read_lock();
1818 while (cgrp) { 1824 do {
1819 const char *name = cgroup_name(cgrp); 1825 const char *name = cgroup_name(cgrp);
1820 int len; 1826 int len;
1821 1827
@@ -1824,15 +1830,12 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
1824 goto out; 1830 goto out;
1825 memcpy(start, name, len); 1831 memcpy(start, name, len);
1826 1832
1827 if (!cgrp->parent)
1828 break;
1829
1830 if (--start < buf) 1833 if (--start < buf)
1831 goto out; 1834 goto out;
1832 *start = '/'; 1835 *start = '/';
1833 1836
1834 cgrp = cgrp->parent; 1837 cgrp = cgrp->parent;
1835 } 1838 } while (cgrp->parent);
1836 ret = 0; 1839 ret = 0;
1837 memmove(buf, start, buf + buflen - start); 1840 memmove(buf, start, buf + buflen - start);
1838out: 1841out: