[CRIU] [PATCHv2 1/2] zdtm/cgroup_ifpriomap: Find cgroup's controller's name to mount
Dmitry Safonov
0x7f454c46 at gmail.com
Sun Feb 11 17:00:51 MSK 2018
I've also dropped `noauto' in this patch, reverting the
commit be98273cf137 ("zdtm: mark static/cgroup_ifpriomap as noauto")
Don't see any sense to separate it as another patch.
Fixes: #383
Signed-off-by: Dmitry Safonov <0x7f454c46 at gmail.com>
---
char c => int c
Because of warning on Aarch Travis build
(comparison EOF == -1 with char)
test/zdtm/static/cgroup_ifpriomap.c | 96 ++++++++++++++++++++++++++++++++--
test/zdtm/static/cgroup_ifpriomap.desc | 2 +-
test/zdtm/static/cgroup_ifpriomap.hook | 9 +++-
3 files changed, 101 insertions(+), 6 deletions(-)
diff --git a/test/zdtm/static/cgroup_ifpriomap.c b/test/zdtm/static/cgroup_ifpriomap.c
index d14508060194..ac186eaf05fd 100644
--- a/test/zdtm/static/cgroup_ifpriomap.c
+++ b/test/zdtm/static/cgroup_ifpriomap.c
@@ -42,12 +42,12 @@ static int mount_cg(const char *controller)
pr_perror("Can't make dir");
return -1;
}
- if (mkdir(mnt_point, 0700) < 0) {
+ if (mkdir(mnt_point, 0700) < 0 && errno != EEXIST) {
pr_perror("Can't make dir `%s'", mnt_point);
return -1;
}
if (mount("none", mnt_point, "cgroup", 0, controller)) {
- pr_perror("Can't mount cgroups");
+ pr_perror("Can't mount `%s' cgroup", controller);
goto err_rm;
}
if (mkdir(subdir, 0700) < 0 && errno != EEXIST) {
@@ -224,20 +224,107 @@ static int compare_maps(void)
return 0;
}
+static ssize_t parse_cgroup_line(FILE *fcgroup, size_t *buf_sz, char **buf)
+{
+ ssize_t line_sz;
+
+ /* Reading cgroup mount nr */
+ errno = 0;
+ line_sz = getdelim(buf, buf_sz, ':', fcgroup);
+ if (errno) {
+ pr_perror("failed to read from file");
+ return -1;
+ }
+
+ if (line_sz == -1) /* EOF */
+ return 0;
+
+ /* Reading mounted controller name */
+ errno = 0;
+ line_sz = getdelim(buf, buf_sz, ':', fcgroup);
+ if (line_sz == -1) { /* no EOF here */
+ pr_perror("failed to read from file");
+ return -1;
+ }
+
+ /*
+ * Reading the rest of the line.
+ * It's zdtm's test, no need to optimize = use fgetc()
+ */
+ do {
+ int c = fgetc(fcgroup);
+
+ if (c == '\n' || c == EOF)
+ break;
+ } while (true);
+
+ return line_sz;
+}
+
+/*
+ * Controller's name may differ depending on the kernel's config:
+ * `net_prio' if only CONFIG_CGROUP_NET_PRIO is set
+ * `net_cls,net_prio' if also CONFIG_CGROUP_NET_CLASSID is set
+ */
+static int get_controller_name(char **name)
+{
+ FILE *self_cgroup = fopen("/proc/self/cgroup", "r");
+ size_t buf_sz = 0;
+ int ret = -1;
+
+ *name = NULL;
+ if (!self_cgroup) {
+ pr_perror("failed to open self/cgroup");
+ return -1;
+ }
+
+ do {
+ ssize_t len = parse_cgroup_line(self_cgroup, &buf_sz, name);
+
+ if (len < 0) {
+ free(*name);
+ goto out_close;
+ }
+
+ if (len == 0) /* EOF */
+ break;
+
+ if (strstr(*name, "net_prio")) {
+ /* erasing ':' delimiter */
+ (*name)[len-1] = '\0';
+ ret = 0;
+ goto out_close;
+ }
+ } while(1);
+
+ /* self/cgroup has no mount for net_prio - try to map it */
+ *name = "net_prio";
+ ret = 0;
+
+out_close:
+ fclose(self_cgroup);
+ return ret;
+}
+
int main(int argc, char **argv)
{
char subdir[PATH_MAX];
char path[PATH_MAX];
int ret = -1;
+ char *controller_name;
srand(time(NULL));
test_init(argc, argv);
- if (mount_cg("net_prio") < 0)
+ if (get_controller_name(&controller_name))
+ return -1;
+
+ if (mount_cg(controller_name) < 0)
return -1;
- sprintf(path, "%s/net_prio/%s/net_prio.ifpriomap", dirname, cgname);
+ sprintf(path, "%s/%s/%s/net_prio.ifpriomap",
+ dirname, controller_name, cgname);
if (read_map(path, maps, PRIOMAPS_SZ))
goto out_umount;
@@ -266,6 +353,7 @@ out_umount:
sprintf(subdir, "%s/%s/%s", dirname, "net_prio", cgname);
rmdir(subdir);
umount_cg("net_prio");
+ free(controller_name);
return ret;
}
diff --git a/test/zdtm/static/cgroup_ifpriomap.desc b/test/zdtm/static/cgroup_ifpriomap.desc
index 3bb68f00a190..5fa9d5079040 100644
--- a/test/zdtm/static/cgroup_ifpriomap.desc
+++ b/test/zdtm/static/cgroup_ifpriomap.desc
@@ -1 +1 @@
-{'flavor': 'h', 'flags': 'suid excl noauto', 'opts': '--manage-cgroups=full'}
+{'flavor': 'h', 'flags': 'suid excl', 'opts': '--manage-cgroups=full'}
diff --git a/test/zdtm/static/cgroup_ifpriomap.hook b/test/zdtm/static/cgroup_ifpriomap.hook
index 692c5ebe26a6..926ffee0c9fb 100755
--- a/test/zdtm/static/cgroup_ifpriomap.hook
+++ b/test/zdtm/static/cgroup_ifpriomap.hook
@@ -2,8 +2,15 @@
[ "$1" == "--clean" -o "$1" == "--pre-restore" ] || exit 0
+# Controller's name may differ depending on the kernel's config:
+# `net_prio' if only CONFIG_CGROUP_NET_PRIO is set
+# `net_cls,net_prio' if also CONFIG_CGROUP_NET_CLASSID is set
+controller=$(sed -n '/net_prio/s/.*:\([^:]*net_prio[^:]*\):.*/\1/p' /proc/self/cgroup)
+
+echo "Controller's name '$controller'"
+
tname=$(mktemp -d cgclean.XXXXXX)
-mount -t cgroup none $tname -o "net_prio"
+mount -t cgroup foobar $tname -o "$controller"
echo "Cleaning $tname"
--
2.15.1
More information about the CRIU
mailing list