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