Message ID | 20241108053710.8639-1-wegao@suse.com |
---|---|
State | New |
Headers | show |
Series | [v1] tst_cgroup.c: Force tst_cg_scan only scan specific cgroup version if needs_ver exist | expand |
Hi! > tst_cgroup.c will scan cgroup mount point and check system's cgroup support status, both > cgroupv1 and cgroupv2, if your case only need check cgroupv1(such as needs_cgroup_ver = TST_CG_V1) > but your system contain cgroupv2 mount point, then TCONF will happen tell you your system already > mount cgroupv2, so test case will be skipped. I do not get what happens here. What is the exact test output that does not work for you? We have tst_cg_require() which attempts to mount either v1 or v2 as described in options. However a controller can be mouted either in v1 or v2 but not in both, so skipping the scan will not solve anything.
On Fri, Nov 08, 2024 at 10:53:11AM +0100, Cyril Hrubis wrote: > Hi! > > tst_cgroup.c will scan cgroup mount point and check system's cgroup support status, both > > cgroupv1 and cgroupv2, if your case only need check cgroupv1(such as needs_cgroup_ver = TST_CG_V1) > > but your system contain cgroupv2 mount point, then TCONF will happen tell you your system already > > mount cgroupv2, so test case will be skipped. > > I do not get what happens here. What is the exact test output that does > not work for you? If you add .needs_cgroup_ver = TST_CG_V1 in cpuset02.c and running on sle-micro you will hit https://github.com/linux-test-project/ltp/blob/6408294d83682635393e36c14bbd6ebd94fead94/lib/tst_cgroup.c#L892 Since sle-micro platform already create cgroupv2 mount point, the tst_cg_scan will get cgroupv2 info and will not call cgroup_mount_v1. > > We have tst_cg_require() which attempts to mount either v1 or v2 as > described in options. However a controller can be mouted either in v1 or > v2 but not in both, so skipping the scan will not solve anything. > > -- > Cyril Hrubis > chrubis@suse.cz
Hi! > If you add .needs_cgroup_ver = TST_CG_V1 in cpuset02.c and running on sle-micro you will hit > https://github.com/linux-test-project/ltp/blob/6408294d83682635393e36c14bbd6ebd94fead94/lib/tst_cgroup.c#L892 > > Since sle-micro platform already create cgroupv2 mount point, the tst_cg_scan will get cgroupv2 info and > will not call cgroup_mount_v1. And that is, as far as I can tell, correct. You cannot mount a controller under v1 when it was already mounted under v2.
On Fri, Nov 08, 2024 at 12:23:48PM +0100, Cyril Hrubis wrote: > Hi! > > If you add .needs_cgroup_ver = TST_CG_V1 in cpuset02.c and running on sle-micro you will hit > > https://github.com/linux-test-project/ltp/blob/6408294d83682635393e36c14bbd6ebd94fead94/lib/tst_cgroup.c#L892 > > > > Since sle-micro platform already create cgroupv2 mount point, the tst_cg_scan will get cgroupv2 info and > > will not call cgroup_mount_v1. > > And that is, as far as I can tell, correct. You cannot mount a > controller under v1 when it was already mounted under v2. On sle-micro 6.1, you can mount v1 controller when it was already mounted under v2 And after you force mount v1 cpuset controller, the v2 cpuset controller will be removed localhost:~ # mount | grep cgroup cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot) localhost:~ # ll /sys/fs/cgroup/ total 0 -r--r--r-- 1 root root 0 Nov 11 01:39 cgroup.controllers -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.depth -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.descendants -rw-r--r-- 1 root root 0 Nov 11 01:39 cgroup.procs -r--r--r-- 1 root root 0 Nov 11 01:44 cgroup.stat -rw-r--r-- 1 root root 0 Nov 11 01:39 cgroup.subtree_control -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.threads -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat.local -r--r--r-- 1 root root 0 Nov 11 01:44 cpuset.cpus.effective <<<< -r--r--r-- 1 root root 0 Nov 11 01:44 cpuset.mems.effective <<<< drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-hugepages.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-mqueue.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 init.scope -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.model -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.qos -r--r--r-- 1 root root 0 Nov 11 01:44 io.stat drwxr-xr-x 2 root root 0 Nov 11 01:39 machine.slice -r--r--r-- 1 root root 0 Nov 11 01:44 memory.numa_stat --w------- 1 root root 0 Nov 11 01:44 memory.reclaim -r--r--r-- 1 root root 0 Nov 11 01:44 memory.stat -r--r--r-- 1 root root 0 Nov 11 01:44 misc.capacity drwxr-xr-x 2 root root 0 Nov 11 01:39 proc-fs-nfsd.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-fs-fuse-connections.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-config.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-debug.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-tracing.mount drwxr-xr-x 40 root root 0 Nov 11 01:42 system.slice drwxr-xr-x 2 root root 0 Nov 11 01:39 user.slice localhost:/tmp # mkdir /var/tmp/cpuset localhost:/tmp # mount -t cgroup -o cpuset cpuset /var/tmp/cpuset <<<<<< localhost:/tmp # ll /var/tmp/cpuset/ total 0 -rw-r--r-- 1 root root 0 Nov 11 01:53 cgroup.clone_children -rw-r--r-- 1 root root 0 Nov 11 01:53 cgroup.procs -r--r--r-- 1 root root 0 Nov 11 01:53 cgroup.sane_behavior -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.cpu_exclusive -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.cpus -r--r--r-- 1 root root 0 Nov 11 01:53 cpuset.effective_cpus -r--r--r-- 1 root root 0 Nov 11 01:53 cpuset.effective_mems -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.mem_exclusive -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.mem_hardwall -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_migrate -r--r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_pressure -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_pressure_enabled -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_spread_page -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_spread_slab -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.mems -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.sched_load_balance <<<<<< -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.sched_relax_domain_level -rw-r--r-- 1 root root 0 Nov 11 01:53 notify_on_release -rw-r--r-- 1 root root 0 Nov 11 01:53 release_agent -rw-r--r-- 1 root root 0 Nov 11 01:53 tasks localhost:/tmp # ll /sys/fs/cgroup/ total 0 -r--r--r-- 1 root root 0 Nov 11 01:44 cgroup.controllers -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.depth -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.descendants -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.procs -r--r--r-- 1 root root 0 Nov 11 01:44 cgroup.stat -rw-r--r-- 1 root root 0 Nov 11 01:39 cgroup.subtree_control -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.threads -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat.local drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-hugepages.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-mqueue.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 init.scope -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.model -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.qos -r--r--r-- 1 root root 0 Nov 11 01:44 io.stat drwxr-xr-x 2 root root 0 Nov 11 01:39 machine.slice -r--r--r-- 1 root root 0 Nov 11 01:44 memory.numa_stat --w------- 1 root root 0 Nov 11 01:44 memory.reclaim -r--r--r-- 1 root root 0 Nov 11 01:44 memory.stat -r--r--r-- 1 root root 0 Nov 11 01:44 misc.capacity drwxr-xr-x 2 root root 0 Nov 11 01:39 proc-fs-nfsd.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-fs-fuse-connections.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-config.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-debug.mount drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-tracing.mount drwxr-xr-x 40 root root 0 Nov 11 02:01 system.slice drwxr-xr-x 2 root root 0 Nov 11 01:39 user.slice localhost:/tmp # mount | grep cgroup cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot) cpuset on /var/tmp/cpuset type cgroup (rw,relatime,cpuset) > > -- > Cyril Hrubis > chrubis@suse.cz
Hi! > On sle-micro 6.1, you can mount v1 controller when it was already mounted under v2 > And after you force mount v1 cpuset controller, the v2 cpuset controller will be removed > > localhost:~ # mount | grep cgroup > cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot) > > localhost:~ # ll /sys/fs/cgroup/ > total 0 > -r--r--r-- 1 root root 0 Nov 11 01:39 cgroup.controllers > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.depth > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.descendants > -rw-r--r-- 1 root root 0 Nov 11 01:39 cgroup.procs > -r--r--r-- 1 root root 0 Nov 11 01:44 cgroup.stat > -rw-r--r-- 1 root root 0 Nov 11 01:39 cgroup.subtree_control > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.threads > -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat > -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat.local > -r--r--r-- 1 root root 0 Nov 11 01:44 cpuset.cpus.effective <<<< > -r--r--r-- 1 root root 0 Nov 11 01:44 cpuset.mems.effective <<<< > drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-hugepages.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-mqueue.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 init.scope > -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.model > -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.qos > -r--r--r-- 1 root root 0 Nov 11 01:44 io.stat > drwxr-xr-x 2 root root 0 Nov 11 01:39 machine.slice > -r--r--r-- 1 root root 0 Nov 11 01:44 memory.numa_stat > --w------- 1 root root 0 Nov 11 01:44 memory.reclaim > -r--r--r-- 1 root root 0 Nov 11 01:44 memory.stat > -r--r--r-- 1 root root 0 Nov 11 01:44 misc.capacity > drwxr-xr-x 2 root root 0 Nov 11 01:39 proc-fs-nfsd.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-fs-fuse-connections.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-config.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-debug.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-tracing.mount > drwxr-xr-x 40 root root 0 Nov 11 01:42 system.slice > drwxr-xr-x 2 root root 0 Nov 11 01:39 user.slice > > localhost:/tmp # mkdir /var/tmp/cpuset > localhost:/tmp # mount -t cgroup -o cpuset cpuset /var/tmp/cpuset <<<<<< You are supposed to get an error here, at least that is what I thought. I do get error here on vanilla 6.10 but on debian 6.1 the mount succeeds as well. CCing Michal. Michal I was under an impression that a controller that has been bound to v2 cannot be removed from there and bound to v1 anymore, but it seems that it may happen in some cases. > localhost:/tmp # ll /var/tmp/cpuset/ > total 0 > -rw-r--r-- 1 root root 0 Nov 11 01:53 cgroup.clone_children > -rw-r--r-- 1 root root 0 Nov 11 01:53 cgroup.procs > -r--r--r-- 1 root root 0 Nov 11 01:53 cgroup.sane_behavior > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.cpu_exclusive > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.cpus > -r--r--r-- 1 root root 0 Nov 11 01:53 cpuset.effective_cpus > -r--r--r-- 1 root root 0 Nov 11 01:53 cpuset.effective_mems > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.mem_exclusive > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.mem_hardwall > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_migrate > -r--r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_pressure > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_pressure_enabled > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_spread_page > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.memory_spread_slab > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.mems > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.sched_load_balance <<<<<< > -rw-r--r-- 1 root root 0 Nov 11 01:53 cpuset.sched_relax_domain_level > -rw-r--r-- 1 root root 0 Nov 11 01:53 notify_on_release > -rw-r--r-- 1 root root 0 Nov 11 01:53 release_agent > -rw-r--r-- 1 root root 0 Nov 11 01:53 tasks > > localhost:/tmp # ll /sys/fs/cgroup/ > total 0 > -r--r--r-- 1 root root 0 Nov 11 01:44 cgroup.controllers > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.depth > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.max.descendants > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.procs > -r--r--r-- 1 root root 0 Nov 11 01:44 cgroup.stat > -rw-r--r-- 1 root root 0 Nov 11 01:39 cgroup.subtree_control > -rw-r--r-- 1 root root 0 Nov 11 01:44 cgroup.threads > -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat > -r--r--r-- 1 root root 0 Nov 11 01:44 cpu.stat.local > drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-hugepages.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 dev-mqueue.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 init.scope > -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.model > -rw-r--r-- 1 root root 0 Nov 11 01:44 io.cost.qos > -r--r--r-- 1 root root 0 Nov 11 01:44 io.stat > drwxr-xr-x 2 root root 0 Nov 11 01:39 machine.slice > -r--r--r-- 1 root root 0 Nov 11 01:44 memory.numa_stat > --w------- 1 root root 0 Nov 11 01:44 memory.reclaim > -r--r--r-- 1 root root 0 Nov 11 01:44 memory.stat > -r--r--r-- 1 root root 0 Nov 11 01:44 misc.capacity > drwxr-xr-x 2 root root 0 Nov 11 01:39 proc-fs-nfsd.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-fs-fuse-connections.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-config.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-debug.mount > drwxr-xr-x 2 root root 0 Nov 11 01:39 sys-kernel-tracing.mount > drwxr-xr-x 40 root root 0 Nov 11 02:01 system.slice > drwxr-xr-x 2 root root 0 Nov 11 01:39 user.slice > > localhost:/tmp # mount | grep cgroup > cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot) > cpuset on /var/tmp/cpuset type cgroup (rw,relatime,cpuset)
diff --git a/include/tst_cgroup.h b/include/tst_cgroup.h index d23a8e652..ff1c4ece0 100644 --- a/include/tst_cgroup.h +++ b/include/tst_cgroup.h @@ -117,7 +117,7 @@ extern const struct tst_cg_group *const tst_cg_drain; /* Search the system for mounted cgroups and available * controllers. Called automatically by tst_cg_require. */ -void tst_cg_scan(void); +void tst_cg_scan(enum tst_cg_ver needs_ver); /* Print the config detected by tst_cg_scan and print the internal * state associated with each controller. Output can be passed to * tst_cg_load_config to configure the internal state to that of the diff --git a/lib/newlib_tests/tst_cgroup01.c b/lib/newlib_tests/tst_cgroup01.c index eda0c548d..00bced72b 100644 --- a/lib/newlib_tests/tst_cgroup01.c +++ b/lib/newlib_tests/tst_cgroup01.c @@ -23,7 +23,7 @@ static void setup(void) { cgopts.needs_ver = !!only_mount_v1 ? TST_CG_V1 : 0; - tst_cg_scan(); + tst_cg_scan(0); tst_cg_print_config(); tst_cg_require("memory", &cgopts); diff --git a/lib/newlib_tests/tst_cgroup02.c b/lib/newlib_tests/tst_cgroup02.c index de2ca1812..47d1c6b2a 100644 --- a/lib/newlib_tests/tst_cgroup02.c +++ b/lib/newlib_tests/tst_cgroup02.c @@ -58,7 +58,7 @@ static void setup(void) { cgopts.needs_ver = !!only_mount_v1 ? TST_CG_V1 : 0; - tst_cg_scan(); + tst_cg_scan(0); tst_cg_print_config(); tst_cg_require("memory", &cgopts); diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c index 1404116a5..652bb70b5 100644 --- a/lib/tst_cgroup.c +++ b/lib/tst_cgroup.c @@ -657,7 +657,7 @@ discard: close(mnt_dfd); } -void tst_cg_scan(void) +void tst_cg_scan(enum tst_cg_ver needs_ver) { struct mntent *mnt; FILE *f = setmntent("/proc/self/mounts", "r"); @@ -674,10 +674,9 @@ void tst_cg_scan(void) } do { - if (strncmp(mnt->mnt_type, "cgroup", 6)) - continue; - - cgroup_root_scan(mnt->mnt_type, mnt->mnt_dir, mnt->mnt_opts); + if ((!strcmp(mnt->mnt_type, "cgroup") && (needs_ver != TST_CG_V2)) || + (!strcmp(mnt->mnt_type, "cgroup2") && (needs_ver != TST_CG_V1))) + cgroup_root_scan(mnt->mnt_type, mnt->mnt_dir, mnt->mnt_opts); } while ((mnt = getmntent(f))); } @@ -717,7 +716,7 @@ mount: if (!ret) { tst_res(TINFO, "Mounted V2 CGroups on %s", mnt_path); - tst_cg_scan(); + tst_cg_scan(TST_CG_V2); roots[0].we_mounted_it = 1; return; } @@ -775,7 +774,7 @@ mount: } tst_res(TINFO, "Mounted V1 %s CGroup on %s", ctrl->ctrl_name, mnt_path); - tst_cg_scan(); + tst_cg_scan(TST_CG_V1); if (!ctrl->ctrl_root) return; @@ -856,7 +855,7 @@ void tst_cg_require(const char *const ctrl_name, if (ctrl->ctrl_root) goto mkdirs; - tst_cg_scan(); + tst_cg_scan(options->needs_ver); if (ctrl->ctrl_root) goto mkdirs; diff --git a/testcases/lib/tst_cgctl.c b/testcases/lib/tst_cgctl.c index 2685bef81..6f324f780 100644 --- a/testcases/lib/tst_cgctl.c +++ b/testcases/lib/tst_cgctl.c @@ -30,7 +30,7 @@ static int cgctl_require(const char *ctrl, int test_pid) static int cgctl_cleanup(const char *const config) { - tst_cg_scan(); + tst_cg_scan(0); tst_cg_load_config(config); tst_cg_cleanup(); @@ -39,7 +39,7 @@ static int cgctl_cleanup(const char *const config) static int cgctl_print(void) { - tst_cg_scan(); + tst_cg_scan(0); tst_cg_print_config(); return 0;
tst_cgroup.c will scan cgroup mount point and check system's cgroup support status, both cgroupv1 and cgroupv2, if your case only need check cgroupv1(such as needs_cgroup_ver = TST_CG_V1) but your system contain cgroupv2 mount point, then TCONF will happen tell you your system already mount cgroupv2, so test case will be skipped. This change will fix above scenario, force check specific version of cgroup once you set needs_ver, then test will continue try to create needs_ver of cgroup mount point. This patch can be used by following cpuset02 case: https://patchwork.ozlabs.org/project/ltp/patch/20240930135809.9300-1-wegao@suse.com/ Signed-off-by: Wei Gao <wegao@suse.com> --- include/tst_cgroup.h | 2 +- lib/newlib_tests/tst_cgroup01.c | 2 +- lib/newlib_tests/tst_cgroup02.c | 2 +- lib/tst_cgroup.c | 15 +++++++-------- testcases/lib/tst_cgctl.c | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-)