add --version and --test flags

This commit is contained in:
Alexey Avramov 2019-03-06 02:32:03 +09:00
parent 87677465ce
commit e568f416a3
3 changed files with 163 additions and 49 deletions

View File

@ -1,10 +1,10 @@
#
VERSION ?= $(shell git describe --tags --long --dirty > /etc/nohang/version 2> /dev/null)
PREFIX = /
all:
@ echo "Nothing to compile. Use: make install, make uninstall, make systemd"
install:
install:
install -d $(DESTDIR)/$(PREFIX)/usr/sbin
install -m0755 ./nohang $(DESTDIR)/$(PREFIX)/usr/sbin/nohang
install -m0755 ./nohang_notify_helper $(DESTDIR)/$(PREFIX)/usr/sbin/nohang_notify_helper
@ -14,8 +14,8 @@ install:
install -m0755 ./oom-trigger $(DESTDIR)/$(PREFIX)/usr/bin/oom-trigger
install -d $(DESTDIR)/$(PREFIX)/etc/nohang
install -m0644 ./nohang.conf $(DESTDIR)/$(PREFIX)/etc/nohang
install -m0644 ./nohang.conf $(DESTDIR)/$(PREFIX)/etc/nohang/nohang.conf.backup
install -m0644 ./nohang.conf $(DESTDIR)/$(PREFIX)/etc/nohang/$(VERSION)
install -m0644 ./nohang.conf $(DESTDIR)/$(PREFIX)/etc/nohang/nohang.conf.default
install -d $(DESTDIR)/$(PREFIX)/usr/share/man/man1
gzip -k -c nohang.1 > $(DESTDIR)/$(PREFIX)/usr/share/man/man1/nohang.1.gz

175
nohang
View File

@ -7,6 +7,7 @@ from time import sleep, time
from operator import itemgetter
from sys import stdout, stderr, argv, exit
from signal import SIGKILL, SIGTERM
import sys
start_time = time()
@ -50,11 +51,10 @@ HR = ''
victim_dict = dict()
# extra_process_table_info = None
extra_process_table_info = None
# will store corrective actions stat
stat_dict = dict()
##########################################################################
@ -62,6 +62,87 @@ extra_process_table_info = None
# define functions
def print_version():
try:
v = rline1('/etc/nohang/version')
except FileNotFoundError:
v = None
if v is None:
print('nohang unknown version')
else:
print(v)
exit()
def test():
print(sys.version)
print(sys.argv)
hr = '=================================='
print(hr)
print("uptime()")
print(uptime())
print(hr)
print("pid_to_starttime('self')")
print(pid_to_starttime('self'))
print(hr)
print("get_victim_id('self')")
print(get_victim_id('self'))
print(hr)
print("errprint('test')")
print(errprint('test'))
print(hr)
print("mlockall()")
print(mlockall())
print(hr)
print("pid_to_state('2')")
print(pid_to_state('2'))
'''
print(hr)
print("update_stat_dict_and_print('key')")
print(update_stat_dict_and_print('key'))
print(hr)
print("psi_mem_some_avg_total()")
print(psi_mem_some_avg_total())
print(hr)
print("psi_mem_some_avg10()")
print(psi_mem_some_avg10())
print(hr)
print("check_mem()")
print(check_mem())
print(hr)
print("os.uname()")
print(os.uname())
print(hr)
print("check_mem()")
print(check_mem())
'''
print(hr)
exit()
def uptime():
return float(rline1('/proc/uptime').split(' ')[0])
@ -146,11 +227,13 @@ def psi_mem_some_avg_total():
def psi_mem_some_avg10():
return float(rline1(psi_path).split(' ')[1].split('=')[1])
if psi_support:
return float(rline1(psi_path).split(' ')[1].split('=')[1])
def check_mem():
"""find mem_available"""
# исправить название фции
return int(rline1('/proc/meminfo').split(':')[1][:-4])
@ -402,7 +485,6 @@ def pid_to_cmdline(pid):
return f.read().replace('\x00', ' ').rstrip()
def pid_to_realpath(pid):
try:
return os.path.realpath('/proc/' + pid + '/exe')
@ -410,10 +492,6 @@ def pid_to_realpath(pid):
return ''
def pid_to_uid(pid):
'''return euid'''
try:
@ -508,6 +586,8 @@ def send_notify_warn():
round(swap_free / (swap_total + 0.1) * 100)
)
b = 'head ' + str(b.encode())
t0 = time()
os.system(b)
t1 = time()
@ -682,7 +762,7 @@ def find_victim():
pid_to_uid(pid).rjust(10),
pid_to_cmdline(pid)
# pid_to_realpath(pid)
)
)
)
pid_badness_list.append((pid, badness))
@ -718,7 +798,6 @@ def find_victim():
def find_victim_info(pid, victim_badness, name):
status0 = time()
try:
@ -964,7 +1043,9 @@ def implement_corrective_action(signal):
etc_info = '\nImplement a corrective action:\n Run the command: {}' \
'\n Exit status: {}; total response time: {} ms'.format(
command.replace('$PID', pid).replace('$NAME', pid_to_name(pid)),
command.replace(
'$PID', pid).replace(
'$NAME', pid_to_name(pid)),
exit_status,
round(response_time * 1000))
@ -1042,7 +1123,6 @@ def implement_corrective_action(signal):
key = 'victim badness < min_badness'
update_stat_dict_and_print(key)
print('###############################################################################')
sleep_after_send_signal(signal)
@ -1167,6 +1247,11 @@ def calculate_percent(arg_key):
##########################################################################
if len(argv) == 1:
if os.path.exists('./nohang.conf'):
config = cd = os.getcwd() + '/nohang.conf'
@ -1175,8 +1260,12 @@ if len(argv) == 1:
elif len(argv) == 2:
if argv[1] == '--help' or argv[1] == '-h':
errprint(help_mess)
exit(1)
print(help_mess)
exit()
elif argv[1] == '--version' or argv[1] == '-v':
print_version()
elif argv[1] == '--test' or argv[1] == '-t':
test()
else:
errprint('Invalid CLI input')
exit(1)
@ -1193,6 +1282,14 @@ else:
exit(1)
##########################################################################
@ -1267,8 +1364,7 @@ uid_re_list = []
# тут тоже список нужен, а не словарь
etc_dict = dict()
# will store corrective actions stat
stat_dict = dict()
try:
with open(config) as f:
@ -1340,14 +1436,7 @@ except FileNotFoundError:
# validation of all parameters
print_victim_info = conf_parse_bool('print_victim_info')
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')
@ -1355,16 +1444,12 @@ 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')
execute_the_command = conf_parse_bool('execute_the_command')
ignore_psi = conf_parse_bool('ignore_psi')
regex_matching = conf_parse_bool('regex_matching')
re_match_cmdline = conf_parse_bool('re_match_cmdline')
re_match_uid = conf_parse_bool('re_match_uid')
if regex_matching or re_match_cmdline or re_match_uid:
from re import search
import sre_constants
@ -1648,6 +1733,30 @@ if max_sleep_time < min_sleep_time:
##########################################################################
# Get KiB levels if it's possible.
# получ кб. если не кб - то процент. Если процент - находим кб ниже на
@ -1851,6 +1960,9 @@ if print_mem_check_results:
report0 = 0
while True:
if psi_support and not ignore_psi:
@ -1944,7 +2056,8 @@ while True:
just_percent_mem(mem_available / mem_total),
human(swap_free, swap_len),
just_percent_swap(swap_free / (swap_total + 0.1)),
speed_info)
speed_info
)
)
else:

View File

@ -4,14 +4,14 @@
# ./nohang_notify_helper "title" "body"
from sys import argv, stdout
from os import listdir
from os import listdir, path
from subprocess import Popen, TimeoutExpired
if len(argv) < 2 or argv[1] == "-h" or argv[1] == "--help":
print('Usage: ./nohang_notify_helper "title" "body"')
exit(1)
wait_time = 10
wait_time = 15
display_env = 'DISPLAY='
dbus_env = 'DBUS_SESSION_BUS_ADDRESS='
@ -57,21 +57,19 @@ def re_pid_environ(pid):
if i.startswith('HOME=/var'):
return None
try:
# dirty hack; todo: fix alg
env = user.partition('USER=')[2], display, dbus
except UnboundLocalError:
print('notify helper: UnboundLocalError')
# print('notify helper: UnboundLocalError')
return None
return env
except FileNotFoundError:
print('notify helper: FileNotFoundError')
# print('notify helper: FileNotFoundError')
return None
except ProcessLookupError:
print('notify helper: ProcessLookupError')
# print('notify helper: ProcessLookupError')
return None
@ -80,10 +78,11 @@ def root_notify_env():
unsorted_envs_list = []
# iterates over processes, find processes with suitable env
for pid in listdir('/proc'):
if pid[0].isdecimal() is False:
continue
one_env = re_pid_environ(pid)
unsorted_envs_list.append(one_env)
if path.exists('/proc/' + pid + '/exe') is True:
one_env = re_pid_environ(pid)
unsorted_envs_list.append(one_env)
env = set(unsorted_envs_list)
env.discard(None)
@ -134,6 +133,8 @@ if list_len > 0:
proc.kill()
print('TimeoutExpired: notify user:' + username)
else:
print('Not send GUI notification: [', argv[1], argv[2], ']. Nobody logged-in with GUI. Nothing to do.')
stdout.flush()
print(
'Not send GUI notification: [',
argv[1],
argv[2],
']. Nobody logged-in with GUI. Nothing to do.')