1fb9fb
From 3bf68910c3425dc4563ba74c671a9b0e311873e2 Mon Sep 17 00:00:00 2001
1fb9fb
From: Karel Zak <kzak@redhat.com>
1fb9fb
Date: Mon, 3 Oct 2016 11:02:35 +0200
1fb9fb
Subject: [PATCH 199/201] chrt: follow nice setting, prefer
1fb9fb
 sched_setscheduler()
1fb9fb
1fb9fb
* do not reset 'nice' setting by sched_setattr(), if 'nice' setting
1fb9fb
  is not zero then chrt ends with EPERM for non-root users:
1fb9fb
1fb9fb
  $ renice -n 5 -p $$; chrt -v -b 0 date
1fb9fb
  12475 (process ID) old priority 0, new priority 5
1fb9fb
  chrt: failed to set pid 0's policy: Operation not permitted
1fb9fb
1fb9fb
* it seems more elegant to always use old sched_setscheduler() API for
1fb9fb
  non-deadline policies; in this case we do not need getpriority()
1fb9fb
  to keep 'nice' unchanged.
1fb9fb
1fb9fb
Addresses: https://github.com/karelzak/util-linux/issues/359
1fb9fb
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1905956
1fb9fb
Signed-off-by: Karel Zak <kzak@redhat.com>
1fb9fb
---
1fb9fb
 schedutils/chrt.c | 34 ++++++++++++++++++----------------
1fb9fb
 1 file changed, 18 insertions(+), 16 deletions(-)
1fb9fb
1fb9fb
diff --git a/schedutils/chrt.c b/schedutils/chrt.c
1fb9fb
index edae0d9f4..0a51c1088 100644
1fb9fb
--- a/schedutils/chrt.c
1fb9fb
+++ b/schedutils/chrt.c
1fb9fb
@@ -26,6 +26,8 @@
1fb9fb
 #include <unistd.h>
1fb9fb
 #include <getopt.h>
1fb9fb
 #include <errno.h>
1fb9fb
+#include <sys/time.h>
1fb9fb
+#include <sys/resource.h>
1fb9fb
 
1fb9fb
 #include "c.h"
1fb9fb
 #include "nls.h"
1fb9fb
@@ -340,6 +342,7 @@ static int set_sched_one_by_setscheduler(struct chrt_ctl *ctl, pid_t pid)
1fb9fb
 	struct sched_param sp = { .sched_priority = ctl->priority };
1fb9fb
 	int policy = ctl->policy;
1fb9fb
 
1fb9fb
+	errno = 0;
1fb9fb
 # ifdef SCHED_RESET_ON_FORK
1fb9fb
 	if (ctl->reset_on_fork)
1fb9fb
 		policy |= SCHED_RESET_ON_FORK;
1fb9fb
@@ -357,29 +360,28 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
1fb9fb
 #else /* !HAVE_SCHED_SETATTR */
1fb9fb
 static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
1fb9fb
 {
1fb9fb
+	struct sched_attr sa = { .size = sizeof(struct sched_attr) };
1fb9fb
+
1fb9fb
+	/* old API is good enough for non-deadline */
1fb9fb
+	if (ctl->policy != SCHED_DEADLINE)
1fb9fb
+		return set_sched_one_by_setscheduler(ctl, pid);
1fb9fb
+
1fb9fb
+	/* no changeed by chrt, follow the current setting */
1fb9fb
+	sa.sched_nice = getpriority(PRIO_PROCESS, pid);
1fb9fb
+
1fb9fb
 	/* use main() to check if the setting makes sense */
1fb9fb
-	struct sched_attr sa = {
1fb9fb
-		.size		= sizeof(struct sched_attr),
1fb9fb
-		.sched_policy	= ctl->policy,
1fb9fb
-		.sched_priority	= ctl->priority,
1fb9fb
-		.sched_runtime  = ctl->runtime,
1fb9fb
-		.sched_period   = ctl->period,
1fb9fb
-		.sched_deadline = ctl->deadline
1fb9fb
-	};
1fb9fb
-	int rc;
1fb9fb
+	sa.sched_policy	  = ctl->policy;
1fb9fb
+	sa.sched_priority = ctl->priority;
1fb9fb
+	sa.sched_runtime  = ctl->runtime;
1fb9fb
+	sa.sched_period   = ctl->period;
1fb9fb
+	sa.sched_deadline = ctl->deadline;
1fb9fb
 
1fb9fb
 # ifdef SCHED_RESET_ON_FORK
1fb9fb
 	if (ctl->reset_on_fork)
1fb9fb
 		sa.sched_flags |= SCHED_RESET_ON_FORK;
1fb9fb
 # endif
1fb9fb
 	errno = 0;
1fb9fb
-	rc = sched_setattr(pid, &sa, 0);
1fb9fb
-
1fb9fb
-	if (rc != 0 && errno == ENOSYS && ctl->policy != SCHED_DEADLINE)
1fb9fb
-		/* fallback -- build with new kernel/libc, but executed on old kernels */
1fb9fb
-		rc = set_sched_one_by_setscheduler(ctl, pid);
1fb9fb
-
1fb9fb
-	return rc;
1fb9fb
+	return sched_setattr(pid, &sa, 0);
1fb9fb
 }
1fb9fb
 #endif /* HAVE_SCHED_SETATTR */
1fb9fb
 
1fb9fb
-- 
1fb9fb
2.28.0
1fb9fb