system/earlyoom: Added (The Early OOM Daemon)

Signed-off-by: bedlam <dave@slackbuilds.org>
This commit is contained in:
Charadon 2022-09-14 07:21:28 +01:00 committed by bedlam
parent fdeee1781c
commit 7cf1544a43
7 changed files with 529 additions and 0 deletions

24
system/earlyoom/README Normal file
View file

@ -0,0 +1,24 @@
earlyoom checks the amount of available memory and free swap up to 10
times a second (less often if there is a lot of free memory). By
default if both are below 10%, it will kill the largest process
(highest oom_score). The percentage value is configurable via command
line arguments.
To enable it, put this line in your rc.local after running chmod +x on
/etc/rc.d/rc.earlyoom:
if [ -x /etc/rc.d/rc.earlyoom ];
then
/etc/rc.d/rc.earlyoom start
fi
and to have it turnoff at shutdown, simply put this in your
rc.local_shutdown:
if [ -x /etc/rc.d/rc.earlyoom ];
then
/etc/rc.d/rc.earlyoom stop
fi
A log file for it is kept at /var/log/earlyoom.log
And earlyoom can be configured by modifying /etc/default/earlyoom

26
system/earlyoom/doinst.sh Normal file
View file

@ -0,0 +1,26 @@
#!/bin/sh
config() {
NEW="$1"
OLD="$(dirname $NEW)/$(basename $NEW .new)"
# If there's no config file by that name, mv it over:
if [ ! -r $OLD ]; then
mv $NEW $OLD
elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then # toss the redundant copy
rm $NEW
fi
# Otherwise, we leave the .new copy for the admin to consider...
}
preserve_perms() {
NEW="$1"
OLD="$(dirname $NEW)/$(basename $NEW .new)"
if [ -e $OLD ]; then
cp -a $OLD ${NEW}.incoming
cat $NEW > ${NEW}.incoming
mv ${NEW}.incoming $NEW
fi
config $NEW
}
preserve_perms etc/rc.d/rc.earlyoom.new

272
system/earlyoom/earlyoom.1 Normal file
View file

@ -0,0 +1,272 @@
.\" Automatically generated by Pandoc 2.16.2
.\"
.TH "earlyoom" "1" "" "" "General Commands Manual"
.hy
.SH NAME
.PP
earlyoom - Early OOM Daemon
.SH SYNOPSIS
.PP
\f[B]earlyoom\f[R] [\f[B]OPTION\f[R]]\&...
.SH DESCRIPTION
.PP
The oom-killer generally has a bad reputation among Linux users.
One may have to sit in front of an unresponsive system, listening to the
grinding disk for minutes, and press the reset button to quickly get
back to what one was doing after running out of patience.
.PP
\f[B]earlyoom\f[R] checks the amount of available memory and free swap
up to 10 times a second (less often if there is a lot of free memory).
If \f[B]both\f[R] memory \f[B]and\f[R] swap are below 10%, it will kill
the largest process (highest \f[C]oom_score\f[R]).
The percentage value is configurable via command line arguments.
.PP
If there is a failure when trying to kill a process, \f[B]earlyoom\f[R]
sleeps for 1 second to limit log spam due to recurring errors.
.SH OPTIONS
.SS -m PERCENT[,KILL_PERCENT]
.PP
set available memory minimum to PERCENT of total (default 10 %).
.PP
earlyoom starts sending SIGTERM once \f[B]both\f[R] memory \f[B]and\f[R]
swap are below their respective PERCENT setting.
It sends SIGKILL once \f[B]both\f[R] are below their respective
KILL_PERCENT setting (default PERCENT/2).
.PP
Use the same value for PERCENT and KILL_PERCENT if you always want to
use SIGKILL.
.PP
Examples:
.IP
.nf
\f[C]
earlyoom # sets PERCENT=10, KILL_PERCENT=5
earlyoom -m 30 # sets PERCENT=30, KILL_PERCENT=15
earlyoom -m 20,18 # sets PERCENT=20, KILL_PERCENT=18
\f[R]
.fi
.SS -s PERCENT[,KILL_PERCENT]
.PP
set free swap minimum to PERCENT of total (default 10 %).
Send SIGKILL if at or below KILL_PERCENT (default PERCENT/2), otherwise
SIGTERM.
.PP
You can use \f[C]-s 100\f[R] to have earlyoom effectively ignore swap
usage: Processes are killed once available memory drops below the
configured minimum, no matter how much swap is free.
.PP
Use the same value for PERCENT and KILL_PERCENT if you always want to
use SIGKILL.
.SS -M SIZE[,KILL_SIZE]
.PP
As an alternative to specifying a percentage of total memory,
\f[C]-M\f[R] sets the available memory minimum to SIZE KiB.
The value is internally converted to a percentage.
If you pass both \f[C]-M\f[R] and \f[C]-m\f[R], the lower value is used.
Example: Reserve 10% of RAM but at most 1 GiB:
.IP
.nf
\f[C]
earlyoom -m 10 -M 1048576
\f[R]
.fi
.PP
earlyoom sends SIGKILL if at or below KILL_SIZE (default SIZE/2),
otherwise SIGTERM.
.SS -S SIZE[,KILL_SIZE]
.PP
As an alternative to specifying a percentage of total swap, \f[C]-S\f[R]
sets the free swap minimum to SIZE KiB.
The value is internally converted to a percentage.
If you pass both \f[C]-S\f[R] and \f[C]-s\f[R], the lower value is used.
.PP
Send SIGKILL if at or below KILL_SIZE (default SIZE/2), otherwise
SIGTERM.
.SS -k
.PP
removed in earlyoom v1.2, ignored for compatibility
.SS -i
.PP
removed in earlyoom v1.7, ignored for compatibility
.SS -d
.PP
enable debugging messages
.SS -v
.PP
print version information and exit
.SS -r INTERVAL
.PP
Time between printing periodic memory reports, in seconds (default 1.0).
A memory report looks like this:
.IP
.nf
\f[C]
mem avail: 21790 of 23909 MiB (91.14%), swap free: 0 of 0 MiB ( 0.00%)
\f[R]
.fi
.PP
Set to 3600 to print a report every hour, to 86400 to print once a day
etc.
Set to 0 to disable printing periodic memory reports.
Free memory monitoring and low-memory killing runs independently of this
option at an adaptive poll rate that only depends on free memory.
Due to the adaptive poll rate, when there is a lot of free memory, the
actual interval may be up to 1 second longer than the setting.
.SS -p
.PP
Increase earlyoom\[cq]s priority: set niceness of earlyoom to -20 and
oom_score_adj to -100.
.PP
When earlyoom is run through its default systemd service, the
\f[C]-p\f[R] switch doesn\[cq]t work.
To achieve the same effect, enter the following three lines into
\f[C]sudo systemctl edit earlyoom\f[R]:
.IP
.nf
\f[C]
[Service]
OOMScoreAdjust=-100
Nice=-20
\f[R]
.fi
.SS -n
.PP
Enable notifications via d-bus.
.PP
To actually see the notifications in your GUI session, you need to have
systembus-notify (https://github.com/rfjakob/systembus-notify) running
as your user.
.SS -N /PATH/TO/SCRIPT
.PP
Run the given script for each process killed.
Must be an absolute path.
.PP
Within the script, information about the killed process can be obtained
via the following environment variables:
.IP
.nf
\f[C]
EARLYOOM_PID Process PID
EARLYOOM_NAME Process name truncated to 16 bytes (as reported in /proc/PID/comm)
EARLYOOM_UID UID of the user running the process
\f[R]
.fi
.PP
WARNING: \f[C]EARLYOOM_NAME\f[R] can contain spaces, newlines, special
characters and is controlled by the user, or it can be empty!
Make sure that your notification script can handle that!
.SS -g
.PP
Kill all processes that have same process group id (PGID) as the process
with excessive memory usage.
.PP
For example, with this flag turned on, the whole application will be
killed when one of its subprocess consumes too much memory (as long as
they all have the same PGID, of course).
.PP
Enable this flag when completely cleaning up the \[lq]entire
application\[rq] is more desirable, and you are sure that the
application puts all its processes in the same PGID.
.PP
Note that some desktop environments (GNOME, for example) put all desktop
application in the same process group as \f[C]gnome-shell\f[R].
earlyoom might kill all such processes including \f[C]gnome-shell\f[R]
when this flag is turned on.
.PP
Be sure to check how your environment behaves beforehand.
Use
.IP
.nf
\f[C]
pstree -gT
\f[R]
.fi
.PP
to show all processes with the PGID in brackets.
.SS --prefer REGEX
.PP
prefer killing processes matching REGEX (adds 300 to oom_score)
.SS --avoid REGEX
.PP
avoid killing processes matching REGEX (subtracts 300 from oom_score)
.SS --ignore REGEX
.PP
ignore processes matching REGEX.
.PP
Unlike the --avoid option, this option disables any potential killing of
the matched processes that might have occurred due to the processes
attaining a high oom_score.
.PP
Use this option with caution as other processes might be sacrificed in
place of the ignored processes when earlyoom determines to kill
processes.
.SS --dryrun
.PP
dry run (do not kill any processes)
.SS -h, --help
.PP
this help text
.SH EXIT STATUS
.PP
0: Successful program execution.
.PP
1: Other error - inspect message for details
.PP
2: Switch conflict.
.PP
4: Could not cd to /proc
.PP
5: Could not open proc
.PP
7: Could not open /proc/sysrq-trigger
.PP
13: Unknown options.
.PP
14: Wrong parameters for other options.
.PP
15: Wrong parameters for memory threshold.
.PP
16: Wrong parameters for swap threshold.
.PP
102: Could not open /proc/meminfo
.PP
103: Could not read /proc/meminfo
.PP
104: Could not find a specific entry in /proc/meminfo
.PP
105: Could not convert number when parse the contents of /proc/meminfo
.SH Why not trigger the kernel oom killer?
.PP
Earlyoom does not use \f[C]echo f > /proc/sysrq-trigger\f[R] because the
Chrome people made their browser always be the first (innocent!)
victim by setting \f[C]oom_score_adj\f[R] very high.
Instead, earlyoom finds out itself by reading through
\f[C]/proc/*/status\f[R] (actually \f[C]/proc/*/statm\f[R], which
contains the same information but is easier to parse programmatically).
.PP
Additionally, in recent kernels (tested on 4.0.5), triggering the kernel
oom killer manually may not work at all.
That is, it may only free some graphics memory (that will be allocated
immediately again) and not actually kill any process.
.SH MEMORY USAGE
.PP
About 2 MiB VmRSS.
All memory is locked using mlockall() to make sure earlyoom does not
slow down in low memory situations.
.SH BUGS
.PP
If there is zero total swap on earlyoom startup, any \f[C]-S\f[R]
(uppercase \[lq]S\[rq]) values are ignored, a warning is printed, and
default swap percentages are used.
.PP
For processes matched by \f[C]--prefer\f[R], negative
\f[C]oom_score_adj\f[R] values are not taken into account, and the
process gets an effective \f[C]oom_score\f[R] of at least 300.
See https://github.com/rfjakob/earlyoom/issues/159 for details.
.SH AUTHOR
.PP
The author of earlyoom is Jakob Unterwurzacher
\[la]jakobunt\[at]gmail.com\[ra].
.PP
This manual page was written by Yangfl \[la]mmyangfl\[at]gmail.com\[ra],
for the Debian project (and may be used by others).

View file

@ -0,0 +1,108 @@
#!/bin/bash
# Slackware build script for earlyoom
# Copyright 2022 Charadon US
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=earlyoom
VERSION=${VERSION:-1.7}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
i?86) ARCH=i586 ;;
arm*) ARCH=arm ;;
*) ARCH=$( uname -m ) ;;
esac
fi
# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
# the name of the created package would be, and then exit. This information
# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
fi
TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
if [ "$ARCH" = "i586" ]; then
SLKCFLAGS="-O2 -march=i586 -mtune=i686"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
SLKCFLAGS="-O2 -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
fi
set -e
rm -rf $PKG
mkdir -p $TMP $PKG $OUTPUT
cd $TMP
rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
chown -R root:root .
find -L . \
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
-o -perm 511 \) -exec chmod 755 {} \; -o \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
make PREFIX=/usr
make DESTDIR=$PKG PREFIX=/usr install-bin
install -Dm644 earlyoom.default $PKG/etc/default/earlyoom
install -Dm644 $CWD/earlyoom.1 $PKG/usr/man/man1/earlyoom.1
rm -f $PKG/{,usr/}lib${LIBDIRSUFFIX}/*.la
find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
find $PKG/usr/man -type f -exec gzip -9 {} \;
for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
install -Dm644 $CWD/rc.earlyoom $PKG/etc/rc.d/rc.earlyoom.new
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
#cp -a <documentation> $PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc
cat $CWD/doinst.sh > $PKG/install/doinst.sh
cd $PKG
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE

View file

@ -0,0 +1,10 @@
PRGNAM="earlyoom"
VERSION="1.7"
HOMEPAGE="https://github.com/rfjakob/earlyoom"
DOWNLOAD="https://github.com/rfjakob/earlyoom/archive/v1.7/earlyoom-1.7.tar.gz"
MD5SUM="9c567930c60b2ccdc536951b005d413d"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
MAINTAINER="Charadon"
EMAIL="dev@iotib.net"

View file

@ -0,0 +1,70 @@
#!/bin/sh
set -eu
. /etc/default/earlyoom
do_start() {
if ps -p "$(cat /var/run/earlyoom.pid)" > /dev/null
then
echo "earlyoom is already running."
else
echo "Starting earlyoom..."
nohup /usr/bin/earlyoom $EARLYOOM_ARGS > /var/log/earlyoom.log 2>&1 &
echo "$!" > /var/run/earlyoom.pid
fi
}
do_stop() {
if ps -p "$(cat /var/run/earlyoom.pid)" > /dev/null
then
echo "Stopping earlyoom..."
kill -15 "$(cat /var/run/earlyoom.pid)"
else
echo "earlyoom is not running."
fi
}
do_force_stop() {
if ps -p "$(cat /var/run/earlyoom.pid)" > /dev/null
then
echo "Killing earlyoom..."
kill -9 "$(cat /var/run/earlyoom.pid)"
else
echo "earlyoom appears to not be running."
fi
}
do_restart() {
do_stop
do_start
}
do_status() {
if ps -p "$(cat /var/run/earlyoom.pid)" > /dev/null
then
echo "earlyoom is running with pid $(cat /var/run/earlyoom.pid)."
else
echo "earlyoom is not running."
fi
}
case $1 in
start)
do_start
;;
stop)
do_stop
;;
restart)
do_restart
;;
force-stop)
do_force_stop
;;
status)
do_status
;;
*)
echo "USAGE: rc.earlyoom (start|stop|force-stop|restart|status)"
;;
esac

View file

@ -0,0 +1,19 @@
# HOW TO EDIT THIS FILE:
# The "handy ruler" below makes it easier to edit a package description.
# Line up the first '|' above the ':' following the base package name, and
# the '|' on the right side marks the last column you can put a character in.
# You must make exactly 11 lines for the formatting to be correct. It's also
# customary to leave one space after the ':' except on otherwise blank lines.
|-----handy-ruler------------------------------------------------------|
earlyoom: earlyoom (The Early OOM Daemon)
earlyoom:
earlyoom: earlyoom checks the amount of available memory and free swap up to
earlyoom: 10 times a second (less often if there is a lot of free memory). By
earlyoom: default if both are below 10%, it will kill the largest process
earlyoom: (highest oom_score). The percentage value is configurable via
earlyoom: command line arguments.
earlyoom:
earlyoom:
earlyoom:
earlyoom: