Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add emerge --jobs-tmpdir-space-threshold option #1345

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions lib/_emerge/Scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from portage._sets.base import InternalPackageSet
from portage.util import ensure_dirs, writemsg, writemsg_level
from portage.util.futures import asyncio
from portage.util.path import first_existing
from portage.util.SlotObject import SlotObject
from portage.util._async.SchedulerInterface import SchedulerInterface
from portage.package.ebuild.digestcheck import digestcheck
Expand Down Expand Up @@ -64,7 +65,7 @@


class Scheduler(PollScheduler):
# max time between loadavg checks (seconds)
# max time between loadavg and tmpdir space checks (seconds)
_loadavg_latency = 30

# max time between display status updates (seconds)
Expand Down Expand Up @@ -229,6 +230,7 @@ def __init__(
if max_jobs is None:
max_jobs = 1
self._set_max_jobs(max_jobs)
self._jobs_tmpdir_space_threshold = myopts.get("--jobs-tmpdir-space-threshold")
self._running_root = trees[trees._running_eroot]["root_config"]
self.edebug = 0
if settings.get("PORTAGE_DEBUG", "") == "1":
Expand Down Expand Up @@ -1573,7 +1575,10 @@ def _main_loop(self):
self._main_exit = self._event_loop.create_future()

if (
self._max_load is not None
(
self._max_load is not None
or self._jobs_tmpdir_space_threshold is not None
)
and self._loadavg_latency is not None
and (self._max_jobs is True or self._max_jobs > 1)
):
Expand Down Expand Up @@ -1792,6 +1797,30 @@ def _is_work_scheduled(self):
def _running_job_count(self):
return self._jobs

def _can_add_job(self):
if not super()._can_add_job():
return False

if self._jobs_tmpdir_space_threshold is not None and hasattr(os, "statvfs"):
tmpdir = first_existing(
os.path.join(self.settings["PORTAGE_TMPDIR"], "portage")
)
try:
vfs_stat = os.statvfs(tmpdir)
except OSError as e:
writemsg_level(
f"!!! statvfs('{tmpdir}'): {e}\n",
noiselevel=-1,
level=logging.ERROR,
)
else:
if (
(vfs_stat.f_blocks - vfs_stat.f_bavail) / vfs_stat.f_blocks
) > self._jobs_tmpdir_space_threshold:
return False
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though, I personally would probably have implemented absolute threshold parameters for free disk space and inodes first, and not a relative one.

Since ratios have no units, it was simpler to implement this threshold as a ratio. I was thinking we could possibly re-use the same option for absolute thresholds if we add support for parsing units.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make it possible to distinguish between used space or remaining space, using a plus or minus operator for example.


return True

def _schedule_tasks(self):
while True:
state_change = 0
Expand Down
35 changes: 34 additions & 1 deletion lib/_emerge/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 1999-2023 Gentoo Authors
# Copyright 1999-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import argparse
Expand Down Expand Up @@ -165,6 +165,7 @@ def __contains__(self, s):
"--getbinpkgonly": y_or_n,
"--ignore-world": y_or_n,
"--jobs": valid_integers,
"--jobs-tmpdir-space-threshold": valid_floats,
"--keep-going": y_or_n,
"--load-average": valid_floats,
"--onlydeps-with-ideps": y_or_n,
Expand Down Expand Up @@ -523,6 +524,10 @@ def parse_opts(tmpcmdline, silent=False):
"help": "Specifies the number of packages to build " + "simultaneously.",
"action": "store",
},
"--jobs-tmpdir-space-threshold": {
"help": "Specifies maximum used space ratio when starting a new job.",
"action": "store",
},
"--keep-going": {
"help": "continue as much as possible after an error",
"choices": true_y_or_n,
Expand Down Expand Up @@ -1033,6 +1038,24 @@ def parse_opts(tmpcmdline, silent=False):

myoptions.jobs = jobs

if myoptions.jobs_tmpdir_space_threshold == "True":
myoptions.jobs_tmpdir_space_threshold = None

if myoptions.jobs_tmpdir_space_threshold:
try:
jobs_tmpdir_space_threshold = float(myoptions.jobs_tmpdir_space_threshold)
except ValueError:
jobs_tmpdir_space_threshold = 0.0

if jobs_tmpdir_space_threshold <= 0.0 or jobs_tmpdir_space_threshold > 1.0:
jobs_tmpdir_space_threshold = None
if not silent:
parser.error(
f"Invalid --jobs-tmpdir-space-threshold: '{myoptions.jobs_tmpdir_space_threshold}'\n"
)

myoptions.jobs_tmpdir_space_threshold = jobs_tmpdir_space_threshold

if myoptions.load_average == "True":
myoptions.load_average = None

Expand Down Expand Up @@ -1304,6 +1327,16 @@ def emerge_main(args: Optional[list[str]] = None):
emerge_config.action, emerge_config.opts, emerge_config.args = parse_opts(
tmpcmdline
)
if (
"--jobs-tmpdir-space-threshold" in emerge_config.opts
and "keep-work" in emerge_config.running_config.settings.features
):
writemsg_level(
"--jobs-tmpdir-space-threshold conflicts with FEATURES=keep-work\n",
level=logging.ERROR,
noiselevel=-1,
)
return 1

try:
return run_action(emerge_config)
Expand Down
10 changes: 9 additions & 1 deletion man/emerge.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH "EMERGE" "1" "May 2024" "Portage @VERSION@" "Portage"
.TH "EMERGE" "1" "Jun 2024" "Portage @VERSION@" "Portage"
.SH "NAME"
emerge \- Command\-line interface to the Portage system
.SH "SYNOPSIS"
Expand Down Expand Up @@ -693,6 +693,14 @@ Note that interactive packages currently force a setting
of \fI\-\-jobs=1\fR. This issue can be temporarily avoided
by specifying \fI\-\-accept\-properties=\-interactive\fR.
.TP
.BR \-\-jobs\-tmpdir\-space\-threshold[=RATIO]
Specifies the maximum ratio of used space allowed (a floating\-point
number) in \fBPORTAGE_TMPDIR\fR when starting a new job. With no
argument, removes a previous space ratio threshold. For example,
use a ratio of \fI0.85\fR to stop starting new jobs when the space
usage in \fBPORTAGE_TMPDIR\fR exceeds \fI85%\fR. This option conflicts
with \fBFEATURES="keep\-work"\fR.
.TP
.BR "\-\-keep\-going [ y | n ]"
Continue as much as possible after an error. When an error occurs,
dependencies are recalculated for remaining packages and any with
Expand Down