staticint do_migration_fn(constchar *cgroup, void *arg)
{ int object_pid = (int)(size_t)arg;
if (setuid(TEST_UID)) return EXIT_FAILURE;
// XXX checking /proc/$pid/cgroup would be quicker than wait if (cg_enter(cgroup, object_pid) ||
cg_wait_for_proc_count(cgroup, 1)) return EXIT_FAILURE;
parent = cg_name(root, "cpuset_test_0"); if (!parent) goto cleanup;
parent_procs = cg_name(parent, "cgroup.procs"); if (!parent_procs) goto cleanup; if (cg_create(parent)) goto cleanup;
child_src = cg_name(parent, "cpuset_test_1"); if (!child_src) goto cleanup;
child_src_procs = cg_name(child_src, "cgroup.procs"); if (!child_src_procs) goto cleanup; if (cg_create(child_src)) goto cleanup;
child_dst = cg_name(parent, "cpuset_test_2"); if (!child_dst) goto cleanup;
child_dst_procs = cg_name(child_dst, "cgroup.procs"); if (!child_dst_procs) goto cleanup; if (cg_create(child_dst)) goto cleanup;
if (cg_write(parent, "cgroup.subtree_control", "+cpuset")) goto cleanup;
if (cg_read_strstr(child_src, "cgroup.controllers", "cpuset") ||
cg_read_strstr(child_dst, "cgroup.controllers", "cpuset")) goto cleanup;
/* Enable permissions along src->dst tree path */ if (chown(child_src_procs, test_euid, -1) ||
chown(child_dst_procs, test_euid, -1)) goto cleanup;
if (allow && chown(parent_procs, test_euid, -1)) goto cleanup;
/* Fork a privileged child as a test object */
object_pid = cg_run_nowait(child_src, idle_process_fn, NULL); if (object_pid < 0) goto cleanup;
/* Carry out migration in a child process that can drop all privileges *(includingcapabilities),themainprocessmustremainprivilegedfor *cleanup. *Childprocess'scgroupisirrelevantbutweplaceitintochild_dst *ashackywaytopassinformationaboutmigrationtargettothechild.
*/ if (allow ^ (cg_run(child_dst, do_migration_fn, (void *)(size_t)object_pid) == EXIT_SUCCESS)) goto cleanup;
parent = cg_name(root, "cpuset_test_0"); if (!parent) goto cleanup;
parent_procs = cg_name(parent, "cgroup.procs"); if (!parent_procs) goto cleanup;
parent_subctl = cg_name(parent, "cgroup.subtree_control"); if (!parent_subctl) goto cleanup; if (cg_create(parent)) goto cleanup;
child = cg_name(parent, "cpuset_test_1"); if (!child) goto cleanup;
child_procs = cg_name(child, "cgroup.procs"); if (!child_procs) goto cleanup; if (cg_create(child)) goto cleanup;
/* Enable permissions as in a delegated subtree */ if (chown(parent_procs, test_euid, -1) ||
chown(parent_subctl, test_euid, -1) ||
chown(child_procs, test_euid, -1)) goto cleanup;
/* Put a privileged child in the subtree and modify controller state *fromanunprivilegedprocess,themainprocessremainsprivileged *forcleanup. *Theunprivilegedchildrunsinsubtreetootoavoidparentand *internal-nodeconstraingviolation.
*/
object_pid = cg_run_nowait(child, idle_process_fn, NULL); if (object_pid < 0) goto cleanup;
if (cg_run(child, do_controller_fn, parent) != EXIT_SUCCESS) goto cleanup;
int main(int argc, char *argv[])
{ char root[PATH_MAX]; int i, ret = EXIT_SUCCESS;
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
if (cg_read_strstr(root, "cgroup.subtree_control", "cpuset")) if (cg_write(root, "cgroup.subtree_control", "+cpuset"))
ksft_exit_skip("Failed to set cpuset controller\n");
for (i = 0; i < ARRAY_SIZE(tests); i++) { switch (tests[i].fn(root)) { case KSFT_PASS:
ksft_test_result_pass("%s\n", tests[i].name); break; case KSFT_SKIP:
ksft_test_result_skip("%s\n", tests[i].name); break; default:
ret = EXIT_FAILURE;
ksft_test_result_fail("%s\n", tests[i].name); break;
}
}
return ret;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.