commit:     a4d882964ee1931462f911d0c46a80e27e59fa48
Author:     Florian Schmaus <flo <AT> geekplace <DOT> eu>
AuthorDate: Sun Mar 21 11:07:38 2021 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Jun 13 21:45:32 2021 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=a4d88296

PORTAGE_NICENESS: Consider autogroup scheduling

With Linux's autogroup scheduling feature (CONFIG_SCHED_AUTOGROUP)
setting a nice value on a per-process base has only an effect for
scheduling decisions relative to the other threads in the same
session (typically: the same terminal window). See the section "The
nice value and group scheduling" in the sched(7) man page.

Basically this means that portage "just" setting the nice value, has
no effect in presence of autogroup scheduling being active (which is
probably true for most (desktop) user systems).

This commit changes emerge to set the autogroup's nice value, instead
of the processes' nice value, in case autogroups are present (detected
by the existence of /proc/self/autogroup). The tricky part about
autogroup nice values is that we want restore the orignal nice value
once we are finished. As otherwise, the session, e.g. your terminal,
would continue using this value, and so would subsequently executed
processes. For that we use Python's atexit functinaly, to register a
function that will restore the orignal nice value of the autogroup.

Bug: https://bugs.gentoo.org/777492
Signed-off-by: Florian Schmaus <flo <AT> geekplace.eu>
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/_emerge/actions.py | 36 +++++++++++++++++++++++++++++++++---
 man/make.conf.5        | 10 +++++++++-
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
index 1946f49df..18f8da200 100644
--- a/lib/_emerge/actions.py
+++ b/lib/_emerge/actions.py
@@ -14,6 +14,7 @@ import textwrap
 import time
 import warnings
 from itertools import chain
+from pathlib import Path
 
 import portage
 portage.proxy.lazyimport.lazyimport(globals(),
@@ -2634,14 +2635,43 @@ def apply_priorities(settings):
        nice(settings)
 
 def nice(settings):
+       nice_value: str = settings.get("PORTAGE_NICENESS", "0")
+
        try:
-               os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
+               os.nice(int(nice_value))
        except (OSError, ValueError) as e:
                out = portage.output.EOutput()
-               out.eerror("Failed to change nice value to '%s'" % \
-                       settings.get("PORTAGE_NICENESS", "0"))
+               out.eerror(f"Failed to change nice value to {nice_value}")
                out.eerror("%s\n" % str(e))
 
+       autogroup_file = Path("/proc/self/autogroup")
+       try:
+               f = autogroup_file.open("r+")
+       except EnvironmentError:
+               # Autogroup scheduling is not enabled on this system.
+               return
+
+       with f:
+               line = f.readline()
+               original_autogroup_nice_value = line.split(" ")[2]
+
+               # We need to restore the original nice value of the
+               # autogroup, as otherwise the session, e.g. the
+               # terminal where portage was executed in, would
+               # continue running with that value.
+               portage.atexit_register(
+                       lambda value: autogroup_file.open("w").write(value),
+                       original_autogroup_nice_value,
+               )
+
+               try:
+                       f.write(nice_value)
+               except EnvironmentError as e:
+                       out = portage.output.EOutput()
+                       out.eerror(f"Failed to change autogroup's nice value to 
{nice_value}")
+                       out.eerror("%s\n" % str(e))
+
+
 def ionice(settings):
 
        ionice_cmd = settings.get("PORTAGE_IONICE_COMMAND")

diff --git a/man/make.conf.5 b/man/make.conf.5
index 1c72109ad..18573b5e2 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -1,4 +1,4 @@
-.TH "MAKE.CONF" "5" "May 2021" "Portage VERSION" "Portage"
+.TH "MAKE.CONF" "5" "Jun 2021" "Portage VERSION" "Portage"
 .SH "NAME"
 make.conf \- custom settings for Portage
 .SH "SYNOPSIS"
@@ -1031,6 +1031,14 @@ The value of this variable will be added to the current 
nice level that
 emerge is running at.  In other words, this will not set the nice level,
 it will increment it.  For more information about nice levels and what
 are acceptable ranges, see \fBnice\fR(1).
+.br
+If set and portage is run under Linux with autogroup scheduling (see
+\fBsched\fR(7)) enabled, then portage will set the nice value of its
+autogroup to PORTAGE_NICENESS. Upon exiting, portage will restore the
+original value. Note that if the function responsible for restoring the
+original value is not run, e.g., because portage's process was killed,
+then the autogroup will stay niced. In such a case, the value can be
+reset via corresponding autogroup pseudo\-file in /proc.
 .TP
 \fBPORTAGE_RO_DISTDIRS\fR = \fI[space delimited list of directories]\fR
 When a given file does not exist in \fBDISTDIR\fR, search for the file

Reply via email to