фикс алгоритма, улучшение вывода результатов проверки памяти

This commit is contained in:
Alexey Avramov 2018-06-12 19:47:30 +09:00
parent a9ef9579fb
commit 139b4e0172
2 changed files with 35 additions and 23 deletions

View File

@ -34,8 +34,8 @@ https://2ch.hk/s/res/2310304.html#2311483, https://archive.li/idixk
### Особенности
- задача - препятствовать зависанию системы при нехватке доступной памяти, а также корректное завершение процессов с целью увеличения объема доступной памяти
- демон на Python 3, VmRSS около 12.8 MiB
- требуется `Linux 3.14+` и `Python 3.4+`
- демон на Python 3, VmRSS не более 13 MiB
- требуется ядро `Linux 3.14` или новее
- периодически проверяет объем доступной памяти, при дефиците памяти отправляет `SIGKILL` или `SIGTERM` процессу с наибольшим `oom_score`
- поддержка работы со `zram`, возможность реакции на `mem_used_total`
- удобный конфиг с возможностью тонкой настройки
@ -101,4 +101,3 @@ sudo ./uninstall.sh
### Известные баги
В рабочем алгоритме известных нет, если найдете - пишите в [Issues](https://github.com/hakavlad/nohang/issues).
Алгоритм снова сломался, ждите релиза v0.1.

53
nohang
View File

@ -17,21 +17,29 @@ from argparse import ArgumentParser
# - задание констант
# найден экспериментально, требует уточнения с разными ядрами и архитектурами
zram_disksize_factor = 0.0042
# где искать конфиг, если не указан через --config
default_configs = ('./nohang.conf', '/etc/nohang/nohang.conf')
# где искать конфиг, если не указан через опцию -c/--config CONFIG
default_configs = (
'./nohang.conf',
'/etc/nohang/nohang.conf'
)
err_mess = '\nSet up path to the valid config file with -c/--config CONFIG option!\nexit'
# означает, что при задани zram disksize = 10000M доступная память уменьшится на 42M
# найден экспериментально, требует уточнения с разными ядрами и архитектурами
# на небольших дисксайзах (до гигабайта) может быть больше, до 0.0045
# создатель модуля zram утверждает, что zram_disksize_factor доожен быть 0.001
# ("zram uses about 0.1% of the size of the disk"
# - https://www.kernel.org/doc/Documentation/blockdev/zram.txt),
# но это утверждение противоречит опытным данным
zram_disksize_factor = 0.0042
###########################################################################################
# - задание функций
def decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after):
def func_decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after):
# цикл для наполнения oom_list
for i in os.listdir('/proc'):
@ -66,8 +74,8 @@ def kib_to_mib(num):
return round(num / 1024.0)
def percent(n):
return round(n * 100, 1)
def percent(num):
return round(num * 100, 1)
def just_percent(num):
@ -75,8 +83,8 @@ def just_percent(num):
# K -> M, выравнивание по правому краю
def human(num):
return str(round(num / 1024)).rjust(5, ' ')
def human(num, lenth):
return str(round(num / 1024)).rjust(lenth, ' ')
# возвращает disksize и mem_used_total по zram id
@ -114,9 +122,8 @@ def pid_to_name(pid):
def find_victim_and_send_signal(signal):
if decrease_oom_score_adj and root:
decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after)
func_decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after)
#print('Find victim...')
oom_list = []
for i in os.listdir('/proc'):
@ -126,6 +133,8 @@ def find_victim_and_send_signal(signal):
oom_score = int(rline1('/proc/' + i + '/oom_score'))
except FileNotFoundError:
oom_score = 0
except ProcessLookupError:
oom_score = 0
oom_list.append((i, oom_score))
# получаем список пар (pid, oom_score)
@ -571,9 +580,8 @@ if print_config:
# для рассчета ширины столбцов mem и zram
mem_len = len(str(round(mem_total / 1024.0)))
###########################################################################################
@ -600,6 +608,7 @@ while True:
break
# если swap_min_sigkill задан в процентах
if swap_kill_is_percent:
swap_min_sigkill_kb = swap_total * swap_min_sigkill_percent / 100.0
@ -621,15 +630,19 @@ while True:
) / 1024.0
# для рассчета ширины столбца свопа
swap_len = len(str(round(swap_total / 1024.0)))
# печать результатов проверк доступной памяти
if print_mem_check_results:
print(
'MemAvail: {}M {}%, SwapFree: {}M {}%, MemUsedZram: {}M {}%'.format(
human(mem_available),
'MemAvail: {}M {}% | SwapFree: {}M {}% | MemUsedZram: {}M {}%'.format(
human(mem_available, mem_len),
just_percent(mem_available / mem_total),
human(swap_free),
human(swap_free, swap_len),
just_percent(swap_free / (swap_total + 0.0001)),
human(mem_used_zram),
human(mem_used_zram, mem_len),
just_percent(mem_used_zram / mem_total)
)
)