add --version and --test flags
This commit is contained in:
parent
87677465ce
commit
e568f416a3
8
Makefile
8
Makefile
@ -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
175
nohang
@ -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:
|
||||
|
@ -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.')
|
||||
|
Loading…
Reference in New Issue
Block a user