swap-related units user input validation
This commit is contained in:
parent
5cad925f5f
commit
bd313a6952
176
nohang
176
nohang
@ -40,27 +40,11 @@ HR = '~' * 79
|
||||
print_total_stat = True
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
|
||||
# define functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def zenity():
|
||||
# test
|
||||
os.system('''sudo -u user DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus zenity --checklist --timeout=10 --text="\n <b>Mem Available: 10% (300 MiB)</b>. \n\n Select a process to be terminated:\n" --ok-label "Terminate" --cancel-label "Do nothing" --separator=" " --width=9999 --height=9999 --list --title="Low memory!" --column "" --column="Pid" --column="Name" --column="VmRSS" 9923 9923 Python3 "800 MiB" 2938 2938 tail "400 MiB" 3938 3938 chromium "300 MiB"''')
|
||||
|
||||
# zenity()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def update_stat_dict_and_print(key):
|
||||
|
||||
if key not in stat_dict:
|
||||
@ -83,7 +67,6 @@ def update_stat_dict_and_print(key):
|
||||
print(stats_msg)
|
||||
|
||||
|
||||
|
||||
def psi_mem_some_avg_total():
|
||||
if psi_support:
|
||||
return float(rline1(psi_path).rpartition('=')[2])
|
||||
@ -510,11 +493,6 @@ def find_victim_and_send_signal(signal):
|
||||
|
||||
if victim_badness >= min_badness:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Try to send signal to found victim
|
||||
|
||||
# Get VmRSS and VmSwap and cmdline of victim process
|
||||
@ -566,12 +544,14 @@ def find_victim_and_send_signal(signal):
|
||||
except FileNotFoundError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process: FileNotFoundError')
|
||||
update_stat_dict_and_print('The victim died in the search process: FileNotFoundError')
|
||||
update_stat_dict_and_print(
|
||||
'The victim died in the search process: FileNotFoundError')
|
||||
return None
|
||||
except ProcessLookupError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process: ProcessLookupError')
|
||||
update_stat_dict_and_print('The victim died in the search process: ProcessLookupError')
|
||||
update_stat_dict_and_print(
|
||||
'The victim died in the search process: ProcessLookupError')
|
||||
return None
|
||||
except UnicodeDecodeError:
|
||||
|
||||
@ -585,7 +565,8 @@ def find_victim_and_send_signal(signal):
|
||||
uid = f_list[i].split('\t')[2]
|
||||
|
||||
if i is vm_size_index:
|
||||
vm_size = kib_to_mib(int(f_list[i].split('\t')[1][:-3]))
|
||||
vm_size = kib_to_mib(
|
||||
int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if i is vm_rss_index:
|
||||
vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3]))
|
||||
@ -605,8 +586,8 @@ def find_victim_and_send_signal(signal):
|
||||
int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if i is vm_swap_index:
|
||||
vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
vm_swap = kib_to_mib(
|
||||
int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
with open('/proc/' + pid + '/cmdline') as file:
|
||||
cmdline = file.readlines()[0].replace('\x00', ' ')
|
||||
@ -617,15 +598,16 @@ def find_victim_and_send_signal(signal):
|
||||
except IndexError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process: IndexError')
|
||||
update_stat_dict_and_print('The victim died in the search process: IndexError')
|
||||
update_stat_dict_and_print(
|
||||
'The victim died in the search process: IndexError')
|
||||
return None
|
||||
except ValueError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process: ValueError')
|
||||
update_stat_dict_and_print('The victim died in the search process: ValueError')
|
||||
update_stat_dict_and_print(
|
||||
'The victim died in the search process: ValueError')
|
||||
return None
|
||||
|
||||
|
||||
len_vm = len(str(vm_size))
|
||||
|
||||
if detailed_rss:
|
||||
@ -679,16 +661,6 @@ def find_victim_and_send_signal(signal):
|
||||
str(vm_swap).rjust(len_vm),
|
||||
cmdline)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if execute_the_command and signal is SIGTERM and name in etc_dict:
|
||||
command = etc_dict[name]
|
||||
exit_status = os.system(etc_dict[name].replace(
|
||||
@ -719,22 +691,16 @@ def find_victim_and_send_signal(signal):
|
||||
name,
|
||||
command.replace('$PID', pid).replace('$NAME', pid_to_name(pid)))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
|
||||
t0 = time()
|
||||
|
||||
m = check_mem_and_swap()
|
||||
ma = round(int(m[0]) / 1024.0)
|
||||
sf = round(int(m[2]) / 1024.0)
|
||||
print('\nMemory status before sending a signal:\nMemAv: {} MiB, SwFree: {} MiB'.format(ma, sf))
|
||||
print(time() - t0)
|
||||
|
||||
|
||||
print('\nMemory status before sending a signal:\nMemA'
|
||||
'v: {} MiB, SwFree: {} MiB'.format(ma, sf))
|
||||
|
||||
os.kill(int(pid), signal)
|
||||
response_time = time() - time0
|
||||
send_result = '\033[32mOK\033[0m; response time: {} ms'.format(
|
||||
@ -748,10 +714,6 @@ def find_victim_and_send_signal(signal):
|
||||
key = 'Send \033[35m{}\033[0m to \033[35m{}\033[0m'.format(
|
||||
sig_dict[signal], name)
|
||||
|
||||
|
||||
# zenity()
|
||||
|
||||
|
||||
if gui_notifications:
|
||||
send_notify(signal, name, pid)
|
||||
|
||||
@ -766,15 +728,11 @@ def find_victim_and_send_signal(signal):
|
||||
round(response_time * 1000))
|
||||
key = 'The victim died in the search process: ProcessLookupError'
|
||||
|
||||
|
||||
print(mem_info)
|
||||
print(preventing_oom_message)
|
||||
|
||||
update_stat_dict_and_print(key)
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
|
||||
response_time = time() - time0
|
||||
@ -791,11 +749,9 @@ def find_victim_and_send_signal(signal):
|
||||
key = 'victim badness < min_badness'
|
||||
update_stat_dict_and_print(key)
|
||||
|
||||
|
||||
sleep_after_send_signal(signal)
|
||||
|
||||
|
||||
|
||||
def sleep_after_check_mem():
|
||||
"""Specify sleep times depends on rates and avialable memory."""
|
||||
|
||||
@ -955,6 +911,8 @@ cd = os.getcwd()
|
||||
|
||||
config = '/etc/nohang/nohang.conf'
|
||||
|
||||
# config = 'nohang.conf'
|
||||
|
||||
print('Config:', config)
|
||||
|
||||
|
||||
@ -1121,7 +1079,6 @@ else:
|
||||
exit()
|
||||
|
||||
|
||||
# НУЖНА ВАЛИДАЦИЯ НА МЕСТЕ!
|
||||
if 'swap_min_sigterm' in config_dict:
|
||||
swap_min_sigterm = config_dict['swap_min_sigterm']
|
||||
else:
|
||||
@ -1129,7 +1086,6 @@ else:
|
||||
exit()
|
||||
|
||||
|
||||
# НУЖНА ВАЛИДАЦИЯ НА МЕСТЕ!
|
||||
if 'swap_min_sigkill' in config_dict:
|
||||
swap_min_sigkill = config_dict['swap_min_sigkill']
|
||||
else:
|
||||
@ -1249,7 +1205,6 @@ else:
|
||||
exit()
|
||||
|
||||
|
||||
# НА МЕСТЕ!!!
|
||||
if 'swap_min_warnings' in config_dict:
|
||||
swap_min_warnings = config_dict['swap_min_warnings']
|
||||
else:
|
||||
@ -1260,50 +1215,72 @@ else:
|
||||
##########################################################################
|
||||
|
||||
|
||||
# Get Kibibytes levels
|
||||
# Get KiB levels if it's possible.
|
||||
|
||||
# получ кб. если не кб - то процент. Если процент - находим кб ниже на
|
||||
# основе полученного своптотал и процентов.
|
||||
|
||||
|
||||
# Returns Kibibytes value if absolute value was set in config,
|
||||
# or tuple with percentage
|
||||
def sig_level_to_kb_swap(string):
|
||||
"""Returns Kibibytes value if abs val was set in config, or tuple with %"""
|
||||
def get_swap_threshold_tuple(string):
|
||||
# re (Num %, True) or (Num KiB, False)
|
||||
"""Returns KiB value if abs val was set in config, or tuple with %"""
|
||||
# return tuple with abs and bool: (abs %, True) or (abs MiB, False)
|
||||
|
||||
if string.endswith('%'):
|
||||
return float(string[:-1].strip()), True
|
||||
valid = string_to_float_convert_test(string[:-1])
|
||||
if valid is None:
|
||||
print('somewhere swap unit is not float_%')
|
||||
exit()
|
||||
|
||||
value = float(string[:-1].strip())
|
||||
if value < 0 or value > 100:
|
||||
print('invalid value, must be from the range[0; 100] %')
|
||||
exit()
|
||||
|
||||
return value, True
|
||||
|
||||
elif string.endswith('M'):
|
||||
return float(string[:-1].strip()) * 1024
|
||||
valid = string_to_float_convert_test(string[:-1])
|
||||
if valid is None:
|
||||
print('somewhere swap unit is not float_M')
|
||||
exit()
|
||||
|
||||
value = float(string[:-1].strip()) * 1024
|
||||
if value < 0:
|
||||
print('invalid unit in config (negative value)')
|
||||
exit()
|
||||
|
||||
return value, False
|
||||
|
||||
else:
|
||||
print('Invalid config file. There are invalid units somewhere\nExit')
|
||||
exit()
|
||||
|
||||
|
||||
# So, get them
|
||||
swap_min_sigterm_swap = sig_level_to_kb_swap(swap_min_sigterm)
|
||||
swap_min_sigkill_swap = sig_level_to_kb_swap(swap_min_sigkill)
|
||||
|
||||
swap_min_warnings_swap = sig_level_to_kb_swap(swap_min_warnings)
|
||||
swap_min_sigterm_tuple = get_swap_threshold_tuple(swap_min_sigterm)
|
||||
swap_min_sigkill_tuple = get_swap_threshold_tuple(swap_min_sigkill)
|
||||
swap_min_warnings_tuple = get_swap_threshold_tuple(swap_min_warnings)
|
||||
|
||||
|
||||
if isinstance(swap_min_sigterm_swap, tuple):
|
||||
swap_term_is_percent = True
|
||||
swap_min_sigterm_percent = swap_min_sigterm_swap[0]
|
||||
swap_term_is_percent = swap_min_sigterm_tuple[1]
|
||||
if swap_term_is_percent:
|
||||
swap_min_sigterm_percent = swap_min_sigterm_tuple[0]
|
||||
else:
|
||||
swap_term_is_percent = False
|
||||
swap_min_sigterm_kb = swap_min_sigterm_swap
|
||||
swap_min_sigterm_kb = swap_min_sigterm_tuple[0]
|
||||
|
||||
if isinstance(swap_min_sigkill_swap, tuple):
|
||||
swap_kill_is_percent = True
|
||||
swap_min_sigkill_percent = swap_min_sigkill_swap[0]
|
||||
|
||||
swap_kill_is_percent = swap_min_sigkill_tuple[1]
|
||||
if swap_kill_is_percent:
|
||||
swap_min_sigkill_percent = swap_min_sigkill_tuple[0]
|
||||
else:
|
||||
swap_kill_is_percent = False
|
||||
swap_min_sigkill_kb = swap_min_sigkill_swap
|
||||
swap_min_sigkill_kb = swap_min_sigkill_tuple[0]
|
||||
|
||||
|
||||
if isinstance(swap_min_warnings_swap, tuple):
|
||||
swap_warn_is_percent = True
|
||||
swap_min_warnings_percent = swap_min_warnings_swap[0]
|
||||
swap_warn_is_percent = swap_min_warnings_tuple[1]
|
||||
if swap_warn_is_percent:
|
||||
swap_min_warnings_percent = swap_min_warnings_tuple[0]
|
||||
else:
|
||||
swap_warn_is_percent = False
|
||||
swap_min_warnings_kb = swap_min_warnings_swap
|
||||
swap_min_warnings_kb = swap_min_warnings_tuple[0]
|
||||
|
||||
|
||||
##########################################################################
|
||||
@ -1413,16 +1390,6 @@ if psi_support and not ignore_psi:
|
||||
avg_value = ''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
if psi_support and not ignore_psi:
|
||||
@ -1447,6 +1414,8 @@ while True:
|
||||
|
||||
mem_available, swap_total, swap_free = check_mem_and_swap()
|
||||
|
||||
# если метры - получаем киб выше и сразу. см.
|
||||
|
||||
# if swap_min_sigkill is set in percent
|
||||
if swap_kill_is_percent:
|
||||
swap_min_sigkill_kb = swap_total * swap_min_sigkill_percent / 100.0
|
||||
@ -1457,6 +1426,9 @@ while True:
|
||||
if swap_warn_is_percent:
|
||||
swap_min_warnings_kb = swap_total * swap_min_warnings_percent / 100.0
|
||||
|
||||
# в общем случае для работы нужны килобайты. Если в процентах задано -
|
||||
# находим КБ тут, после получения своптотал.
|
||||
|
||||
mem_used_zram = check_zram()
|
||||
|
||||
if print_mem_check_results:
|
||||
@ -1503,6 +1475,8 @@ while True:
|
||||
# печатать так: SwapTotal = 0, ignore swapspace
|
||||
swap_sigterm_pc = '-'
|
||||
|
||||
# это для печати меминфо. Все переработать нахрен.
|
||||
|
||||
# далее пошло ветвление
|
||||
|
||||
# MEM SWAP KILL
|
||||
@ -1563,7 +1537,7 @@ while True:
|
||||
percent(mem_available / mem_total),
|
||||
kib_to_mib(mem_min_sigterm_kb),
|
||||
# percent(mem_min_sigterm_kb / mem_total),
|
||||
# ОКРУГЛЯТЬ НА МЕСТЕ ВЫШЕ
|
||||
# ОКРУГЛЯТЬ НА МЕСТЕ ВЫШЕ (или не выше, хз)
|
||||
round(mem_min_sigterm_percent, 1),
|
||||
kib_to_mib(swap_free),
|
||||
percent(swap_free / (swap_total + 0.1)),
|
||||
|
Loading…
Reference in New Issue
Block a user