From d08fa867d4769348f6a5b855b8820fd1330096dd Mon Sep 17 00:00:00 2001 From: Fredrik Eriksson Date: Sun, 7 Apr 2019 14:29:54 +0200 Subject: [PATCH] fixed detection of deleted files on linux --- bin/sau | 11 +++++++++-- sau/gentoo.py | 40 ++++++++++++++++++++++++++++------------ sau/services.py | 21 ++++++++++++++++++++- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/bin/sau b/bin/sau index 2630ac3..8f6f37d 100755 --- a/bin/sau +++ b/bin/sau @@ -5,6 +5,7 @@ import logging.handlers import os import platform import sys +import time import sau import sau.services @@ -14,14 +15,20 @@ import sau.platforms def main(): conf = sau.config log = logging.getLogger(sau.LOGNAME) - reboot_required = False platform = sau.platforms.get_platform() - #reboot_required = platform.system_upgrade() + reboot_required = platform.system_upgrade() platform.pkg_upgrade() reboot_recommended = sau.services.restart_services() if conf.getboolean('default', 'do_reboot', fallback=False): + if reboot_required: + log.warning('Rebooting because of a system upgrade') + elif reboot_recommended: + log.warning('Rebooting because service restarts did not close all deleted files') if reboot_required or reboot_recommended: + # sleep a little to make sure the above log-messages has reached + # syslog before we reboot + time.sleep(1) os.system('/sbin/reboot') diff --git a/sau/gentoo.py b/sau/gentoo.py index b4be270..91b546b 100644 --- a/sau/gentoo.py +++ b/sau/gentoo.py @@ -72,7 +72,7 @@ def identify_service_from_bin(exe): def restart_service(service): log = logging.getLogger(sau.LOGNAME) - cmd = [ SERVICE_PATH, service, 'restart' ] + cmd = [ RC_SERVICE_PATH, service, 'restart' ] log.debug('Executing "{}"'.format(' '.join(cmd))) proc = subprocess.Popen( cmd, @@ -92,6 +92,7 @@ def restart_service(service): log.info("restarted service {}".format(service)) def system_upgrade(): + log = logging.getLogger(sau.LOGNAME) log.debug('Gentoo has no concept of system upgrade, ignoring...') return False @@ -179,18 +180,11 @@ def _get_upgradable_packages_eix(): return upgradable -def _get_upgradable_packages(): - log = loggin.getLogger(sau.LOGNAME) - conf = sau.config - - pretend_re = re.compile(r'^\[ebuild ([^\]]*)\] ([^ ]+)( \[([^\])]\])?') - def pkg_upgrade(): log = logging.getLogger(sau.LOGNAME) conf = sau.config _sync_portage() - #packages = _get_upgradable_packages() # [ebuild U ] media-plugins/alsa-plugins-1.1.8 [1.1.6] pretend_re = re.compile(r'^\[ebuild ([^\]]*)\] ([^ ]+)( \[[^\]]+\])?') @@ -240,7 +234,7 @@ def pkg_upgrade(): min_diff = conf.getint('packages', name, fallback=default_version_diff) diff = sau.helpers.version_diff(version, old) if min_diff >= diff: - log.debug('{}-{} -> {} configured level {} >= pkg level {}'.format(name, old, version, min_diff, diff)) + log.info('{}-{} -> {} configured level {} >= pkg level {}'.format(name, old, version, min_diff, diff)) else: log.warning('{}-{} -> {} configured level {} < pkg level {}'.format(name, old, version, min_diff, diff)) do_rebuild = False @@ -259,8 +253,8 @@ def pkg_upgrade(): out = out.decode('utf-8') err = err.decode('utf-8') - if not proc.returncode == 0 or err: - log.error('emerge pretend returned {}'.format(proc.returncode)) + if proc.returncode != 0 or err: + log.error('emerge returned {}'.format(proc.returncode)) for line in out.splitlines(): log.error('stdout: {}'.format(line)) for line in err.splitlines(): @@ -268,5 +262,27 @@ def pkg_upgrade(): else: log.info('upgrade complete') for line in out.splitlines(): - log.warning('stdout: {}'.format(line)) + if line.startswith(' * '): + log.warning(line) + cmd = [ EMERGE_PATH, '--color', 'n', '-q', '@preserved-rebuild' ] + log.debug('Executing "{}"'.format(' '.join(cmd))) + proc = subprocess.Popen( + cmd, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE) + out, err = proc.communicate() + out = out.decode('utf-8') + err = err.decode('utf-8') + + if proc.returncode != 0 or err: + log.error('preserved-rebuild returned {}'.format(proc.returncode)) + for line in out.splitlines(): + log.error('stdout: {}'.format(line)) + for line in err.splitlines(): + log.error('stderr: {}'.format(line)) + else: + log.info('preserved-rebuild complete') + for line in out.splitlines(): + if line.startswith(' * '): + log.warning(line) diff --git a/sau/services.py b/sau/services.py index 8ec54e1..96d6ad9 100644 --- a/sau/services.py +++ b/sau/services.py @@ -11,11 +11,28 @@ import sau import sau.errors import sau.platforms +proc_fd_map_re = re.compile(r'^.*(/[^\(]*) \(deleted\)$') def _get_deleted_open_files(proc): + log = logging.getLogger(sau.LOGNAME) files = set() + + # try the linux-way first + maps_file = '/proc/{}/maps'.format(proc.pid) + if os.path.isfile(maps_file): + with open(maps_file, 'r') as f: + for line in f: + match = re.match(proc_fd_map_re, line) + if match: + files.add(match.group(1)) + return files + + # on FreeBSD psutils open_files() helpfully returns a null path if a file + # has been deleted. try: for f in proc.open_files(): + if 'lvmetad' in f.path: + log.debug(f) if f.path and os.path.exists(f.path): continue else: @@ -108,9 +125,11 @@ def restart_services(): log.warning('Could not find service for process {}'.format(proc)) continue - services.add(service_name) + if service_name: + services.add(service_name) for service in services: + log.info('Restarting service {}'.format(service)) platform.restart_service(service) recommend_restart = False