From ff4215412f2db595d5e12b8e8213122d2940c33d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 18 Feb 2016 01:37:32 -0500 Subject: [PATCH] gentoo-check-services: handle deleted files/libs automatically --- .bin/gentoo-check-services | 157 +++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 .bin/gentoo-check-services diff --git a/.bin/gentoo-check-services b/.bin/gentoo-check-services new file mode 100755 index 0000000..bff7b33 --- /dev/null +++ b/.bin/gentoo-check-services @@ -0,0 +1,157 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +"""Script for restarting services that refer to old/deleted libs.""" + +from __future__ import print_function + +import argparse +import glob +import os +import signal +import sys +import time + + +# Set of paths that are "OK" and safe to ignore. +IGNORE_PATHS = set(( + '/dev/zero', + '/etc/ld.so.cache', +)) + + +def find_svcs(): + """Find all programs w/deleted paths.""" + svcs = {} + for pid in os.listdir('/proc'): + try: + pid_nr = int(pid) + except ValueError: + continue + + map = '/proc/%s/maps' % pid + if not os.path.exists(map): + print('skipping %s' % pid) + continue + + old_paths = set() + for line in open(map): + if not line.endswith(' (deleted)\n'): + continue + # b71c7000-b7307000 rw-s 00000000 00:04 17024337 /dev/zero (deleted) + addr, perm, offset, dev, inode, path, _ = line.split() + if (path == '/[aio]' or + path.startswith('/SYSV') or + path.startswith('/dev/shm/')): + continue + old_paths.add(path) + + old_paths -= IGNORE_PATHS + if not old_paths: + continue + + cmdline = open('/proc/%s/cmdline' % pid).read().split('\0') + try: + while True: + cmdline.remove('') + except ValueError: + pass + svcs[pid_nr] = { + 'cmdline': cmdline, + 'old_paths': old_paths, + } + return svcs + + +# Mapping of known programs to their init.d scripts. +SERVICES = { + '/usr/sbin/acpid': 'acpid', + '/usr/sbin/apache2': 'apache2', + '/usr/sbin/atd': 'atd', + '/usr/sbin/bacula-fd': 'bacula-fd', + '/usr/sbin/cron': 'vixie-cron', + '/usr/sbin/crond': 'dcron', + '/usr/sbin/snmpd': 'snmpd', + '/usr/sbin/sshd': 'sshd', + '/usr/sbin/syslog-ng': 'syslog-ng', + '/usr/sbin/xinetd': 'xinetd', + '/usr/bin/distccd': 'distccd', + '/usr/bin/monit': 'monit', + '/usr/bin/stunnel': 'stunnel', + '/usr/bin/tor': 'tor', + '/usr/bin/transmission-daemon': 'transmission-daemon', + '/usr/bin/mediatomb': 'mediatomb', + '/lib/systemd/systemd-udevd': 'udev', + '/usr/libexec/nrpe': 'nrpe', + '/usr/libexec/postfix/master': 'postfix', + 'denyhosts.py': 'denyhosts', + 'dropbear': 'dropbear', + 'galileo': 'galileo', + 'tlsdated': 'tlsdated', +} +def auto_restart(svcs): + kill = set() + restart = set() + for pid, svc in svcs.items(): + if svc['cmdline'][0] == '/sbin/agetty': + kill.add(pid) + elif 'postgres:' in svc['cmdline'][0]: + p = os.path.basename(glob.glob('/etc/runlevels/default/postgresql-*')[0]) + restart.add(p) + elif svc['cmdline'][0].startswith('metalog'): + restart.add('metalog') + else: + prog = svc['cmdline'][0] + if prog.startswith('/usr/bin/python'): + prog = os.path.basename(svc['cmdline'][1]) + + init = SERVICES.get(prog) + if init: + restart.add(init) + + if kill or restart: + for pid in kill: + print('killing %s (%s)' % (pid, svcs[pid]['cmdline'][0])) + os.kill(pid, signal.SIGTERM) + for init in restart: + print('restarting %s' % init) + os.system('/etc/init.d/%s -q restart' % init) + + time.sleep(1) + svcs = find_svcs() + + return svcs + + +def summarize(svcs): + print() + sslh = False + for pid in svcs.keys(): + if svcs[pid]['cmdline'][0] == '/usr/sbin/sslh': + del svcs[pid] + sslh = True + if sslh: + print('sslh needs restart') + + print() + for pid, svc in svcs.items(): + print(pid, svc['cmdline']) + print('\t%s' % '\n\t'.join(svc['old_paths'])) + + +def get_parser(): + parser = argparse.ArgumentParser(description=__doc__) + return parser + + +def main(argv): + parser = get_parser() + opts = parser.parse_args(argv) + + svcs = find_svcs() + svcs = auto_restart(svcs) + summarize(svcs) + + +if __name__ == '__main__': + exit(main(sys.argv[1:])) -- 2.39.5