fix GUI notifications

This commit is contained in:
Alexey Avramov 2019-03-21 06:32:59 +09:00
parent 2f4b89ff51
commit 74a20ce28e
3 changed files with 59 additions and 81 deletions

109
nohang
View File

@ -41,7 +41,7 @@ if self_uid == 0:
else:
root = False
wait_time = 10
# wait_time = 10
notify_helper_path = '/usr/sbin/nohang_notify_helper'
@ -63,18 +63,12 @@ separate_log = False # will be overwritten after parse config
# define functions
def func_print_proc_table():
print_proc_table = True
find_victim(print_proc_table)
exit()
def log(*msg):
"""
"""
@ -282,6 +276,12 @@ def check_mem():
return int(rline1('/proc/meminfo').split(':')[1][:-4])
def write(text):
file = '/dev/shm/nohang_notify'
with open(file, 'w') as f:
f.write(text)
def check_mem_and_swap():
"""find mem_available, swap_total, swap_free"""
with open('/proc/meminfo') as f:
@ -560,29 +560,6 @@ def pid_to_uid(pid):
return f_list[uid_index].split('\t')[2]
def notify_send_wait(title, body):
"""GUI notifications with UID != 0"""
with Popen(['notify-send', '--icon=dialog-warning', title, body]) as proc:
try:
proc.wait(timeout=wait_time)
except TimeoutExpired:
proc.kill()
print('TimeoutExpired: notify-send {} {}'.format(title, body))
def notify_helper(title, body):
"""GUI notification with UID = 0"""
with Popen([notify_helper_path, title, body]) as proc:
try:
proc.wait(timeout=wait_time)
except TimeoutExpired:
proc.kill()
print(
'TimeoutExpired: nohang_notify_helper: {} {}'.format(
title, body))
def send_notify_warn():
"""
Look for process with maximum 'badness' and warn user with notification.
@ -613,7 +590,7 @@ def send_notify_warn():
'''
'''
body = 'Next victim: {}[{}]'.format(
body2 = 'Next victim: {}[{}]'.format(
name.replace(
# symbol '&' can break notifications in some themes,
# therefore it is replaced by '*'
@ -634,18 +611,19 @@ def send_notify_warn():
# send notification to user that runs this nohang
notify_send_wait(title, body)
'''
#os.system('echo --- \ - $(sleep 5) - ')
b = """{} 'Low memory' 'MemAvail: {}%\nSwapFree: {}%' &""".format(
notify_helper_path,
t0 = time()
title = 'Low memoy'
body = 'MemAvail: {}%\nSwapFree: {}%'.format(
round(mem_available / mem_total * 100),
round(swap_free / (swap_total + 0.1) * 100)
)
b = 'head ' + str(b.encode())
t0 = time()
os.system(b)
write('{}\x00{}'.format(title, body))
os.system(notify_helper_path + ' &')
t1 = time()
print('t:', t1 - t0)
@ -667,12 +645,18 @@ def send_notify(signal, name, pid):
'&', '*'
)
)
write('{}\x00{}'.format(title, body))
os.system(notify_helper_path + ' &')
'''
if root:
# send notification to all active users with notify-send
notify_helper(title, body)
else:
# send notification to user that runs this nohang
notify_send_wait(title, body)
'''
def send_notify_etc(pid, name, command):
@ -689,12 +673,17 @@ def send_notify_etc(pid, name, command):
pid,
command.replace('&', '*')
)
write('{}\x00{}'.format(title, body))
os.system(notify_helper_path + ' &')
'''
if root:
# send notification to all active users with notify-send
notify_helper(title, body)
else:
# send notification to user that runs this nohang
notify_send_wait(title, body)
'''
def sleep_after_send_signal(signal):
@ -709,7 +698,7 @@ def sleep_after_send_signal(signal):
sleep(min_delay_after_sigkill)
else:
if print_sleep_periods:
print(
log(
'Sleep {} sec after implementing a corrective action'.format(
min_delay_after_sigterm))
sleep(min_delay_after_sigterm)
@ -1855,21 +1844,10 @@ if max_sleep_time < min_sleep_time:
exit(1)
if print_proc_table_flag:
func_print_proc_table()
##########################################################################
@ -1951,10 +1929,6 @@ else:
##########################################################################
if print_config:
print(
@ -2034,8 +2008,7 @@ if print_config:
# for calculating the column width when printing mem and zram
mem_len = len(str(round(mem_total / 1024.0)))
if gui_notifications or gui_low_memory_warnings:
from subprocess import Popen, TimeoutExpired
if gui_notifications:
notify_sig_dict = {SIGKILL: 'Killing',
SIGTERM: 'Terminating'}
@ -2061,7 +2034,7 @@ mlockall()
if print_proc_table:
find_victim()
find_victim(print_proc_table)
log('Monitoring started!')
@ -2193,17 +2166,17 @@ while True:
else:
log('{}MemAvail: {} M, {} % | SwapFree: {} M, {} % | Mem'
'UsedZram: {} M, {} %{}'.format(
avg_value,
human(mem_available, mem_len),
just_percent_mem(mem_available / mem_total),
human(swap_free, swap_len),
just_percent_swap(swap_free / (swap_total + 0.1)),
human(mem_used_zram, mem_len),
just_percent_mem(mem_used_zram / mem_total),
speed_info
)
)
'UsedZram: {} M, {} %{}'.format(
avg_value,
human(mem_available, mem_len),
just_percent_mem(mem_available / mem_total),
human(swap_free, swap_len),
just_percent_swap(swap_free / (swap_total + 0.1)),
human(mem_used_zram, mem_len),
just_percent_mem(mem_used_zram / mem_total),
speed_info
)
)
# если swap_min_sigkill задан в абсолютной величине и Swap_total = 0
if swap_total > swap_min_sigkill_kb: # If swap_min_sigkill is absolute

View File

@ -178,7 +178,7 @@ decrease_oom_score_adj = False
Valid values are integers from the range [0; 1000].
oom_score_adj_max = 30
oom_score_adj_max = 20
#####################################################################

View File

@ -3,15 +3,10 @@
# Usage:
# ./nohang_notify_helper "title" "body"
from sys import argv, stdout
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 = 15
wait_time = 10
display_env = 'DISPLAY='
dbus_env = 'DBUS_SESSION_BUS_ADDRESS='
@ -25,6 +20,15 @@ def rline1(path):
return line
def rfile(path):
"""read file."""
with open(path) as f:
return f.read()
a1, a2 = rfile('/dev/shm/nohang_notify').split('\x00')
def re_pid_environ(pid):
"""
read environ of 1 process
@ -108,9 +112,7 @@ list_len = len(list_with_envs)
if list_len > 0:
for i in list_with_envs:
print('Send GUI notification:', argv[1], argv[2], i)
stdout.flush()
print('Send GUI notification:', a1, a2, i)
# iterating over logged-in users
for i in list_with_envs:
@ -125,7 +127,10 @@ if list_len > 0:
'env',
'DISPLAY=' + display_value,
'DBUS_SESSION_BUS_ADDRESS=' + dbus_value,
'notify-send', '--icon=dialog-warning', argv[1], argv[2]
'notify-send',
'--icon=dialog-warning',
a1,
a2
]) as proc:
try:
proc.wait(timeout=wait_time)
@ -135,6 +140,6 @@ if list_len > 0:
else:
print(
'Not send GUI notification: [',
argv[1],
argv[2],
a1,
a2,
']. Nobody logged-in with GUI. Nothing to do.')