fix low mem warn slowdown

This commit is contained in:
Alexey Avramov 2018-11-19 23:07:17 +09:00
parent 37bb9780ff
commit 3faa07ba95
3 changed files with 102 additions and 14 deletions

View File

@ -8,6 +8,9 @@ install:
install -d $(DESTDIR)/$(PREFIX)/usr/sbin install -d $(DESTDIR)/$(PREFIX)/usr/sbin
install -m0755 ./nohang $(DESTDIR)/$(PREFIX)/usr/sbin/nohang install -m0755 ./nohang $(DESTDIR)/$(PREFIX)/usr/sbin/nohang
install -d $(DESTDIR)/$(PREFIX)/usr/sbin
install -m0755 ./nohang_notify_low_mem $(DESTDIR)/$(PREFIX)/usr/sbin/nohang_notify_low_mem
install -d $(DESTDIR)/$(PREFIX)/etc/nohang install -d $(DESTDIR)/$(PREFIX)/etc/nohang
install -m0644 ./nohang.conf $(DESTDIR)/$(PREFIX)/etc/nohang install -m0644 ./nohang.conf $(DESTDIR)/$(PREFIX)/etc/nohang
install -m0644 ./default_values_backup.conf $(DESTDIR)/$(PREFIX)/etc/nohang install -m0644 ./default_values_backup.conf $(DESTDIR)/$(PREFIX)/etc/nohang
@ -23,6 +26,7 @@ uninstall:
# 'make uninstall' must not fail with error if systemctl is unavailable or returns error # 'make uninstall' must not fail with error if systemctl is unavailable or returns error
systemctl disable nohang.service || true systemctl disable nohang.service || true
rm -fv $(PREFIX)/usr/sbin/nohang rm -fv $(PREFIX)/usr/sbin/nohang
rm -fv $(PREFIX)/usr/sbin/nohang_notify_low_mem
rm -fv $(PREFIX)/usr/share/man/man1/nohang.1.gz rm -fv $(PREFIX)/usr/share/man/man1/nohang.1.gz
rm -fv $(PREFIX)/lib/systemd/system/nohang.service rm -fv $(PREFIX)/lib/systemd/system/nohang.service
rm -fvr $(PREFIX)/etc/nohang/ rm -fvr $(PREFIX)/etc/nohang/

25
nohang
View File

@ -204,35 +204,33 @@ def pid_to_name(pid):
def send_notify_warn(): def send_notify_warn():
# find process with max badness
fat_tuple = fattest() fat_tuple = fattest()
pid = fat_tuple[1]
name = fat_tuple[0]
if mem_used_zram > 0: if mem_used_zram > 0:
title = 'Low memory: {}% {}% {}%'.format( low_mem_percent = '{}% {}% {}%'.format(
round(mem_available / mem_total * 100), round(mem_available / mem_total * 100),
round(swap_free / (swap_total + 0.1) * 100), round(swap_free / (swap_total + 0.1) * 100),
round(mem_used_zram / mem_total * 100)) round(mem_used_zram / mem_total * 100))
elif swap_free > 0: elif swap_free > 0:
title = 'Low memory: {}% {}%'.format( low_mem_percent = '{}% {}%'.format(
round(mem_available / mem_total * 100), round(mem_available / mem_total * 100),
round(swap_free / (swap_total + 0.1) * 100)) round(swap_free / (swap_total + 0.1) * 100))
else: else:
title = 'Low memory: {}%'.format( low_mem_percent = '{}%'.format(
round(mem_available / mem_total * 100)) round(mem_available / mem_total * 100))
body = 'Fattest process: <b>{}</b>, <b>{}</b>'.format(fat_tuple[1], fat_tuple[0]) title = 'Low memory: {}'.format(low_mem_percent)
body = 'Fattest process: <b>{}</b>, <b>{}</b>'.format(pid, name)
if root: if root:
# отправляем уведомление всем залогиненным пользователям # send notification to all active users
b = root_notify_env() Popen(['/usr/sbin/nohang_notify_low_mem', '--mem', low_mem_percent, '--pid', pid, '--name', name])
if len(b) > 0:
for i in b:
username, display_env, dbus_env = i[0], i[1], i[2]
Popen(['sudo', '-u', username, 'env', display_env,
dbus_env, 'notify-send', '--icon=dialog-warning',
'{}'.format(title), '{}'.format(body)])
else: else:
# отправляем уведомление пользователю, который запустил nohang # отправляем уведомление пользователю, который запустил nohang
Popen(['notify-send', '--icon=dialog-warning', '{}'.format(title), '{}'.format(body)]) Popen(['notify-send', '--icon=dialog-warning', 'Low memory: {}'.format(title), '{}'.format(body)])
def send_notify(signal, name, pid): def send_notify(signal, name, pid):
@ -1515,4 +1513,3 @@ while True:
stdout.flush() stdout.flush()
sleep_after_check_mem() sleep_after_check_mem()

87
nohang_notify_low_mem Executable file
View File

@ -0,0 +1,87 @@
#!/usr/bin/env python3
# notify_low_mem --mem '14% 12%' --name 'stress' --pid '6666'
# output:
# Low memory: 14% 12%
# Fattest process: 6666, stress
from argparse import ArgumentParser
from subprocess import Popen, PIPE
parser = ArgumentParser()
parser.add_argument(
'--mem',
help="""available memory percent (15%, for example)""",
default=None,
type=str
)
parser.add_argument(
'--pid',
help="""pid""",
default=None,
type=str
)
parser.add_argument(
'--name',
help="""process name""",
default=None,
type=str
)
args = parser.parse_args()
pid = args.pid
name = args.name
mem = args.mem
title = 'Low memory: {}'.format(mem)
body = 'Fattest process: <b>{}</b>, <b>{}</b>'.format(pid, name)
# return list of tuples with
# username, DISPLAY and DBUS_SESSION_BUS_ADDRESS
def root_notify_env():
ps_output_list = Popen(['ps', 'ae'], stdout=PIPE
).communicate()[0].decode().split('\n')
lines_with_displays = []
for line in ps_output_list:
if ' DISPLAY=' in line and ' DBUS_SESSION_BUS_ADDRES' \
'S=' in line and ' USER=' in line:
lines_with_displays.append(line)
# list of tuples with needments
deus = []
for i in lines_with_displays:
for i in i.split(' '):
if i.startswith('USER='):
user = i.strip('\n').split('=')[1]
continue
if i.startswith('DISPLAY='):
disp_value = i.strip('\n').split('=')[1][0:2]
disp = 'DISPLAY=' + disp_value
continue
if i.startswith('DBUS_SESSION_BUS_ADDRESS='):
dbus = i.strip('\n')
deus.append(tuple([user, disp, dbus]))
# unique list of tuples
vult = []
for user_env_tuple in set(deus):
vult.append(user_env_tuple)
return vult
b = root_notify_env()
if len(b) > 0:
for i in b:
username, display_env, dbus_env = i[0], i[1], i[2]
Popen(['sudo', '-u', username, 'env', display_env,
dbus_env, 'notify-send', '--icon=dialog-warning',
'{}'.format(title), '{}'.format(body)])