From f5ed2ac596d1513e9c134167bae44ef4c1303277 Mon Sep 17 00:00:00 2001 From: Radostin Stoyanov Date: Mon, 4 Mar 2024 15:10:31 +0000 Subject: [PATCH] Add support for reset-on-fork scheduling flag This patch extends CRIU with support for SCHED_RESET_ON_FORK. If the SCHED_RESET_ON_FORK flag is set, the following rules apply for subsequently created children: - If the calling thread has a scheduling policy of SCHED_FIFO or SCHED_RR, the policy is reset to SCHED_OTHER in child processes. - If the calling process has a negative nice value, the nice value is reset to zero in child processes. (See 'man 7 sched') Fixes: #2359 Signed-off-by: Radostin Stoyanov --- criu/cr-dump.c | 3 ++- criu/cr-restore.c | 2 ++ test/zdtm/static/sched_policy00.c | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/criu/cr-dump.c b/criu/cr-dump.c index ee5974acc9..ea9caaa326 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -157,7 +157,8 @@ static int dump_sched_info(int pid, ThreadCoreEntry *tc) tc->has_sched_policy = true; tc->sched_policy = ret; - if ((ret == SCHED_RR) || (ret == SCHED_FIFO)) { + if ((ret == SCHED_RR) || (ret == SCHED_FIFO) || + (ret == (SCHED_RR | SCHED_RESET_ON_FORK)) || (ret == (SCHED_FIFO | SCHED_RESET_ON_FORK))) { ret = syscall(__NR_sched_getparam, pid, &sp); if (ret < 0) { pr_perror("Can't get sched param for %d", pid); diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 318d34c487..6f8318c58e 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -3060,6 +3060,8 @@ static int validate_sched_parm(struct rst_sched_param *sp) switch (sp->policy) { case SCHED_RR: case SCHED_FIFO: + case (SCHED_RR | SCHED_RESET_ON_FORK): + case (SCHED_FIFO | SCHED_RESET_ON_FORK): return ((sp->prio > 0) && (sp->prio < 100)); case SCHED_IDLE: case SCHED_OTHER: diff --git a/test/zdtm/static/sched_policy00.c b/test/zdtm/static/sched_policy00.c index dc71eed940..a351350503 100644 --- a/test/zdtm/static/sched_policy00.c +++ b/test/zdtm/static/sched_policy00.c @@ -51,7 +51,7 @@ int main(int argc, char **argv) } p.sched_priority = param; - if (sched_setscheduler(pid, SCHED_RR, &p)) { + if (sched_setscheduler(pid, SCHED_RR | SCHED_RESET_ON_FORK, &p)) { pr_perror("Can't set policy"); kill(pid, SIGKILL); return -1; @@ -61,7 +61,7 @@ int main(int argc, char **argv) test_waitsig(); ret = sched_getscheduler(pid); - if (ret != SCHED_RR) { + if (ret != (SCHED_RR | SCHED_RESET_ON_FORK)) { fail("Broken/No policy"); err++; }