diff --git a/nohang b/nohang index 2ad110e..53fcddb 100755 --- a/nohang +++ b/nohang @@ -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 diff --git a/nohang.conf b/nohang.conf index 0b6be90..94435b0 100644 --- a/nohang.conf +++ b/nohang.conf @@ -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 ##################################################################### diff --git a/nohang_notify_helper b/nohang_notify_helper index df8c8b5..3ac4ded 100755 --- a/nohang_notify_helper +++ b/nohang_notify_helper @@ -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.')