diff --git a/Makefile b/Makefile
index 591e414..3e5ef62 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,9 @@ install:
install -d $(DESTDIR)/$(PREFIX)/usr/sbin
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 -m0644 ./nohang.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
systemctl disable nohang.service || true
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)/lib/systemd/system/nohang.service
rm -fvr $(PREFIX)/etc/nohang/
diff --git a/nohang b/nohang
index 55ed22f..77bc0a3 100755
--- a/nohang
+++ b/nohang
@@ -204,35 +204,33 @@ def pid_to_name(pid):
def send_notify_warn():
+ # find process with max badness
fat_tuple = fattest()
+ pid = fat_tuple[1]
+ name = fat_tuple[0]
if mem_used_zram > 0:
- title = 'Low memory: {}% {}% {}%'.format(
+ low_mem_percent = '{}% {}% {}%'.format(
round(mem_available / mem_total * 100),
round(swap_free / (swap_total + 0.1) * 100),
round(mem_used_zram / mem_total * 100))
elif swap_free > 0:
- title = 'Low memory: {}% {}%'.format(
+ low_mem_percent = '{}% {}%'.format(
round(mem_available / mem_total * 100),
round(swap_free / (swap_total + 0.1) * 100))
else:
- title = 'Low memory: {}%'.format(
+ low_mem_percent = '{}%'.format(
round(mem_available / mem_total * 100))
- body = 'Fattest process: {}, {}'.format(fat_tuple[1], fat_tuple[0])
+ title = 'Low memory: {}'.format(low_mem_percent)
+ body = 'Fattest process: {}, {}'.format(pid, name)
if root:
- # отправляем уведомление всем залогиненным пользователям
- 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)])
+ # send notification to all active users
+ Popen(['/usr/sbin/nohang_notify_low_mem', '--mem', low_mem_percent, '--pid', pid, '--name', name])
else:
# отправляем уведомление пользователю, который запустил 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):
@@ -1515,4 +1513,3 @@ while True:
stdout.flush()
sleep_after_check_mem()
-
diff --git a/nohang_notify_low_mem b/nohang_notify_low_mem
new file mode 100755
index 0000000..53ff4ff
--- /dev/null
+++ b/nohang_notify_low_mem
@@ -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: {}, {}'.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)])