~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/cgroup/test_pids.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #define _GNU_SOURCE
  3 
  4 #include <errno.h>
  5 #include <linux/limits.h>
  6 #include <signal.h>
  7 #include <string.h>
  8 #include <sys/stat.h>
  9 #include <sys/types.h>
 10 #include <unistd.h>
 11 
 12 #include "../kselftest.h"
 13 #include "cgroup_util.h"
 14 
 15 static int run_success(const char *cgroup, void *arg)
 16 {
 17         return 0;
 18 }
 19 
 20 static int run_pause(const char *cgroup, void *arg)
 21 {
 22         return pause();
 23 }
 24 
 25 /*
 26  * This test checks that pids.max prevents forking new children above the
 27  * specified limit in the cgroup.
 28  */
 29 static int test_pids_max(const char *root)
 30 {
 31         int ret = KSFT_FAIL;
 32         char *cg_pids;
 33         int pid;
 34 
 35         cg_pids = cg_name(root, "pids_test");
 36         if (!cg_pids)
 37                 goto cleanup;
 38 
 39         if (cg_create(cg_pids))
 40                 goto cleanup;
 41 
 42         if (cg_read_strcmp(cg_pids, "pids.max", "max\n"))
 43                 goto cleanup;
 44 
 45         if (cg_write(cg_pids, "pids.max", "2"))
 46                 goto cleanup;
 47 
 48         if (cg_enter_current(cg_pids))
 49                 goto cleanup;
 50 
 51         pid = cg_run_nowait(cg_pids, run_pause, NULL);
 52         if (pid < 0)
 53                 goto cleanup;
 54 
 55         if (cg_run_nowait(cg_pids, run_success, NULL) != -1 || errno != EAGAIN)
 56                 goto cleanup;
 57 
 58         if (kill(pid, SIGINT))
 59                 goto cleanup;
 60 
 61         ret = KSFT_PASS;
 62 
 63 cleanup:
 64         cg_enter_current(root);
 65         cg_destroy(cg_pids);
 66         free(cg_pids);
 67 
 68         return ret;
 69 }
 70 
 71 /*
 72  * This test checks that pids.events are counted in cgroup associated with pids.max
 73  */
 74 static int test_pids_events(const char *root)
 75 {
 76         int ret = KSFT_FAIL;
 77         char *cg_parent = NULL, *cg_child = NULL;
 78         int pid;
 79 
 80         cg_parent = cg_name(root, "pids_parent");
 81         cg_child = cg_name(cg_parent, "pids_child");
 82         if (!cg_parent || !cg_child)
 83                 goto cleanup;
 84 
 85         if (cg_create(cg_parent))
 86                 goto cleanup;
 87         if (cg_write(cg_parent, "cgroup.subtree_control", "+pids"))
 88                 goto cleanup;
 89         if (cg_create(cg_child))
 90                 goto cleanup;
 91 
 92         if (cg_write(cg_parent, "pids.max", "2"))
 93                 goto cleanup;
 94 
 95         if (cg_read_strcmp(cg_child, "pids.max", "max\n"))
 96                 goto cleanup;
 97 
 98         if (cg_enter_current(cg_child))
 99                 goto cleanup;
100 
101         pid = cg_run_nowait(cg_child, run_pause, NULL);
102         if (pid < 0)
103                 goto cleanup;
104 
105         if (cg_run_nowait(cg_child, run_success, NULL) != -1 || errno != EAGAIN)
106                 goto cleanup;
107 
108         if (kill(pid, SIGINT))
109                 goto cleanup;
110 
111         if (cg_read_key_long(cg_child, "pids.events", "max ") != 0)
112                 goto cleanup;
113         if (cg_read_key_long(cg_parent, "pids.events", "max ") != 1)
114                 goto cleanup;
115 
116 
117         ret = KSFT_PASS;
118 
119 cleanup:
120         cg_enter_current(root);
121         if (cg_child)
122                 cg_destroy(cg_child);
123         if (cg_parent)
124                 cg_destroy(cg_parent);
125         free(cg_child);
126         free(cg_parent);
127 
128         return ret;
129 }
130 
131 
132 
133 #define T(x) { x, #x }
134 struct pids_test {
135         int (*fn)(const char *root);
136         const char *name;
137 } tests[] = {
138         T(test_pids_max),
139         T(test_pids_events),
140 };
141 #undef T
142 
143 int main(int argc, char **argv)
144 {
145         char root[PATH_MAX];
146 
147         ksft_print_header();
148         ksft_set_plan(ARRAY_SIZE(tests));
149         if (cg_find_unified_root(root, sizeof(root), NULL))
150                 ksft_exit_skip("cgroup v2 isn't mounted\n");
151 
152         /*
153          * Check that pids controller is available:
154          * pids is listed in cgroup.controllers
155          */
156         if (cg_read_strstr(root, "cgroup.controllers", "pids"))
157                 ksft_exit_skip("pids controller isn't available\n");
158 
159         if (cg_read_strstr(root, "cgroup.subtree_control", "pids"))
160                 if (cg_write(root, "cgroup.subtree_control", "+pids"))
161                         ksft_exit_skip("Failed to set pids controller\n");
162 
163         for (int i = 0; i < ARRAY_SIZE(tests); i++) {
164                 switch (tests[i].fn(root)) {
165                 case KSFT_PASS:
166                         ksft_test_result_pass("%s\n", tests[i].name);
167                         break;
168                 case KSFT_SKIP:
169                         ksft_test_result_skip("%s\n", tests[i].name);
170                         break;
171                 default:
172                         ksft_test_result_fail("%s\n", tests[i].name);
173                         break;
174                 }
175         }
176 
177         ksft_finished();
178 }
179 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php