update readme, man, conf

This commit is contained in:
Alexey Avramov 2018-07-10 05:16:56 +09:00
parent c135b644e3
commit e24587f1d3
4 changed files with 87 additions and 98 deletions

View File

@ -10,9 +10,8 @@ OOM killer doesn't prevent OOM conditions.
### Solutions ### Solutions
- Use of [earlyoom](https://github.com/rfjakob/earlyoom). This is the simple OOM preventer written in C. - Use of [earlyoom](https://github.com/rfjakob/earlyoom). This is the simple OOM preventer written in C
- Use of nohang. This is advanced OOM preventer written in Python.
- Use of nohang.
### Some features ### Some features
@ -75,9 +74,10 @@ MemAvail: 4610 M, 78.5 % | SwapFree: 9024 M, 83.9 %
### Status ### Status
The program is unstable and some fixes are requird before the first stable version will be released. The program is unstable and some fixes are requird before the first stable version will be released. (Need documentation, translation, review.)
### Download ### Download
```bash ```bash
git clone https://github.com/hakavlad/nohang.git git clone https://github.com/hakavlad/nohang.git
cd nohang cd nohang
@ -88,6 +88,7 @@ cd nohang
```bash ```bash
sudo ./install.sh sudo ./install.sh
``` ```
### Purge ### Purge
```bash ```bash
@ -97,7 +98,7 @@ sudo ./purge.sh
### Command line options ### Command line options
``` ```
./nohang --help ./nohang -h
usage: nohang [-h] [-c CONFIG] usage: nohang [-h] [-c CONFIG]
optional arguments: optional arguments:
@ -113,5 +114,5 @@ Just read the config and edit the values. Run the command `sudo systemctl restar
### Feedback ### Feedback
Please, create [issues](https://github.com/hakavlad/nohang/issues). Please create [issues](https://github.com/hakavlad/nohang/issues).

58
nohang
View File

@ -2,21 +2,11 @@
# Nohang - The No Hang Daemon for Linux # Nohang - The No Hang Daemon for Linux
##########################################################################
# импорты
import os import os
from operator import itemgetter from operator import itemgetter
from time import sleep from time import sleep, time
import datetime import datetime
from argparse import ArgumentParser from argparse import ArgumentParser
import time
##########################################################################
# задание констант
version = 'upstream'
sig_dict = {9: 'SIGKILL', 15: 'SIGTERM'} sig_dict = {9: 'SIGKILL', 15: 'SIGTERM'}
@ -29,7 +19,7 @@ default_configs = (
'/etc/nohang/nohang.conf' '/etc/nohang/nohang.conf'
) )
# универсальное сообщение при инвалидном конфиге # universal message if config is invalid
conf_err_mess = '\nSet up the path to the valid config file with -c/--confi' \ conf_err_mess = '\nSet up the path to the valid config file with -c/--confi' \
'g option!\nExit' 'g option!\nExit'
@ -45,7 +35,7 @@ zram_disksize_factor = 0.0042
########################################################################## ##########################################################################
# задание функций # function definition section
def string_to_float_convert_test(string): def string_to_float_convert_test(string):
@ -270,14 +260,6 @@ def sleep_after_send_signal(signal):
def find_victim_and_send_signal(signal): def find_victim_and_send_signal(signal):
time_now_and_mem_info = datetime.datetime.today().strftime(
'\n%Y-%m-%d %a %H:%M:%S\n{}'.format(mem_info))
print(time_now_and_mem_info)
if logging:
append_log(time_now_and_mem_info)
# выставляем потолок для oom_score_adj всех процессов # выставляем потолок для oom_score_adj всех процессов
if decrease_oom_score_adj and root: if decrease_oom_score_adj and root:
func_decrease_oom_score_adj(oom_score_adj_max) func_decrease_oom_score_adj(oom_score_adj_max)
@ -330,7 +312,6 @@ def find_victim_and_send_signal(signal):
oom_list.append((pid, oom_score)) oom_list.append((pid, oom_score))
# если найден хоть один в черном списке - нет смысла сравнивать с остальными # если найден хоть один в черном списке - нет смысла сравнивать с остальными
if oom_blacklist_regex != []: if oom_blacklist_regex != []:
@ -420,9 +401,6 @@ def find_victim_and_send_signal(signal):
append_log(etc_info) append_log(etc_info)
else: else:
try_to_send = ' Preventing OOM: trying to send the {} signal to {},\n Pid: {}, Badness: {}, VmRSS: {} MiB, VmSwap: {} MiB'.format(sig_dict[signal], name, pid, oom_score, vm_rss, vm_swap)
print(try_to_send)
try: try:
os.kill(int(pid), signal) os.kill(int(pid), signal)
@ -436,6 +414,20 @@ def find_victim_and_send_signal(signal):
except ProcessLookupError: except ProcessLookupError:
send_result = ' No such process' send_result = ' No such process'
time_now_and_mem_info = datetime.datetime.today().strftime(
'\n%Y-%m-%d %a %H:%M:%S\n{}'.format(mem_info))
print(time_now_and_mem_info)
if logging:
append_log(time_now_and_mem_info)
try_to_send = ' Preventing OOM: trying to send the {} signal to {},\n Pid: {}, Badness: {}, VmRSS: {} MiB, VmSwap: {} MiB'.format(sig_dict[signal], name, pid, oom_score, vm_rss, vm_swap)
print(try_to_send)
print(send_result) print(send_result)
if logging: if logging:
@ -787,12 +779,6 @@ else:
exit() exit()
if 'zram_max_sigterm' in config_dict: if 'zram_max_sigterm' in config_dict:
zram_max_sigterm = config_dict['zram_max_sigterm'] zram_max_sigterm = config_dict['zram_max_sigterm']
@ -1077,8 +1063,6 @@ else:
if 'zram_max_warnings' in config_dict: if 'zram_max_warnings' in config_dict:
zram_max_warnings = config_dict['zram_max_warnings'] zram_max_warnings = config_dict['zram_max_warnings']
@ -1172,7 +1156,7 @@ else:
########################################################################## ##########################################################################
# самозащита # self-defense
# повышаем приоритет # повышаем приоритет
try: try:
@ -1216,7 +1200,6 @@ else:
########################################################################## ##########################################################################
# печать конфига
if print_config: if print_config:
@ -1486,8 +1469,8 @@ while True:
elif low_memory_warnings and desktop_notifications: elif low_memory_warnings and desktop_notifications:
if mem_available < mem_min_warnings_kb and swap_free < swap_min_warnings_kb + 0.1 or mem_used_zram > zram_max_warnings_kb: if mem_available < mem_min_warnings_kb and swap_free < swap_min_warnings_kb + 0.1 or mem_used_zram > zram_max_warnings_kb:
warn_time_delta = time.time() - warn_time_now warn_time_delta = time() - warn_time_now
warn_time_now = time.time() warn_time_now = time()
warn_timer += warn_time_delta warn_timer += warn_time_delta
if warn_timer > min_time_between_warnings: if warn_timer > min_time_between_warnings:
send_notify_warn() send_notify_warn()
@ -1498,3 +1481,4 @@ while True:
else: else:
sleep_after_check_mem() sleep_after_check_mem()

View File

@ -7,7 +7,7 @@ nohang \- no hang daemon
.RB [ OPTION ]... .RB [ OPTION ]...
.SH DESCRIPTION .SH DESCRIPTION
Nohang - аналог earlyoom с поддержкой zram и SIGTERM. При дефиците доступной памяти nohang корректно завершает наиболее прожорливые процессы сигналом SIGTERM, тем самым препятствуя зависанию, а также избыточному убийству процессов ядерным OOM killer'ом. See https://github.com/hakavlad/nohang Nohang is a highly configurable daemon for Linux which is able to correctly prevent out of memory conditions. See https://github.com/hakavlad/nohang
.SH OPTIONS .SH OPTIONS
.TP .TP

View File

@ -1,30 +1,25 @@
Nohang config file This is nohang config file.
Комментариями являются строки, начинающиеся с решёток, пробелов Lines beginning with #, tabs and spaces are comments.
и табуляций. Инлайновые комментарии запрещены.
Пробелы допустимы внутри строк в любом количестве.
Все параметры, кроме строковых (display, notify_options,
*list_regex), проходят проверку на допустимые значения.
##################################################################### #####################################################################
I. STANDARD OUTPUT VERBOSITY I. STANDARD OUTPUT VERBOSITY
Печатать параметров конфига при запуске программы. Display the configuration when the program starts.
Допустимые значения: True и False Valid values are True and False.
Values are case sensitive!
print_config = True print_config = True
Печатать ли результаты измерения доступной памяти. Print memory check results or not print.
Допустимые значения: True и False Valid values are True and False.
print_mem_check_results = True print_mem_check_results = True
Печатать ли время сна между проверками памяти и после отправки Print sleep periods between memory checks or not print.
сигналов. Можно установить в значение True для дебага. Valid values are True and False.
Допустимые значения: True и False
print_sleep_periods = False print_sleep_periods = False
@ -44,13 +39,14 @@ mlockall = False
требует наличия root прав. требует наличия root прав.
Установка отрицательного self_nice повышает приоритет процесса. Установка отрицательного self_nice повышает приоритет процесса.
Допустимые значения - целые числа из диапазона [-20; 19]
self_nice = -15 Valid values are integers from the range [-20; 19].
Задать oom_score_adj для процесса. self_nice = -10
Установка значения -1000 запретит самоубийство.
Допустимые значения - целые числа из диапазона [-1000; 1000] Set oom_score_adj for the process.
Valid values are integers from the range [-1000; 1000].
Setting the values to -1000 will prohibit suicide.
self_oom_score_adj = -100 self_oom_score_adj = -100
@ -71,7 +67,9 @@ self_oom_score_adj = -100
В дефолтных настройках на данной интенсивности демон работает В дефолтных настройках на данной интенсивности демон работает
достаточно хорошо, успешно справляясь с резкими скачками потребления достаточно хорошо, успешно справляясь с резкими скачками потребления
памяти. памяти.
Valid values are positive floating-point numbers.
rate_mem = 6 rate_mem = 6
rate_swap = 3 rate_swap = 3
@ -87,25 +85,24 @@ rate_zram = 1
Сигнал отправляется если MemAvailable и SwapFree одновременно Сигнал отправляется если MemAvailable и SwapFree одновременно
опустятся ниже соответствующих значений. опустятся ниже соответствующих значений.
Значения могут быть выражены в процентах (%) и мебибайтах (M) Can be specified in % (percent) and M (MiB).
Valid values are floating-point numbers from the range [0; 100] %.
Диапазон допустимых значений - от 0 до 100 %. mem_min_sigterm = 9 %
mem_min_sigterm = 10 %
mem_min_sigkill = 6 % mem_min_sigkill = 6 %
swap_min_sigterm = 10 % swap_min_sigterm = 9 %
swap_min_sigkill = 6 % swap_min_sigkill = 6 %
Задание общей доли zram в памяти, при превышении которой Задание общей доли zram в памяти, при превышении которой
происходит отправка соответствующих сигналов. происходит отправка соответствующих сигналов.
Экспериментально удалось добиться доли зрам в 95%, при которой
система виснет или запускается OOM killer.
По мере увеличения доли zram в памяти может падать По мере увеличения доли zram в памяти может падать
отзывчивость системы. отзывчивость системы.
Может также задаваться в % и M.
Диапазон допустимых значений - от 0 до 100% (90% - это обычно Can also be specified in % and M.
уровень зависания или срабатывания OOM killer'a) Valid values are floating-point numbers from the range [0; 100] %.
90 % is a usual hang level, not recommended to set very high
level.
zram_max_sigterm = 55 % zram_max_sigterm = 55 %
zram_max_sigkill = 60 % zram_max_sigkill = 60 %
@ -117,11 +114,9 @@ zram_max_sigkill = 60 %
Минимальное значение oom_score, которым должен обладать Минимальное значение oom_score, которым должен обладать
процесс для того, чтобы ему был отправлен сигнал. процесс для того, чтобы ему был отправлен сигнал.
Позволяет предотвратить убийство невиновных если что-то Позволяет предотвратить убийство невиновных если что-то
пойдет не так. пойдет не так. Может min_badness с учетом списков?
Значение должно быть целым числом из диапазона [0; 1000] Valid values are integers from the range [-1000; 1000].
Может min_badness с учетом списков?
oom_score_min = 20 oom_score_min = 20
@ -129,6 +124,8 @@ oom_score_min = 20
для предотвращения риска убийства сразу множества процессов. для предотвращения риска убийства сразу множества процессов.
Должно быть неотрицательным числом. Должно быть неотрицательным числом.
Valid values are non-negative floating-point numbers.
min_delay_after_sigterm = 0.5 min_delay_after_sigterm = 0.5
min_delay_after_sigkill = 3 min_delay_after_sigkill = 3
@ -142,11 +139,12 @@ min_delay_after_sigkill = 3
False - не изменять oom_score_adj процессов перед поиском False - не изменять oom_score_adj процессов перед поиском
жертвы. Значения чувствительны к регистру! жертвы. Значения чувствительны к регистру!
Требует root прав. Enabling the option requires root privileges.
Valid values are True and False.
decrease_oom_score_adj = True decrease_oom_score_adj = False
Допустимые значения - целые числа из диапазона [0; 1000] Valid values are integers from the range [0; 1000].
oom_score_adj_max = 20 oom_score_adj_max = 20
@ -161,9 +159,9 @@ oom_score_adj_max = 20
При запуске nohang от рута уведомления рассылаются всем При запуске nohang от рута уведомления рассылаются всем
залогиненным пользователям. залогиненным пользователям.
See also wiki.archlinux.org/index.php/Desktop_notifications See also wiki.archlinux.org/index.php/Desktop_notifications
Допустимые значения: True и False Valid values are True and False.
desktop_notifications = True desktop_notifications = False
Дополнительные опции для notify-send. Дополнительные опции для notify-send.
См. notify-send --help и man notify-send См. notify-send --help и man notify-send
@ -191,6 +189,8 @@ root_display = :0
Включение этой опции замедляет поиск жертвы, так как Включение этой опции замедляет поиск жертвы, так как
имена всех процессов сравниваются с заданными regex-паттернами. имена всех процессов сравниваются с заданными regex-паттернами.
Valid values are True and False.
use_regex_lists = False use_regex_lists = False
Приоритет списков (если один процесс находится одновременно в Приоритет списков (если один процесс находится одновременно в
@ -205,7 +205,7 @@ use_regex_lists = False
Регулярное выражение для формирования белого списка. Регулярное выражение для формирования белого списка.
whitelist_regex = Xorg|sshd whitelist_regex = sshd
При нехватке памяти все процессы, имена которых соответствуют При нехватке памяти все процессы, имена которых соответствуют
blacklist_regex, получат сигнал. blacklist_regex, получат сигнал.
@ -216,9 +216,9 @@ blacklist_regex =
будут рассчитываться по формуле будут рассчитываться по формуле
badness = (oom_score + 1) * preferlist_factor badness = (oom_score + 1) * preferlist_factor
preferlist_regex = tail|python3 preferlist_regex = tail|python3|someprocessname
Диапазон допустимых значений: [1; 1000] Valid values are floating-point numbers from the range [1; 1000].
preferlist_factor = 3 preferlist_factor = 3
@ -228,9 +228,9 @@ preferlist_factor = 3
будут рассчитываться по формуле будут рассчитываться по формуле
badness = oom_score / avoidlist_factor badness = oom_score / avoidlist_factor
avoidlist_regex = avoidlist_regex = Xorg
Диапазон допустимых значений: [1; 1000] Valid values are floating-point numbers from the range [1; 1000].
avoidlist_factor = 3 avoidlist_factor = 3
@ -238,9 +238,8 @@ avoidlist_factor = 3
VIII. LOGGING VIII. LOGGING
В лог записывается дата, объемы доступной памяти и ход Date, the amount of available memory and OOM prevention progress
предотвращения OOM. can be logged.
Valid values are True and False. Valid values are True and False.
logging = True logging = True
@ -257,20 +256,22 @@ logfile = /var/log/nohang/nohang.log
Valid values are True and False. Valid values are True and False.
low_memory_warnings = True low_memory_warnings = False
Минимальное время между отправками уведомлений в секундах. Минимальное время между отправками уведомлений в секундах.
Должно быть в диапазоне [1; 300]. Valid values are floating-point numbers from the range [1; 300].
min_time_between_warnings = 20 min_time_between_warnings = 20
Уровни MemAvailable и SwapFree одновременно будут ниже Уровни MemAvailable и SwapFree одновременно будут ниже
соотвестствующих значений, то будут отправлены уведомления. соотвестствующих значений, то будут отправлены уведомления.
Могут быть выражены в процентах (%) и мебибайтах (M).
Can be specified in % (percent) and M (MiB).
Valid values are floating-point numbers from the range [0; 100] %.
mem_min_warnings = 20 % mem_min_warnings = 20 %
swap_min_warnings = 20% swap_min_warnings = 20 %
Если доля zram в памяти превысит значение zram_max_warnings, Если доля zram в памяти превысит значение zram_max_warnings,
то будут отправляться уведомления с минимальным периодом то будут отправляться уведомления с минимальным периодом
@ -289,7 +290,7 @@ zram_max_warnings = 40 %
Например, если процесс запущен как демон, то вместо Например, если процесс запущен как демон, то вместо
отправки SIGTERM можно выполнить команду перезапуска. отправки SIGTERM можно выполнить команду перезапуска.
Допустимые значения: True и False. Valid values are True and False.
execute_the_command = False execute_the_command = False
@ -298,10 +299,13 @@ execute_the_command = False
содержащими имена процессов и соотвестствующие команды для содержащими имена процессов и соотвестствующие команды для
перезапуска этих процессов. После имени процесса через двойное перезапуска этих процессов. После имени процесса через двойное
двоеточие (::) следует команда. двоеточие (::) следует команда.
Например:
For example:
** mysqld :: systemctl restart mariadb.service & ** mysqld :: systemctl restart mariadb.service &
** php-fpm7.0 :: systemctl restart php7.0-fpm.service & ** php-fpm7.0 :: systemctl restart php7.0-fpm.service &
Амперсанд (&) в конце команды позволит nohang продолжить работу Амперсанд (&) в конце команды позволит nohang продолжить работу
не дожидаясь окончания выполнения команды. не дожидаясь окончания выполнения команды.
** processname :: some command & ** processname :: some command &