From 1727af3436beef2a429a61dfe5d9fd55b5d7ee0b Mon Sep 17 00:00:00 2001 From: "Alice H." Date: Fri, 19 Sep 2025 10:35:14 +0100 Subject: [PATCH] earlyoom: add new package earlyoom checks the amount of available memory and swap at an adaptive rate for up to 10 times per second. When both available memory and swap are below threshold, it'll send SIGTERM or SIGKILL to the process with the highest oom_score. Details about oom_score can be obtained at https://man7.org/linux/man-pages/man5/proc_pid_oom_score.5.html Signed-off-by: Alice H. --- admin/earlyoom/Makefile | 44 +++++++++++++++++++ admin/earlyoom/files/earlyoom.config | 26 ++++++++++++ admin/earlyoom/files/earlyoom.init | 63 ++++++++++++++++++++++++++++ admin/earlyoom/test.sh | 3 ++ 4 files changed, 136 insertions(+) create mode 100644 admin/earlyoom/Makefile create mode 100644 admin/earlyoom/files/earlyoom.config create mode 100644 admin/earlyoom/files/earlyoom.init create mode 100644 admin/earlyoom/test.sh diff --git a/admin/earlyoom/Makefile b/admin/earlyoom/Makefile new file mode 100644 index 0000000000..cfa69ac153 --- /dev/null +++ b/admin/earlyoom/Makefile @@ -0,0 +1,44 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=earlyoom +PKG_VERSION:=1.9.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/rfjakob/earlyoom/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=b2fe5e1e071a5a000b22fb9602c068fd69d09c057f0ba972dfc5d85daf464b2a + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Alice H. + +include $(INCLUDE_DIR)/package.mk + +define Package/earlyoom + SECTION:=admin + CATEGORY:=Administration + TITLE:=Early OOM Daemon for Linux + URL:=https://github.com/rfjakob/earlyoom +endef + +define Package/earlyoom/description + earlyoom checks the amount of available memory and swap at an adaptive + rate for up to 10 times per second. When both available memory and swap + are below threshold, it'll send SIGTERM or SIGKILL to the process with + the highest oom_score. Details about oom_score can be obtained at + https://man7.org/linux/man-pages/man5/proc_pid_oom_score.5.html +endef + +MAKE_VARS += \ + VERSION=v$(PKG_VERSION) + +define Package/earlyoom/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/earlyoom $(1)/usr/sbin/earlyoom + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) $(CURDIR)/files/earlyoom.config $(1)/etc/config/earlyoom + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(CURDIR)/files/earlyoom.init $(1)/etc/init.d/earlyoom +endef + +$(eval $(call BuildPackage,earlyoom)) diff --git a/admin/earlyoom/files/earlyoom.config b/admin/earlyoom/files/earlyoom.config new file mode 100644 index 0000000000..b3a50e8e2d --- /dev/null +++ b/admin/earlyoom/files/earlyoom.config @@ -0,0 +1,26 @@ +config earlyoom 'main' + option memory_term_percent '10' + option memory_kill_percent '5' + option swap_term_percent '10' + option swap_kill_percent '5' + + option memory_term_kib '0' + option memory_kill_kib '0' + option swap_term_kib '0' + option swap_kill_kib '0' + + option prefer_regex '' + option avoid_regex '^netifd|dropbear|dnsmasq|odhcpd|odhcp6c|hostapd|wpa_supplicant$' + option ignore_regex '' + + option pre_script_path '' + option post_script_path '' + + option report_interval '3600' + + option debug_log '0' + option high_priority '1' + option kill_process_group '0' + option sort_by_rss '0' + option dry_run '0' + option syslog '1' diff --git a/admin/earlyoom/files/earlyoom.init b/admin/earlyoom/files/earlyoom.init new file mode 100644 index 0000000000..649e200705 --- /dev/null +++ b/admin/earlyoom/files/earlyoom.init @@ -0,0 +1,63 @@ +#!/bin/sh /etc/rc.common +# shellcheck disable=SC3043 + +START=50 +USE_PROCD=1 + +start_service() { + config_load 'earlyoom' + + for opt in memory_term_percent memory_kill_percent \ + swap_term_percent swap_kill_percent memory_term_kib \ + memory_kill_kib swap_term_kib swap_kill_kib prefer_regex \ + avoid_regex ignore_regex report_interval \ + pre_script_path post_script_path + do + local "$opt" + config_get "$opt" 'main' "$opt" + done + + for opt in debug_log high_priority kill_process_group \ + sort_by_rss dry_run syslog + do + local "$opt" + config_get_bool "$opt" 'main' "$opt" 0 + done + + procd_open_instance + procd_set_param command '/usr/sbin/earlyoom' + procd_set_param stderr 1 + procd_set_param respawn + + [ "$memory_term_percent" -gt '0' ] || [ "$memory_kill_percent" -gt '0' ] && + procd_append_param command -m "$memory_term_percent","$memory_kill_percent" + [ "$swap_term_percent" -gt '0' ] || [ "$swap_kill_percent" -gt '0' ] && + procd_append_param command -s "$swap_term_percent","$swap_kill_percent" + + [ "$memory_term_kib" -gt '0' ] || [ "$memory_kill_kib" -gt '0' ] && + procd_append_param command -M "$memory_term_kib","$memory_kill_kib" + [ "$swap_term_kib" -gt '0' ] || [ "$swap_kill_kib" -gt '0' ] && + procd_append_param command -S "$swap_term_kib","$swap_kill_kib" + + [ -n "$prefer_regex" ] && procd_append_param command --prefer "$prefer_regex" + [ -n "$avoid_regex" ] && procd_append_param command --avoid "$avoid_regex" + [ -n "$ignore_regex" ] && procd_append_param command --ignore "$ignore_regex" + + [ -x "$pre_script_path" ] && procd_append_param command -P "$pre_script_path" + [ -x "$post_script_path" ] && procd_append_param command -N "$post_script_path" + + [ -n "$report_interval" ] && procd_append_param command -r "$report_interval" + + [ "$debug_log" -eq '1' ] && procd_append_param command -d + [ "$high_priority" -eq '1' ] && procd_append_param command -p + [ "$kill_process_group" -eq '1' ] && procd_append_param command -g + [ "$sort_by_rss" -eq '1' ] && procd_append_param command --sort-by-rss + [ "$dry_run" -eq '1' ] && procd_append_param command --dryrun + [ "$syslog" -eq '1' ] && procd_append_param command --syslog + + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger 'earlyoom' +} diff --git a/admin/earlyoom/test.sh b/admin/earlyoom/test.sh new file mode 100644 index 0000000000..6b429f2c71 --- /dev/null +++ b/admin/earlyoom/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +"$1" -v 2>&1 | grep "$2" -- 2.30.2