support EXECUTE THE COMMAND INSTEAD OF SENDING THE SIGTERM SIGNAL
This commit is contained in:
parent
9bebbe38f9
commit
c5a9478cd5
@ -74,6 +74,7 @@ https://www.reddit.com/r/linux/comments/5rixe9/this_is_why_i_love_linux_hundreds
|
|||||||
- возможность показа десктопных уведомлений c помощью `notify-send`, с показом сигнала (`SIGTERM` или `SIGKILL`), который отправлен процессу, а также `Pid`, `oom_score`, `VmRSS`, `VmSwap`, которыми обладал процесс перед получением сигнала.
|
- возможность показа десктопных уведомлений c помощью `notify-send`, с показом сигнала (`SIGTERM` или `SIGKILL`), который отправлен процессу, а также `Pid`, `oom_score`, `VmRSS`, `VmSwap`, которыми обладал процесс перед получением сигнала.
|
||||||
- поддержка white, black, prefer и avoid списков с использованием Perl-compatible regular expressions
|
- поддержка white, black, prefer и avoid списков с использованием Perl-compatible regular expressions
|
||||||
- наличие `man` страницы
|
- наличие `man` страницы
|
||||||
|
- возможность выполнения определенных команд как альтернатива отправке SIGTERM для избранных процессов (можно использовать для перезапуска демонов вместо завершения)
|
||||||
- поддержка журналирования в отдельный файл
|
- поддержка журналирования в отдельный файл
|
||||||
- поддержка десктопных уведомлений о низком уровне доступной памяти
|
- поддержка десктопных уведомлений о низком уровне доступной памяти
|
||||||
- наличие установщика для пользователей `systemd`
|
- наличие установщика для пользователей `systemd`
|
||||||
|
73
nohang
73
nohang
@ -411,26 +411,35 @@ def find_victim_and_send_signal(signal):
|
|||||||
vm_rss = 0
|
vm_rss = 0
|
||||||
vm_swap = 0
|
vm_swap = 0
|
||||||
|
|
||||||
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)
|
if name in etc_dict and signal is 15:
|
||||||
|
command = etc_dict[name]
|
||||||
|
etc_info = ' Process {} is a victim,\n Pid: {}, Badness: {}, VmRSS: {} MiB, VmSwap: {} MiB\n Execute command: {}'.format(name, pid, oom_score, vm_rss, vm_swap, command)
|
||||||
|
print(etc_info)
|
||||||
|
os.system(etc_dict[name])
|
||||||
|
append_log(etc_info)
|
||||||
|
|
||||||
try:
|
else:
|
||||||
os.kill(int(pid), signal)
|
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)
|
||||||
send_result = ' Success'
|
|
||||||
|
|
||||||
if desktop_notifications:
|
print(try_to_send)
|
||||||
send_notify(signal, name, pid, oom_score, vm_rss, vm_swap)
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
try:
|
||||||
send_result = ' No such process'
|
os.kill(int(pid), signal)
|
||||||
except ProcessLookupError:
|
send_result = ' Success'
|
||||||
send_result = ' No such process'
|
|
||||||
|
|
||||||
print(send_result)
|
if desktop_notifications:
|
||||||
|
send_notify(signal, name, pid, oom_score, vm_rss, vm_swap)
|
||||||
|
|
||||||
if logging:
|
except FileNotFoundError:
|
||||||
append_log(try_to_send + '\n' + send_result)
|
send_result = ' No such process'
|
||||||
|
except ProcessLookupError:
|
||||||
|
send_result = ' No such process'
|
||||||
|
|
||||||
|
print(send_result)
|
||||||
|
|
||||||
|
if logging:
|
||||||
|
append_log(try_to_send + '\n' + send_result)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@ -547,17 +556,40 @@ print(config)
|
|||||||
|
|
||||||
# парсинг конфига с получением словаря параметров
|
# парсинг конфига с получением словаря параметров
|
||||||
|
|
||||||
|
# conf_parameters_dict
|
||||||
|
# conf_restart_dict
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(config) as f:
|
with open(config) as f:
|
||||||
|
|
||||||
|
# словарь с параметрами конфига
|
||||||
config_dict = dict()
|
config_dict = dict()
|
||||||
|
|
||||||
|
# словарь с именами и командами для параметра execute_the_command
|
||||||
|
etc_dict = dict()
|
||||||
|
|
||||||
for line in f:
|
for line in f:
|
||||||
|
|
||||||
a = line.startswith('#')
|
a = line.startswith('#')
|
||||||
b = line.startswith('\n')
|
b = line.startswith('\n')
|
||||||
c = line.startswith('\t')
|
c = line.startswith('\t')
|
||||||
d = line.startswith(' ')
|
d = line.startswith(' ')
|
||||||
if not a and not b and not c and not d:
|
|
||||||
|
etc = line.startswith('**')
|
||||||
|
|
||||||
|
if not a and not b and not c and not d and not etc:
|
||||||
a = line.split('=')
|
a = line.split('=')
|
||||||
config_dict[a[0].strip()] = a[1].strip()
|
config_dict[a[0].strip()] = a[1].strip()
|
||||||
|
|
||||||
|
if etc:
|
||||||
|
a = line[2:].split('::')
|
||||||
|
etc_name = a[0].strip()
|
||||||
|
etc_command = a[1].strip()
|
||||||
|
if len(etc_name) > 15:
|
||||||
|
print('инвалид конфиг, длина имени процесса не должна превышать 15 символов\nExit')
|
||||||
|
exit()
|
||||||
|
etc_dict[etc_name] = etc_command
|
||||||
|
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
print('PermissionError', conf_err_mess)
|
print('PermissionError', conf_err_mess)
|
||||||
exit()
|
exit()
|
||||||
@ -1087,6 +1119,9 @@ else:
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
execute_the_command = conf_parse_bool('execute_the_command')
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
# получение уровней в кибибайтах
|
# получение уровней в кибибайтах
|
||||||
@ -1266,6 +1301,14 @@ if print_config:
|
|||||||
round(zram_max_warnings_mb), round(zram_max_warnings_percent, 1)))
|
round(zram_max_warnings_mb), round(zram_max_warnings_percent, 1)))
|
||||||
|
|
||||||
|
|
||||||
|
print('\nX. EXECUTE THE COMMAND INSTEAD OF SENDING THE SIGTERM SIGNAL')
|
||||||
|
print('execute_the_command: {}'.format(execute_the_command))
|
||||||
|
if execute_the_command:
|
||||||
|
print('\nPROCESS NAME COMMAND TO EXECUTE')
|
||||||
|
for key in etc_dict:
|
||||||
|
print('{} {}'.format(key.ljust(15), etc_dict[key]))
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
33
nohang.conf
33
nohang.conf
@ -20,7 +20,7 @@ print_config = True
|
|||||||
Печатать ли результаты измерения доступной памяти.
|
Печатать ли результаты измерения доступной памяти.
|
||||||
Допустимые значения: True и False
|
Допустимые значения: True и False
|
||||||
|
|
||||||
print_mem_check_results = False
|
print_mem_check_results = True
|
||||||
|
|
||||||
Печатать ли время сна между проверками памяти и после отправки
|
Печатать ли время сна между проверками памяти и после отправки
|
||||||
сигналов. Можно установить в значение True для дебага.
|
сигналов. Можно установить в значение True для дебага.
|
||||||
@ -94,8 +94,8 @@ rate_zram = 1
|
|||||||
mem_min_sigterm = 8 %
|
mem_min_sigterm = 8 %
|
||||||
mem_min_sigkill = 4 %
|
mem_min_sigkill = 4 %
|
||||||
|
|
||||||
swap_min_sigterm = 8 %
|
swap_min_sigterm = 50 %
|
||||||
swap_min_sigkill = 4 %
|
swap_min_sigkill = 20 %
|
||||||
|
|
||||||
Задание общей доли zram в памяти, при превышении которой
|
Задание общей доли zram в памяти, при превышении которой
|
||||||
происходит отправка соответствующих сигналов.
|
происходит отправка соответствующих сигналов.
|
||||||
@ -278,3 +278,30 @@ swap_min_warnings = 20%
|
|||||||
|
|
||||||
zram_max_warnings = 40 %
|
zram_max_warnings = 40 %
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
X. EXECUTE THE COMMAND INSTEAD OF SENDING THE SIGTERM SIGNAL
|
||||||
|
|
||||||
|
Для процессов с определенным именем можно задать команду,
|
||||||
|
которая будет выполняться вместо отправки сигнала SIGTERM
|
||||||
|
процессу с соответствующим именем.
|
||||||
|
|
||||||
|
Например, если процесс запущен как демон, то вместо
|
||||||
|
отправки SIGTERM можно выполнить команду перезапуска.
|
||||||
|
|
||||||
|
Допустимые значения: True и False.
|
||||||
|
|
||||||
|
execute_the_command = False
|
||||||
|
|
||||||
|
Длина имени процесса не должна превышать 15 символов.
|
||||||
|
Синтаксис таков: строки, начинающиеся с **, считаются строками,
|
||||||
|
содержащими имена процессов и соотвестствующие команды для
|
||||||
|
перезапуска этих процессов. После имени процесса через двойное
|
||||||
|
двоеточие (::) следует команда.
|
||||||
|
Например:
|
||||||
|
** mysqld :: systemctl restart mariadb.service &
|
||||||
|
** php-fpm7.0 :: systemctl restart php7.0-fpm.service &
|
||||||
|
Амперсанд (&) в конце команды позволит nohang продолжить работу
|
||||||
|
не дожидаясь окончания выполнения команды.
|
||||||
|
|
||||||
|
** processname :: some command &
|
||||||
|
Loading…
Reference in New Issue
Block a user