fix comments, fix low mem warns

This commit is contained in:
Alexey Avramov 2018-11-29 03:14:48 +09:00
parent 2096628d21
commit 55f4d1fa18

537
nohang
View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""A daemon that prevents OOM in linux systems."""
"""A daemon that prevents OOM in Linux systems."""
import os
import signal
from operator import itemgetter
@ -22,21 +22,9 @@ conf_err_mess = '\nSet up the path to the valid conf' \
'ig file with -c/--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 = deltaMemAvailavle / disksize
# found experimentally
zram_disksize_factor = 0.0042
##########################################################################
# function definition section
@ -137,7 +125,7 @@ def conf_parse_bool(param):
def func_decrease_oom_score_adj(oom_score_adj_max):
"""
Pls, put description here...
Stupid function, must be removed or remaked
"""
for i in os.listdir('/proc'):
if i.isdigit() is not True:
@ -185,9 +173,8 @@ def just_percent_swap(num):
return str(round(num * 100, 1)).rjust(5, ' ')
# KiB to MiB, right alignment
def human(num, lenth):
"""Convert Kib values to Mib values with right alignment"""
"""Convert KiB values to MiB values with right alignment"""
return str(round(num / 1024)).rjust(lenth, ' ')
@ -238,8 +225,6 @@ def pid_to_name(pid):
def send_notify_warn():
"""
Look for process with maximum 'badness' and warn user with notification.
"""
# find process with max badness
fat_tuple = fattest()
@ -268,8 +253,7 @@ def send_notify_warn():
'--pid', pid, '--name', name])
else: # Or by regular user
# send notification to user that runs this nohang
Popen(['notify-send', '--icon=dialog-warning',
'Low memory: {}'.format(title), '{}'.format(body)])
Popen(['notify-send', '--icon=dialog-warning', '{}'.format(title), '{}'.format(body)])
def send_notify(signal, name, pid):
@ -294,7 +278,8 @@ def send_notify(signal, name, pid):
'{}'.format(title), '{}'.format(body)])
else:
# send notification to user that runs this nohang
Popen(['notify-send', '--icon=dialog-warning', '{}'.format(title), '{}'.format(body)])
Popen(['notify-send', '--icon=dialog-warning',
'{}'.format(title), '{}'.format(body)])
def send_notify_etc(pid, name, command):
@ -341,9 +326,7 @@ def sleep_after_send_signal(signal):
def find_victim_and_send_signal(signal):
"""
Please describe this.
thanks
Find victim with highest badness and send SIGTERM/SIGKILL
"""
if decrease_oom_score_adj and root:
func_decrease_oom_score_adj(oom_score_adj_max)
@ -442,27 +425,34 @@ def find_victim_and_send_signal(signal):
try:
os.kill(int(pid), signal)
response_time = time() - time0
send_result = 'OK; response time: {} ms'.format(round(response_time * 1000))
send_result = 'OK; response time: {} ms'.format(
round(response_time * 1000))
if gui_notifications:
send_notify(signal, name, pid)
except FileNotFoundError:
response_time = time() - time0
send_result = 'no such process; response time: {} ms'.format(round(response_time * 1000))
send_result = 'no such process; response time: {} ms'.format(
round(response_time * 1000))
except ProcessLookupError:
response_time = time() - time0
send_result = 'no such process; response time: {} ms'.format(round(response_time * 1000))
send_result = 'no such process; response time: {} ms'.format(
round(response_time * 1000))
# Pls correct line length =)
preventing_oom_message = ' Finding the process with the highest badness\n Victim is {}, pid: {}, badness: {}, VmRSS: {} MiB, VmSwap: {} MiB\n Sending {} to the victim; {}'.format(name, pid, victim_badness, vm_rss, vm_swap, sig_dict[signal], send_result)
preventing_oom_message = ' Finding the process with the highes' \
't badness\n Victim is {}, pid: {}, badness: {}, VmRS' \
'S: {} MiB, VmSwap: {} MiB\n Sending {} to the victim; {}'.format(
name, pid, victim_badness, vm_rss, vm_swap, sig_dict[signal],
send_result)
print(mem_info)
print(preventing_oom_message)
else:
response_time = time() - time0
victim_badness_is_too_small = ' victim badness {} < min_badness {}; nothing to do; response time: {} ms'.format(victim_badness, min_badness, round(response_time * 1000))
victim_badness_is_too_small = ' victim badness {} < min_badness {}; nothing to do; response time: {} ms'.format(
victim_badness, min_badness, round(response_time * 1000))
print(victim_badness_is_too_small)
@ -487,8 +477,13 @@ def sleep_after_check_mem():
try:
if print_sleep_periods:
print('sleep', round(t, 2), ' (t_mem={}, t_swap={}, t_zram={})'.format(
round(t_mem, 2), round(t_swap, 2), round(t_zram, 2)))
print(
'sleep', round(
t, 2), ' (t_mem={}, t_swap={}, t_zram={})'.format(
round(
t_mem, 2), round(
t_swap, 2), round(
t_zram, 2)))
sleep(t)
except KeyboardInterrupt:
exit()
@ -544,9 +539,68 @@ def fattest():
return (name, pid)
def calculate_percent(arg_key):
"""
parse conf dict
Calculate mem_min_KEY_percent.
Try use this one)
arg_key: str key for config_dict
returns int mem_min_percent or NoneType if got some error
"""
if arg_key in config_dict:
mem_min = config_dict[arg_key]
if mem_min.endswith('%'):
# truncate percents, so we have a number
mem_min_percent = mem_min[:-1].strip()
# then 'float test'
mem_min_percent = string_to_float_convert_test(mem_min_percent)
if mem_min_percent is None:
print('Invalid {} value, not float\nExit'.format(arg_key))
exit()
# Final validations...
if mem_min_percent < 0 or mem_min_percent > 100:
print(
'{}, as percents value, out of range [0; 100]\nExit'.format(arg_key))
exit()
# mem_min_sigterm_percent is clean and valid float percentage. Can
# translate into Kb
mem_min_kb = mem_min_percent / 100 * mem_total
mem_min_mb = round(mem_min_kb / 1024)
elif mem_min.endswith('M'):
mem_min_mb = string_to_float_convert_test(mem_min[:-1].strip())
if mem_min_mb is None:
print('Invalid {} value, not float\nExit'.format(arg_key))
exit()
mem_min_kb = mem_min_mb * 1024
if mem_min_kb > mem_total:
print(
'{} value can not be greater then MemTotal ({} MiB)\nExit'.format(
arg_key, round(
mem_total / 1024)))
exit()
mem_min_percent = mem_min_kb / mem_total * 100
else:
print('Invalid {} units in config.\n Exit'.format(arg_key))
mem_min_percent = None
else:
print('{} not in config\nExit'.format(arg_key))
mem_min_percent = None
return mem_min_kb, mem_min_mb, mem_min_percent
##########################################################################
# поиск позиций и mem_total
# find mem_total
# find positions of SwapFree and SwapTotal in /proc/meminfo
with open('/proc/meminfo') as file:
mem_list = file.readlines()
@ -556,7 +610,7 @@ 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, Linux 3.14+ requie\nExit')
print('Your Linux kernel is too old, Linux 3.14+ requied\nExit')
exit()
swap_total_index = mem_list_names.index('SwapTotal')
@ -564,10 +618,11 @@ swap_free_index = swap_total_index + 1
mem_total = int(mem_list[0].split(':')[1].strip(' kB\n'))
# Get names from /proc/*/status to be able to get VmRSS and VmSwap values
with open('/proc/self/status') as file:
status_list = file.readlines()
# Get names from /proc/*/status to be able to get VmRSS and VmSwap values
status_names = []
for s in status_list:
status_names.append(s.split(':')[0])
@ -575,8 +630,10 @@ for s in status_list:
vm_rss_index = status_names.index('VmRSS')
vm_swap_index = status_names.index('VmSwap')
##########################################################################
# Configurations
# Cmd argparse
@ -617,8 +674,10 @@ else:
print('The path to the config:', config)
##########################################################################
# parsing the config with obtaining the parameters dictionary
# conf_parameters_dict
@ -630,7 +689,8 @@ try:
# dictionary with config options
config_dict = dict()
# dictionary with names and commands for the parameter execute_the_command
# dictionary with names and commands for the parameter
# execute_the_command
etc_dict = dict()
for line in f:
@ -651,7 +711,8 @@ try:
etc_name = a[0].strip()
etc_command = a[1].strip()
if len(etc_name) > 15:
print('Invalid config, the length of the process name must not exceed 15 characters\nExit')
print(
'Invalid config, the length of the process name must not exceed 15 characters\nExit')
exit()
etc_dict[etc_name] = etc_command
@ -668,23 +729,42 @@ except IndexError:
print('IndexError', conf_err_mess)
exit()
##########################################################################
# extracting parameters from the dictionary
# check for all necessary parameters
# validation of all parameters
print_config = conf_parse_bool('print_config')
print_mem_check_results = conf_parse_bool('print_mem_check_results')
print_sleep_periods = conf_parse_bool('print_sleep_periods')
realtime_ionice = conf_parse_bool('realtime_ionice')
mlockall = conf_parse_bool('mlockall')
gui_low_memory_warnings = conf_parse_bool('gui_low_memory_warnings')
gui_notifications = conf_parse_bool('gui_notifications')
decrease_oom_score_adj = conf_parse_bool('decrease_oom_score_adj')
regex_matching = conf_parse_bool('regex_matching')
execute_the_command = conf_parse_bool('execute_the_command')
prefer_regex = conf_parse_string('prefer_regex')
avoid_regex = conf_parse_string('avoid_regex')
mem_min_sigterm_kb, mem_min_sigterm_mb, mem_min_sigterm_percent = calculate_percent(
'mem_min_sigterm')
mem_min_sigkill_kb, mem_min_sigkill_mb, mem_min_sigkill_percent = calculate_percent(
'mem_min_sigkill')
zram_max_sigterm_kb, zram_max_sigterm_mb, zram_max_sigterm_percent = calculate_percent(
'zram_max_sigterm')
zram_max_sigkill_kb, zram_max_sigkill_mb, zram_max_sigkill_percent = calculate_percent(
'zram_max_sigkill')
mem_min_warnings_kb, mem_min_warnings_mb, mem_min_warnings_percent = calculate_percent(
'mem_min_warnings')
zram_max_warnings_kb, zram_max_warnings_mb, zram_max_warnings_percent = calculate_percent(
'zram_max_warnings')
if 'realtime_ionice_classdata' in config_dict:
@ -706,9 +786,6 @@ else:
exit()
mlockall = conf_parse_bool('mlockall')
if 'niceness' in config_dict:
niceness = string_to_int_convert_test(config_dict['niceness'])
if niceness is None:
@ -775,143 +852,6 @@ else:
exit()
def calculate_percent(arg_key):
"""
Calculate mem_min_KEY_percent.
Try use this one)
arg_key: str key for config_dict
returns int mem_min_percent or NoneType if got some error
"""
global mem_total
global string_to_float_convert_test
global config_dict
if arg_key in config_dict:
mem_min = config_dict[arg_key]
if mem_min.endswith('%'):
# truncate percents, so we have a number
mem_min_percent = mem_min[:-1].strip()
# then 'float test'
mem_min_percent = string_to_float_convert_test(mem_min_percent)
if mem_min_percent is None:
print('Invalid {} value, not float\nExit'.format(arg_key))
exit()
# Final validations...
if mem_min_percent < 0 or mem_min_percent > 100:
print('{}, as percents value, out of range [0; 100]\nExit'.format(arg_key))
exit()
# mem_min_sigterm_percent is clean and valid float percentage. Can translate into Kb
mem_min_kb = mem_min_percent / 100 * mem_total
mem_min_mb = round(mem_min_kb / 1024)
elif mem_min.endswith('M'):
mem_min_mb = string_to_float_convert_test(mem_min[:-1].strip())
if mem_min_mb is None:
print('Invalid {} value, not float\nExit'.format(arg_key))
exit()
mem_min_kb = mem_min_mb * 1024
if mem_min_kb > mem_total:
print('{} value can not be greater then MemTotal ({} MiB)\nExit'.format(arg_key, round(mem_total / 1024)))
exit()
mem_min_percent = mem_min_kb / mem_total * 100
else:
print('Invalid {} units in config.\n Exit'.format(arg_key))
mem_min_percent = None
else:
print('{} not in config\nExit'.format(arg_key))
mem_min_percent = None
return mem_min_kb, mem_min_mb, mem_min_percent
# if 'mem_min_sigterm' in config_dict:
# mem_min_sigterm = config_dict['mem_min_sigterm']
# if mem_min_sigterm.endswith('%'):
# # truncate percents, so we have a number
# mem_min_sigterm_percent = mem_min_sigterm[:-1].strip()
# # then 'float test'
# mem_min_sigterm_percent = string_to_float_convert_test(mem_min_sigterm_percent)
# if mem_min_sigterm_percent is None:
# print('Invalid mem_min_sigterm value, not float\nExit')
# exit()
# # Final validations...
# if mem_min_sigterm_percent < 0 or mem_min_sigterm_percent > 100:
# print('mem_min_sigterm, as percents value, out of range [0; 100]\nExit')
# exit()
# # mem_min_sigterm_percent is clean and valid float percentage. Can translate into Kb
# mem_min_sigterm_kb = mem_min_sigterm_percent / 100 * mem_total
# mem_min_sigterm_mb = round(mem_min_sigterm_kb / 1024)
# elif mem_min_sigterm.endswith('M'):
# mem_min_sigterm_mb = string_to_float_convert_test(mem_min_sigterm[:-1].strip())
# if mem_min_sigterm_mb is None:
# print('Invalid mem_min_sigterm value, not float\nExit')
# exit()
# mem_min_sigterm_kb = mem_min_sigterm_mb * 1024
# if mem_min_sigterm_kb > mem_total:
# print('mem_min_sigterm value can not be greater then MemTotal ({} MiB)\nExit'.format(round(mem_total / 1024)))
# exit()
# mem_min_sigterm_percent = mem_min_sigterm_kb / mem_total * 100
# else:
# print('Invalid mem_min_sigterm units in config.\n Exit')
# exit()
# else:
# print('mem_min_sigterm not in config\nExit')
# exit()
# if 'mem_min_sigkill' in config_dict:
# mem_min_sigkill = config_dict['mem_min_sigkill']
# if mem_min_sigkill.endswith('%'):
# # truncate percent, so we have a number
# mem_min_sigkill_percent = mem_min_sigkill[:-1].strip()
# # then 'float test'
# mem_min_sigkill_percent = string_to_float_convert_test(mem_min_sigkill_percent)
# if mem_min_sigkill_percent is None:
# print('Invalid mem_min_sigkill value, not float\nExit')
# exit()
# # Final validation
# if mem_min_sigkill_percent < 0 or mem_min_sigkill_percent > 100:
# print('mem_min_sigkill, as a percentage, out of range [0; 100]\nExit')
# exit()
# # mem_min_sigterm_percent is clean and valid float percentage. Can translate into Kb
# mem_min_sigkill_kb = mem_min_sigkill_percent / 100 * mem_total
# mem_min_sigkill_mb = round(mem_min_sigkill_kb / 1024)
# elif mem_min_sigkill.endswith('M'):
# mem_min_sigkill_mb = string_to_float_convert_test(mem_min_sigkill[:-1].strip())
# if mem_min_sigkill_mb is None:
# print('Invalid mem_min_sigkill value, not float\nExit')
# exit()
# mem_min_sigkill_kb = mem_min_sigkill_mb * 1024
# if mem_min_sigkill_kb > mem_total:
# print('mem_min_sigkill value can not be greater then MemTotal ({} MiB)\nExit'.format(round(mem_total / 1024)))
# exit()
# mem_min_sigkill_percent = mem_min_sigkill_kb / mem_total * 100
# else:
# print('Invalid mem_min_sigkill units in config\nExit')
# exit()
# else:
# print('mem_min_sigkill not in config\nExit')
# exit()
mem_min_sigterm_kb, mem_min_sigterm_mb, mem_min_sigterm_percent = calculate_percent('mem_min_sigterm')
mem_min_sigkill_kb, mem_min_sigkill_mb, mem_min_sigkill_percent = calculate_percent('mem_min_sigkill')
# НУЖНА ВАЛИДАЦИЯ НА МЕСТЕ!
if 'swap_min_sigterm' in config_dict:
swap_min_sigterm = config_dict['swap_min_sigterm']
@ -928,89 +868,6 @@ else:
exit()
zram_max_sigterm_kb, zram_max_sigterm_mb, zram_max_sigterm_percent = calculate_percent('zram_max_sigterm')
zram_max_sigkill_kb, zram_max_sigkill_mb, zram_max_sigkill_percent = calculate_percent('zram_max_sigkill')
# if 'zram_max_sigterm' in config_dict:
# zram_max_sigterm = config_dict['zram_max_sigterm']
# if zram_max_sigterm.endswith('%'):
# # отбрасываем процент, получаем число
# zram_max_sigterm_percent = zram_max_sigterm[:-1].strip()
# # далее флоат тест
# zram_max_sigterm_percent = string_to_float_convert_test(zram_max_sigterm_percent)
# if zram_max_sigterm_percent is None:
# print('Invalid zram_max_sigterm value, not float\nExit')
# exit()
# # окончательная валидация
# if zram_max_sigterm_percent < 0 or zram_max_sigterm_percent > 100:
# print('zram_max_sigterm, выраженный в процентах, должен быть быть в диапазоне [0; 100]\nExit')
# exit()
# # zram_max_sigterm_percent это теперь чистое валидное флоат число процентов, можно переводить в кб
# zram_max_sigterm_kb = zram_max_sigterm_percent / 100 * mem_total
# zram_max_sigterm_mb = round(zram_max_sigterm_kb / 1024)
# elif zram_max_sigterm.endswith('M'):
# zram_max_sigterm_mb = string_to_float_convert_test(zram_max_sigterm[:-1].strip())
# if zram_max_sigterm_mb is None:
# print('Invalid zram_max_sigterm value, not float\nExit')
# exit()
# zram_max_sigterm_kb = zram_max_sigterm_mb * 1024
# if zram_max_sigterm_kb > mem_total:
# print('zram_max_sigterm value не должен быть больше MemTotal ({} MiB)\nExit'.format(round(mem_total / 1024)))
# exit()
# zram_max_sigterm_percent = zram_max_sigterm_kb / mem_total * 100
# else:
# print('Конфиг инвалид, для zram_max_sigterm неверно указаны единицы измерения\nExit')
# exit()
# else:
# print('zram_max_sigterm not in config\nExit')
# exit()
# if 'zram_max_sigkill' in config_dict:
# zram_max_sigkill = config_dict['zram_max_sigkill']
# if zram_max_sigkill.endswith('%'):
# # отбрасываем процент, получаем число
# zram_max_sigkill_percent = zram_max_sigkill[:-1].strip()
# # далее флоат тест
# zram_max_sigkill_percent = string_to_float_convert_test(zram_max_sigkill_percent)
# if zram_max_sigkill_percent is None:
# print('Invalid zram_max_sigkill value, not float\nExit')
# exit()
# # окончательная валидация
# if zram_max_sigkill_percent < 0 or zram_max_sigkill_percent > 100:
# print('zram_max_sigkill, выраженный в процентах, должен быть быть в диапазоне [0; 100]\nExit')
# exit()
# # zram_max_sigkill_percent это теперь чистое валидное флоат число процентов, можно переводить в кб
# zram_max_sigkill_kb = zram_max_sigkill_percent / 100 * mem_total
# zram_max_sigkill_mb = round(zram_max_sigkill_kb / 1024)
# elif zram_max_sigkill.endswith('M'):
# zram_max_sigkill_mb = string_to_float_convert_test(zram_max_sigkill[:-1].strip())
# if zram_max_sigkill_mb is None:
# print('Invalid zram_max_sigkill value, not float\nExit')
# exit()
# zram_max_sigkill_kb = zram_max_sigkill_mb * 1024
# if zram_max_sigkill_kb > mem_total:
# print('zram_max_sigkill value не должен быть больше MemTotal ({} MiB)\nExit'.format(round(mem_total / 1024)))
# exit()
# zram_max_sigkill_percent = zram_max_sigkill_kb / mem_total * 100
# else:
# print('Конфиг инвалид, для zram_max_sigkill неверно указаны единицы измерения\nExit')
# exit()
# else:
# print('zram_max_sigkill not in config\nExit')
# exit()
if 'min_delay_after_sigterm' in config_dict:
min_delay_after_sigterm = string_to_float_convert_test(
config_dict['min_delay_after_sigterm'])
@ -1053,9 +910,6 @@ else:
exit()
decrease_oom_score_adj = conf_parse_bool('decrease_oom_score_adj')
if 'oom_score_adj_max' in config_dict:
oom_score_adj_max = string_to_int_convert_test(
config_dict['oom_score_adj_max'])
@ -1070,12 +924,6 @@ else:
exit()
regex_matching = conf_parse_bool('regex_matching')
prefer_regex = conf_parse_string('prefer_regex')
if 'prefer_factor' in config_dict:
prefer_factor = string_to_float_convert_test(config_dict['prefer_factor'])
if prefer_factor is None:
@ -1089,9 +937,6 @@ else:
exit()
avoid_regex = conf_parse_string('avoid_regex')
if 'avoid_factor' in config_dict:
avoid_factor = string_to_float_convert_test(config_dict['avoid_factor'])
if avoid_factor is None:
@ -1105,11 +950,6 @@ else:
exit()
gui_low_memory_warnings = conf_parse_bool('gui_low_memory_warnings')
gui_notifications = conf_parse_bool('gui_notifications')
if 'min_time_between_warnings' in config_dict:
min_time_between_warnings = string_to_float_convert_test(
config_dict['min_time_between_warnings'])
@ -1124,48 +964,6 @@ else:
exit()
mem_min_warnings_kb, mem_min_warnings_mb, mem_min_warnings_percent = calculate_percent('mem_min_warnings')
# if 'mem_min_warnings' in config_dict:
# mem_min_warnings = config_dict['mem_min_warnings']
# if mem_min_warnings.endswith('%'):
# # отбрасываем процент, получаем число
# mem_min_warnings_percent = mem_min_warnings[:-1].strip()
# # далее флоат тест
# mem_min_warnings_percent = string_to_float_convert_test(mem_min_warnings_percent)
# if mem_min_warnings_percent is None:
# print('Invalid mem_min_warnings value, not float\nExit')
# exit()
# # окончательная валидация
# if mem_min_warnings_percent < 0 or mem_min_warnings_percent > 100:
# print('mem_min_warnings, выраженный в процентах, должен быть быть в диапазоне [0; 100]\nExit')
# exit()
# # mem_min_warnings_percent это теперь чистое валидное флоат число процентов, можно переводить в кб
# mem_min_warnings_kb = mem_min_warnings_percent / 100 * mem_total
# mem_min_warnings_mb = round(mem_min_warnings_kb / 1024)
# elif mem_min_warnings.endswith('M'):
# mem_min_warnings_mb = string_to_float_convert_test(mem_min_warnings[:-1].strip())
# if mem_min_warnings_mb is None:
# print('Invalid mem_min_warnings value, not float\nExit')
# exit()
# mem_min_warnings_kb = mem_min_warnings_mb * 1024
# if mem_min_warnings_kb > mem_total:
# print('mem_min_warnings value не должен быть больше MemTotal ({} MiB)\nExit'.format(round(mem_total / 1024)))
# exit()
# mem_min_warnings_percent = mem_min_warnings_kb / mem_total * 100
# else:
# print('Конфиг инвалид, для mem_min_warnings неверно указаны единицы измерения\nExit')
# exit()
# else:
# print('mem_min_warnings not in config\nExit')
# exit()
# НА МЕСТЕ!!!
if 'swap_min_warnings' in config_dict:
swap_min_warnings = config_dict['swap_min_warnings']
@ -1174,60 +972,16 @@ else:
exit()
zram_max_warnings_kb, zram_max_warnings_mb, zram_max_warnings_percent = calculate_percent('zram_max_warnings')
# if 'zram_max_warnings' in config_dict:
# zram_max_warnings = config_dict['zram_max_warnings']
# if zram_max_warnings.endswith('%'):
# # отбрасываем процент, получаем число
# zram_max_warnings_percent = zram_max_warnings[:-1].strip()
# # далее флоат тест
# zram_max_warnings_percent = string_to_float_convert_test(zram_max_warnings_percent)
# if zram_max_warnings_percent is None:
# print('Invalid zram_max_warnings value, not float\nExit')
# exit()
# # окончательная валидация
# if zram_max_warnings_percent < 0 or zram_max_warnings_percent > 100:
# print('zram_max_warnings, выраженный в процентах, должен быть быть в диапазоне [0; 100]\nExit')
# exit()
# # zram_max_warnings_percent это теперь чистое валидное флоат число процентов, можно переводить в кб
# zram_max_warnings_kb = zram_max_warnings_percent / 100 * mem_total
# zram_max_warnings_mb = round(zram_max_warnings_kb / 1024)
# elif zram_max_warnings.endswith('M'):
# zram_max_warnings_mb = string_to_float_convert_test(zram_max_warnings[:-1].strip())
# if zram_max_warnings_mb is None:
# print('Invalid zram_max_warnings value, not float\nExit')
# exit()
# zram_max_warnings_kb = zram_max_warnings_mb * 1024
# if zram_max_warnings_kb > mem_total:
# print('zram_max_warnings value не должен быть больше MemTotal ({} MiB)\nExit'.format(round(mem_total / 1024)))
# exit()
# zram_max_warnings_percent = zram_max_warnings_kb / mem_total * 100
# else:
# print('Конфиг инвалид, для zram_max_warnings неверно указаны единицы измерения\nExit')
# exit()
# else:
# print('zram_max_warnings not in config\nExit')
# exit()
execute_the_command = conf_parse_bool('execute_the_command')
##########################################################################
# Get Kibibytes levels
# Returns Kilobytes value if absolute value was set in config,
# Returns Kibibytes value if absolute value was set in config,
# or tuple with percentage
def sig_level_to_kb_swap(string):
"""Returns Kilobytes value if abs val was set in config, or tuple with %"""
"""Returns Kibibytes value if abs val was set in config, or tuple with %"""
if string.endswith('%'):
return float(string[:-1].strip()), True
elif string.endswith('M'):
@ -1271,6 +1025,9 @@ else:
# self-defense
# возожно стоит убрать поддержку mlockall и ionice
# Increase priority
try:
os.nice(niceness)
@ -1285,11 +1042,9 @@ try:
file.write('{}\n'.format(oom_score_adj))
oom_score_adj_result = 'OK'
except PermissionError:
pass
oom_score_adj_result = 'Fail'
except OSError:
oom_score_adj_result = 'Fail'
pass
# Deny process swapping
if mlockall:
@ -1324,7 +1079,8 @@ if root and realtime_ionice:
if print_config:
print('\n1. Memory levels to respond to as an OOM threat\n[displaying these options need fix]\n')
print(
'\n1. Memory levels to respond to as an OOM threat\n[displaying these options need fix]\n')
print('mem_min_sigterm: {} MiB, {} %'.format(
round(mem_min_sigterm_mb), round(mem_min_sigterm_percent, 1)))
@ -1386,7 +1142,8 @@ if print_config:
print('zram_max_warnings: {} MiB, {} %'.format(
round(zram_max_warnings_mb), round(zram_max_warnings_percent, 1)))
print('\n7. Preventing the slowing down of the program\n[displaying these options need fix]\n')
print(
'\n7. Preventing the slowing down of the program\n[displaying these options need fix]\n')
print('mlockall: {} ({})'.format(mlockall, mla_res))
print('niceness: {} ({})'.format(
niceness, niceness_result
@ -1433,6 +1190,9 @@ warn_timer = 0
print('Monitoring started!')
##########################################################################
@ -1461,6 +1221,7 @@ while True:
if swap_warn_is_percent:
swap_min_warnings_kb = swap_total * swap_min_warnings_percent / 100.0
# find MemUsedZram
disksize_sum = 0
mem_used_total_sum = 0
@ -1469,10 +1230,24 @@ while True:
stat = zram_stat(dev)
disksize_sum += int(stat[0])
mem_used_total_sum += int(stat[1])
# Означает, что при задани zram disksize = 10000M доступная память
# уменьшится на 42 MiB.
# Найден экспериментально, требует уточнения с разными ядрами и архитектурами.
# На небольших дисксайзах (до гигабайта) может быть больше, до 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 = deltaMemAvailavle / disksize
# found experimentally
zram_disksize_factor = 0.0042
mem_used_zram = (
mem_used_total_sum + disksize_sum * zram_disksize_factor
) / 1024.0
if print_mem_check_results:
# Calculate 'swap-column' width
@ -1512,6 +1287,7 @@ while True:
else:
# СТОИТ ПЕЧАТАТЬ СВОП ТОЛЬКО ПРИ SwapTotal > 0
# нет, печатать так: SwapTotal = 0 KiB, ignore swapspace
swap_sigterm_pc = '-'
# Limits overdrafting checks
@ -1592,7 +1368,8 @@ while True:
# LOW MEMORY WARNINGS
elif gui_low_memory_warnings:
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() - warn_time_now
warn_time_now = time()
warn_timer += warn_time_delta
@ -1603,7 +1380,5 @@ while True:
# SLEEP BETWEEN MEM CHECKS
else:
stdout.flush()
sleep_after_check_mem()