косметические правки
This commit is contained in:
parent
989336f622
commit
40fa3257ea
529
nohang
529
nohang
@ -2,12 +2,21 @@
|
|||||||
|
|
||||||
# Nohang - No Hang Daemon
|
# Nohang - No Hang Daemon
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - импорты
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from ctypes import CDLL
|
from ctypes import CDLL
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - задание констант
|
||||||
|
|
||||||
# найден экспериментально, требует уточнения с разными ядрами и архитектурами
|
# найден экспериментально, требует уточнения с разными ядрами и архитектурами
|
||||||
zram_disksize_factor = 0.0042
|
zram_disksize_factor = 0.0042
|
||||||
|
|
||||||
@ -16,6 +25,167 @@ default_configs = ('./nohang.conf', '/etc/nohang/nohang.conf')
|
|||||||
|
|
||||||
err_mess = '\nSet up path to the valid config file with -c/--config CONFIG option!\nexit'
|
err_mess = '\nSet up path to the valid config file with -c/--config CONFIG option!\nexit'
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - задание функций
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after):
|
||||||
|
# цикл для наполнения oom_list
|
||||||
|
for i in os.listdir('/proc'):
|
||||||
|
|
||||||
|
# пропускаем элементы, не состоящие только из цифр
|
||||||
|
if i.isdigit() is not True:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
oom_score_adj = int(rline1('/proc/' + i + '/oom_score_adj'))
|
||||||
|
if oom_score_adj > oom_score_adj_before:
|
||||||
|
write('/proc/' + i + '/oom_score_adj', oom_score_adj_after + '\n')
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# чтение первой строки файла
|
||||||
|
def rline1(path):
|
||||||
|
with open(path) as f:
|
||||||
|
for line in f:
|
||||||
|
return line[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
# запись в файл
|
||||||
|
def write(path, string):
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(string)
|
||||||
|
|
||||||
|
|
||||||
|
def kib_to_mib(num):
|
||||||
|
return round(num / 1024.0)
|
||||||
|
|
||||||
|
|
||||||
|
def percent(n):
|
||||||
|
return round(n * 100, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def just_percent(num):
|
||||||
|
return str(round(num * 100, 1)).rjust(5, ' ')
|
||||||
|
|
||||||
|
|
||||||
|
# K -> M, выравнивание по правому краю
|
||||||
|
def human(num):
|
||||||
|
return str(round(num / 1024)).rjust(5, ' ')
|
||||||
|
|
||||||
|
|
||||||
|
# возвращает disksize и mem_used_total по zram id
|
||||||
|
def zram_stat(zram_id):
|
||||||
|
try:
|
||||||
|
disksize = rline1('/sys/block/' + zram_id + '/disksize')
|
||||||
|
except FileNotFoundError:
|
||||||
|
return '0', '0'
|
||||||
|
if disksize == ['0\n']:
|
||||||
|
return '0', '0'
|
||||||
|
try:
|
||||||
|
mm_stat = rline1('/sys/block/' + zram_id + '/mm_stat').split(' ')
|
||||||
|
mm_stat_list = []
|
||||||
|
for i in mm_stat:
|
||||||
|
if i != '':
|
||||||
|
mm_stat_list.append(i)
|
||||||
|
mem_used_total = mm_stat_list[2]
|
||||||
|
except FileNotFoundError:
|
||||||
|
mem_used_total = rline1('/sys/block/' + zram_id + '/mem_used_total')
|
||||||
|
return disksize, mem_used_total # BYTES, str
|
||||||
|
|
||||||
|
|
||||||
|
# имя через пид
|
||||||
|
def pid_to_name(pid):
|
||||||
|
try:
|
||||||
|
with open('/proc/' + pid + '/status') as f:
|
||||||
|
for line in f:
|
||||||
|
return line[:-1].split('\t')[1]
|
||||||
|
except FileNotFoundError:
|
||||||
|
return '<unknown>'
|
||||||
|
except ProcessLookupError:
|
||||||
|
return '<unknown>'
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
#print('Find victim...')
|
||||||
|
oom_list = []
|
||||||
|
|
||||||
|
for i in os.listdir('/proc'):
|
||||||
|
if i.isdigit() is not True:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
oom_score = int(rline1('/proc/' + i + '/oom_score'))
|
||||||
|
except FileNotFoundError:
|
||||||
|
oom_score = 0
|
||||||
|
oom_list.append((i, oom_score))
|
||||||
|
|
||||||
|
# получаем список пар (pid, oom_score)
|
||||||
|
pid_tuple_list = sorted(oom_list, key=itemgetter(1), reverse=True)[0]
|
||||||
|
oom_score = pid_tuple_list[1]
|
||||||
|
|
||||||
|
# посылаем сигнал
|
||||||
|
if oom_score >= oom_score_min:
|
||||||
|
pid = pid_tuple_list[0]
|
||||||
|
name = pid_to_name(pid)
|
||||||
|
|
||||||
|
print(
|
||||||
|
' Try to send signal {} to {}, Pid {}, oom_score {}'.format(
|
||||||
|
signal, name, pid, oom_score
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.kill(int(pid), signal)
|
||||||
|
print(' Success')
|
||||||
|
except ProcessLookupError:
|
||||||
|
print(' No such process')
|
||||||
|
except PermissionError:
|
||||||
|
print(' Operation not permitted')
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
print(' oom_score {} < oom_score_min {}'.format(oom_score, oom_score_min))
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - поиск позиций
|
||||||
|
|
||||||
|
|
||||||
|
# ищем позиции
|
||||||
|
with open('/proc/meminfo') as file:
|
||||||
|
mem_list = file.readlines()
|
||||||
|
|
||||||
|
mem_list_names = []
|
||||||
|
for s in mem_list:
|
||||||
|
mem_list_names.append(s.split(':')[0])
|
||||||
|
|
||||||
|
if mem_list_names[2] != 'MemAvailable':
|
||||||
|
print('Your Linux kernel is too old (3.14+ requie), bye!')
|
||||||
|
exit()
|
||||||
|
|
||||||
|
swap_total_index = mem_list_names.index('SwapTotal')
|
||||||
|
swap_free_index = swap_total_index + 1
|
||||||
|
|
||||||
|
mem_total = int(mem_list[0].split(':')[1].split(' ')[-2])
|
||||||
|
|
||||||
|
|
||||||
|
# еще найти позиции VmRSS & VmSwap
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - получение пути к конфигу
|
||||||
|
|
||||||
# парсинг аргументов командной строки
|
# парсинг аргументов командной строки
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
@ -30,7 +200,6 @@ parser.add_argument(
|
|||||||
arg_config = parser.parse_args().config
|
arg_config = parser.parse_args().config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if arg_config is None:
|
if arg_config is None:
|
||||||
|
|
||||||
# print('конфиг не задан через опцию -с/--config, берем его из дефолтных путей')
|
# print('конфиг не задан через опцию -с/--config, берем его из дефолтных путей')
|
||||||
@ -59,6 +228,11 @@ else:
|
|||||||
print('Path to nohang config file:', config)
|
print('Path to nohang config file:', config)
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - парсинг конфига с получением словаря параметров
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(config) as f:
|
with open(config) as f:
|
||||||
config_dict = dict()
|
config_dict = dict()
|
||||||
@ -84,11 +258,10 @@ except IndexError:
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################################################
|
###########################################################################################
|
||||||
|
|
||||||
|
# - извлечение параметров из словаря, проверка наличия всех необходимых параметров
|
||||||
|
|
||||||
# проверка наличия параметров в словаре, их извречение из словаря
|
|
||||||
|
|
||||||
|
|
||||||
if 'print_config' in config_dict:
|
if 'print_config' in config_dict:
|
||||||
@ -236,21 +409,21 @@ else:
|
|||||||
print('oom_score_min not in config, exit!')
|
print('oom_score_min not in config, exit!')
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
if 'decrease_oom_score_adj_enable' in config_dict:
|
if 'decrease_oom_score_adj' in config_dict:
|
||||||
decrease_oom_score_adj_enable = config_dict['decrease_oom_score_adj_enable']
|
decrease_oom_score_adj = config_dict['decrease_oom_score_adj']
|
||||||
if decrease_oom_score_adj_enable == 'True':
|
if decrease_oom_score_adj == 'True':
|
||||||
decrease_oom_score_adj_enable = True
|
decrease_oom_score_adj = True
|
||||||
elif decrease_oom_score_adj_enable == 'False':
|
elif decrease_oom_score_adj == 'False':
|
||||||
decrease_oom_score_adj_enable = False
|
decrease_oom_score_adj = False
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
'invalid decrease_oom_score_adj_enable value {} (should be True or False), exit!'.format(
|
'invalid decrease_oom_score_adj value {} (should be True or False), exit!'.format(
|
||||||
decrease_oom_score_adj_enable
|
decrease_oom_score_adj
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
exit()
|
exit()
|
||||||
else:
|
else:
|
||||||
print('decrease_oom_score_adj_enable not in config, exit!')
|
print('decrease_oom_score_adj not in config, exit!')
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
if 'oom_score_adj_before' in config_dict:
|
if 'oom_score_adj_before' in config_dict:
|
||||||
@ -266,8 +439,74 @@ else:
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################################################
|
###########################################################################################
|
||||||
|
|
||||||
|
# - получение уровней в килобайтах
|
||||||
|
|
||||||
|
|
||||||
|
def sig_level_to_kb(string):
|
||||||
|
if string.endswith('%'):
|
||||||
|
return float(string[:-1].strip()) / 100 * mem_total
|
||||||
|
elif string.endswith('K'):
|
||||||
|
return float(string[:-1].strip())
|
||||||
|
elif string.endswith('M'):
|
||||||
|
return float(string[:-1].strip()) * 1024
|
||||||
|
elif string.endswith('G'):
|
||||||
|
return float(string[:-1].strip()) * 1048576
|
||||||
|
else:
|
||||||
|
print('Конфиг инвалид, где-то неверно указаны единицы измерения')
|
||||||
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
mem_min_sigterm_kb = sig_level_to_kb(mem_min_sigterm)
|
||||||
|
mem_min_sigkill_kb = sig_level_to_kb(mem_min_sigkill)
|
||||||
|
zram_max_sigterm_kb = sig_level_to_kb(zram_max_sigterm)
|
||||||
|
zram_max_sigkill_kb = sig_level_to_kb(zram_max_sigkill)
|
||||||
|
|
||||||
|
|
||||||
|
# возвращает число килобайт при задании в конфиге абсолютного значения,
|
||||||
|
# или кортеж с числом процентов
|
||||||
|
def sig_level_to_kb_swap(string):
|
||||||
|
|
||||||
|
if string.endswith('%'):
|
||||||
|
return float(string[:-1].strip()), True
|
||||||
|
|
||||||
|
elif string.endswith('K'):
|
||||||
|
return float(string[:-1].strip())
|
||||||
|
elif string.endswith('M'):
|
||||||
|
return float(string[:-1].strip()) * 1024
|
||||||
|
elif string.endswith('G'):
|
||||||
|
return float(string[:-1].strip()) * 1048576
|
||||||
|
else:
|
||||||
|
print('Конфиг инвалид, где-то неверно указаны единицы измерения')
|
||||||
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
# получаем число килобайт или кортеж с процентами
|
||||||
|
swap_min_sigterm_swap = sig_level_to_kb_swap(swap_min_sigterm)
|
||||||
|
swap_min_sigkill_swap = sig_level_to_kb_swap(swap_min_sigkill)
|
||||||
|
|
||||||
|
if type(swap_min_sigterm_swap) is tuple:
|
||||||
|
swap_term_is_percent = True
|
||||||
|
swap_min_sigterm_percent = swap_min_sigterm_swap[0]
|
||||||
|
else:
|
||||||
|
swap_term_is_percent = False
|
||||||
|
swap_min_sigterm_kb = swap_min_sigterm_swap
|
||||||
|
|
||||||
|
if type(swap_min_sigkill_swap) is tuple:
|
||||||
|
swap_kill_is_percent = True
|
||||||
|
swap_min_sigkill_percent = swap_min_sigkill_swap[0]
|
||||||
|
else:
|
||||||
|
swap_kill_is_percent = False
|
||||||
|
swap_min_sigkill_kb = swap_min_sigkill_swap
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
# - самозащита и печать конфига
|
||||||
|
|
||||||
|
|
||||||
# повышаем приоритет
|
# повышаем приоритет
|
||||||
try:
|
try:
|
||||||
@ -327,232 +566,17 @@ if print_config:
|
|||||||
print('min_delay_after_sigterm: {}'.format(min_delay_after_sigterm))
|
print('min_delay_after_sigterm: {}'.format(min_delay_after_sigterm))
|
||||||
print('min_delay_after_sigkill: {}'.format(min_delay_after_sigkill))
|
print('min_delay_after_sigkill: {}'.format(min_delay_after_sigkill))
|
||||||
print('oom_score_min: {}'.format(oom_score_min))
|
print('oom_score_min: {}'.format(oom_score_min))
|
||||||
print('decrease_oom_score_adj_enable: {} ({})'.format(decrease_oom_score_adj_enable, decrease_res))
|
|
||||||
|
# False (OK) - OK не нужен когда фолс
|
||||||
|
print('decrease_oom_score_adj: {} ({})'.format(decrease_oom_score_adj, decrease_res))
|
||||||
print('oom_score_adj_before: {}'.format(oom_score_adj_before))
|
print('oom_score_adj_before: {}'.format(oom_score_adj_before))
|
||||||
print('oom_score_adj_after: {}'.format(oom_score_adj_after))
|
print('oom_score_adj_after: {}'.format(oom_score_adj_after))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################################################
|
###########################################################################################
|
||||||
|
|
||||||
|
# - цикл проверки уровней доступной памяти
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after):
|
|
||||||
#print('Decrease oom_score_adj...')
|
|
||||||
# цикл для наполнения oom_list
|
|
||||||
for i in os.listdir('/proc'):
|
|
||||||
|
|
||||||
# пропускаем элементы, не состоящие только из цифр
|
|
||||||
if i.isdigit() is not True:
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
oom_score_adj = int(rline1('/proc/' + i + '/oom_score_adj'))
|
|
||||||
if oom_score_adj > oom_score_adj_before:
|
|
||||||
write('/proc/' + i + '/oom_score_adj', oom_score_adj_after + '\n')
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
except ProcessLookupError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# чтение первой строки файла
|
|
||||||
def rline1(path):
|
|
||||||
with open(path) as f:
|
|
||||||
for line in f:
|
|
||||||
return line[:-1]
|
|
||||||
|
|
||||||
|
|
||||||
# обработать исключения!
|
|
||||||
def write(path, string):
|
|
||||||
with open(path, 'w') as f:
|
|
||||||
f.write(string)
|
|
||||||
# дикриз не от рута
|
|
||||||
|
|
||||||
|
|
||||||
def percent(n):
|
|
||||||
return round(n * 100, 1)
|
|
||||||
|
|
||||||
|
|
||||||
def just_percent(num):
|
|
||||||
return str(round(num * 100, 1)).rjust(5, ' ')
|
|
||||||
|
|
||||||
|
|
||||||
# K -> M, выравнивание по правому краю
|
|
||||||
def human(num):
|
|
||||||
return str(round(num / 1024)).rjust(5, ' ')
|
|
||||||
|
|
||||||
|
|
||||||
# возвращает disksize и mem_used_total по zram id
|
|
||||||
def zram_stat(zram_id):
|
|
||||||
try:
|
|
||||||
disksize = rline1('/sys/block/' + zram_id + '/disksize')
|
|
||||||
except FileNotFoundError:
|
|
||||||
return '0', '0'
|
|
||||||
if disksize == ['0\n']:
|
|
||||||
return '0', '0'
|
|
||||||
try:
|
|
||||||
mm_stat = rline1('/sys/block/' + zram_id + '/mm_stat').split(' ')
|
|
||||||
mm_stat_list = []
|
|
||||||
for i in mm_stat:
|
|
||||||
if i != '':
|
|
||||||
mm_stat_list.append(i)
|
|
||||||
mem_used_total = mm_stat_list[2]
|
|
||||||
except FileNotFoundError:
|
|
||||||
mem_used_total = rline1('/sys/block/' + zram_id + '/mem_used_total')
|
|
||||||
return disksize, mem_used_total # BYTES, str
|
|
||||||
|
|
||||||
|
|
||||||
# имя через пид
|
|
||||||
def pid_to_name(pid):
|
|
||||||
try:
|
|
||||||
with open('/proc/' + pid + '/status') as f:
|
|
||||||
for line in f:
|
|
||||||
return line[:-1].split('\t')[1]
|
|
||||||
except FileNotFoundError:
|
|
||||||
return '<unknown>'
|
|
||||||
except ProcessLookupError:
|
|
||||||
return '<unknown>'
|
|
||||||
|
|
||||||
|
|
||||||
def find_victim_and_send_signal(signal):
|
|
||||||
|
|
||||||
if decrease_oom_score_adj_enable and root:
|
|
||||||
decrease_oom_score_adj(oom_score_adj_before, oom_score_adj_after)
|
|
||||||
|
|
||||||
#print('Find victim...')
|
|
||||||
oom_list = []
|
|
||||||
|
|
||||||
for i in os.listdir('/proc'):
|
|
||||||
if i.isdigit() is not True:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
oom_score = int(rline1('/proc/' + i + '/oom_score'))
|
|
||||||
except FileNotFoundError:
|
|
||||||
oom_score = 0
|
|
||||||
oom_list.append((i, oom_score))
|
|
||||||
|
|
||||||
# получаем список пар (pid, oom_score)
|
|
||||||
pid_tuple_list = sorted(oom_list, key=itemgetter(1), reverse=True)[0]
|
|
||||||
oom_score = pid_tuple_list[1]
|
|
||||||
|
|
||||||
# посылаем сигнал
|
|
||||||
if oom_score >= oom_score_min:
|
|
||||||
pid = pid_tuple_list[0]
|
|
||||||
name = pid_to_name(pid)
|
|
||||||
|
|
||||||
print(
|
|
||||||
' Try to send signal {} to {}, Pid {}, oom_score {}'.format(
|
|
||||||
signal, name, pid, oom_score
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.kill(int(pid), signal)
|
|
||||||
print(' Success')
|
|
||||||
except ProcessLookupError:
|
|
||||||
print(' No such process')
|
|
||||||
except PermissionError:
|
|
||||||
print(' Operation not permitted')
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
print(' oom_score {} < oom_score_min {}'.format(oom_score, oom_score_min))
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
# START
|
|
||||||
|
|
||||||
|
|
||||||
# ищем позиции
|
|
||||||
with open('/proc/meminfo') as file:
|
|
||||||
mem_list = file.readlines()
|
|
||||||
|
|
||||||
mem_list_names = []
|
|
||||||
for s in mem_list:
|
|
||||||
mem_list_names.append(s.split(':')[0])
|
|
||||||
|
|
||||||
if mem_list_names[2] != 'MemAvailable':
|
|
||||||
print('Your Linux kernel is too old (3.14+ requie), bye!')
|
|
||||||
exit()
|
|
||||||
|
|
||||||
swap_total_index = mem_list_names.index('SwapTotal')
|
|
||||||
swap_free_index = swap_total_index + 1
|
|
||||||
|
|
||||||
mem_total = int(mem_list[0].split(':')[1].split(' ')[-2])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sig_level_to_kb(string):
|
|
||||||
if string.endswith('%'):
|
|
||||||
return float(string[:-1].strip()) / 100 * mem_total
|
|
||||||
elif string.endswith('K'):
|
|
||||||
return float(string[:-1].strip())
|
|
||||||
elif string.endswith('M'):
|
|
||||||
return float(string[:-1].strip()) * 1024
|
|
||||||
elif string.endswith('G'):
|
|
||||||
return float(string[:-1].strip()) * 1048576
|
|
||||||
else:
|
|
||||||
print('Конфиг инвалид, где-то неверно указаны единицы измерения')
|
|
||||||
exit()
|
|
||||||
|
|
||||||
|
|
||||||
mem_min_sigterm_kb = sig_level_to_kb(mem_min_sigterm)
|
|
||||||
mem_min_sigkill_kb = sig_level_to_kb(mem_min_sigkill)
|
|
||||||
zram_max_sigterm_kb = sig_level_to_kb(zram_max_sigterm)
|
|
||||||
zram_max_sigkill_kb = sig_level_to_kb(zram_max_sigkill)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# возвращает число килобайт при задании в конфиге абсолютного значения,
|
|
||||||
# или кортеж с числом процентов
|
|
||||||
def sig_level_to_kb_swap(string):
|
|
||||||
|
|
||||||
if string.endswith('%'):
|
|
||||||
return float(string[:-1].strip()), True
|
|
||||||
|
|
||||||
elif string.endswith('K'):
|
|
||||||
return float(string[:-1].strip())
|
|
||||||
elif string.endswith('M'):
|
|
||||||
return float(string[:-1].strip()) * 1024
|
|
||||||
elif string.endswith('G'):
|
|
||||||
return float(string[:-1].strip()) * 1048576
|
|
||||||
else:
|
|
||||||
print('Конфиг инвалид, где-то неверно указаны единицы измерения')
|
|
||||||
exit()
|
|
||||||
|
|
||||||
|
|
||||||
# получаем число килобайт или кортеж с процентами
|
|
||||||
swap_min_sigterm_swap = sig_level_to_kb_swap(swap_min_sigterm)
|
|
||||||
swap_min_sigkill_swap = sig_level_to_kb_swap(swap_min_sigkill)
|
|
||||||
|
|
||||||
if type(swap_min_sigterm_swap) is tuple:
|
|
||||||
swap_term_is_percent = True
|
|
||||||
swap_min_sigterm_percent = swap_min_sigterm_swap[0]
|
|
||||||
else:
|
|
||||||
swap_term_is_percent = False
|
|
||||||
swap_min_sigterm_kb = swap_min_sigterm_swap
|
|
||||||
|
|
||||||
if type(swap_min_sigkill_swap) is tuple:
|
|
||||||
swap_kill_is_percent = True
|
|
||||||
swap_min_sigkill_percent = swap_min_sigkill_swap[0]
|
|
||||||
else:
|
|
||||||
swap_kill_is_percent = False
|
|
||||||
swap_min_sigkill_kb = swap_min_sigkill_swap
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def kib_to_mib(num):
|
|
||||||
return round(num / 1024.0)
|
|
||||||
|
|
||||||
###########################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print('Start monitoring...')
|
print('Start monitoring...')
|
||||||
|
|
||||||
@ -574,7 +598,7 @@ while True:
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
# если swap_min_sigkill задан в процентах
|
||||||
if swap_kill_is_percent:
|
if swap_kill_is_percent:
|
||||||
swap_min_sigkill_kb = swap_total * swap_min_sigkill_percent / 100.0
|
swap_min_sigkill_kb = swap_total * swap_min_sigkill_percent / 100.0
|
||||||
|
|
||||||
@ -582,7 +606,6 @@ while True:
|
|||||||
swap_min_sigterm_kb = swap_total * swap_min_sigterm_percent / 100.0
|
swap_min_sigterm_kb = swap_total * swap_min_sigterm_percent / 100.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# находим MemUsedZram
|
# находим MemUsedZram
|
||||||
disksize_sum = 0
|
disksize_sum = 0
|
||||||
mem_used_total_sum = 0
|
mem_used_total_sum = 0
|
||||||
@ -596,23 +619,7 @@ while True:
|
|||||||
) / 1024.0
|
) / 1024.0
|
||||||
|
|
||||||
|
|
||||||
|
# печать результатов проверк доступной памяти
|
||||||
|
|
||||||
t_mem = mem_available / 1000000.0 / rate_mem
|
|
||||||
t_swap = swap_free / 10000000.0 / rate_swap
|
|
||||||
t_zram = (mem_total * 0.8 - mem_used_zram) / 1000000.0 / rate_zram
|
|
||||||
if t_zram < 0.01:
|
|
||||||
t_zram = 0.01
|
|
||||||
|
|
||||||
t_mem_swap = t_mem + t_swap
|
|
||||||
t_mem_zram = t_mem + t_zram
|
|
||||||
|
|
||||||
if t_mem_swap <= t_mem_zram:
|
|
||||||
t = t_mem_swap
|
|
||||||
else:
|
|
||||||
t = t_mem_zram
|
|
||||||
|
|
||||||
|
|
||||||
if print_mem_check_results:
|
if print_mem_check_results:
|
||||||
print(
|
print(
|
||||||
'MemAvail: {}M {}%, SwapFree: {}M {}%, MemUsedZram: {}M {}%'.format(
|
'MemAvail: {}M {}%, SwapFree: {}M {}%, MemUsedZram: {}M {}%'.format(
|
||||||
@ -626,7 +633,7 @@ while True:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# если swap_min_sigkill задан в абсолютной величине и Swap_total = 0
|
||||||
if swap_total > swap_min_sigkill_kb:
|
if swap_total > swap_min_sigkill_kb:
|
||||||
swap_sigkill_pc = percent(swap_min_sigkill_kb / (swap_total + 1))
|
swap_sigkill_pc = percent(swap_min_sigkill_kb / (swap_total + 1))
|
||||||
else:
|
else:
|
||||||
@ -657,6 +664,7 @@ while True:
|
|||||||
sleep(min_delay_after_sigkill)
|
sleep(min_delay_after_sigkill)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
# MEM ZRAM KILL
|
# MEM ZRAM KILL
|
||||||
if mem_used_zram >= zram_max_sigkill_kb:
|
if mem_used_zram >= zram_max_sigkill_kb:
|
||||||
print(
|
print(
|
||||||
@ -671,6 +679,7 @@ while True:
|
|||||||
sleep(min_delay_after_sigkill)
|
sleep(min_delay_after_sigkill)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
# MEM SWAP TERM
|
# MEM SWAP TERM
|
||||||
if mem_available <= mem_min_sigterm_kb and swap_free <= swap_min_sigterm_kb:
|
if mem_available <= mem_min_sigterm_kb and swap_free <= swap_min_sigterm_kb:
|
||||||
print(
|
print(
|
||||||
@ -689,6 +698,7 @@ while True:
|
|||||||
find_victim_and_send_signal(15)
|
find_victim_and_send_signal(15)
|
||||||
sleep(min_delay_after_sigterm)
|
sleep(min_delay_after_sigterm)
|
||||||
|
|
||||||
|
|
||||||
# MEM ZRAM TERM
|
# MEM ZRAM TERM
|
||||||
if mem_used_zram >= zram_max_sigterm_kb:
|
if mem_used_zram >= zram_max_sigterm_kb:
|
||||||
print(
|
print(
|
||||||
@ -702,6 +712,23 @@ while True:
|
|||||||
find_victim_and_send_signal(15)
|
find_victim_and_send_signal(15)
|
||||||
sleep(min_delay_after_sigterm)
|
sleep(min_delay_after_sigterm)
|
||||||
|
|
||||||
|
|
||||||
|
# задание периода в зависимости от рейтов и уровней доступной памяти
|
||||||
|
t_mem = mem_available / 1000000.0 / rate_mem
|
||||||
|
t_swap = swap_free / 10000000.0 / rate_swap
|
||||||
|
t_zram = (mem_total * 0.8 - mem_used_zram) / 1000000.0 / rate_zram
|
||||||
|
if t_zram < 0.01:
|
||||||
|
t_zram = 0.01
|
||||||
|
|
||||||
|
t_mem_swap = t_mem + t_swap
|
||||||
|
t_mem_zram = t_mem + t_zram
|
||||||
|
|
||||||
|
if t_mem_swap <= t_mem_zram:
|
||||||
|
t = t_mem_swap
|
||||||
|
else:
|
||||||
|
t = t_mem_zram
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sleep(t)
|
sleep(t)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
Loading…
Reference in New Issue
Block a user