[yum-commits] 2 commits - Makefile needs-restarting.py yum-utils.spec

skvidal at osuosl.org skvidal at osuosl.org
Wed Nov 4 17:46:31 UTC 2009


 Makefile            |    2 
 needs-restarting.py |  136 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 yum-utils.spec      |    4 +
 3 files changed, 141 insertions(+), 1 deletion(-)

New commits:
commit 80fc97868306d92d1164de0417b2aec191ab0e96
Merge: 43e630f... 4b19eeb...
Author: Seth Vidal <skvidal at fedoraproject.org>
Date:   Wed Nov 4 12:45:20 2009 -0500

    Merge branch 'master' of ssh://yum.baseurl.org/srv/projects/yum/git/yum-utils
    
    * 'master' of ssh://yum.baseurl.org/srv/projects/yum/git/yum-utils:
      Compare the currently running kernel for security problems
      Add aliases for list-updateinfo instead of list-security

commit 43e630fb134e78fc44651c203e3fad364acf1b64
Author: Seth Vidal <skvidal at fedoraproject.org>
Date:   Wed Nov 4 12:44:20 2009 -0500

    add needs-restarting as a yum-util

diff --git a/Makefile b/Makefile
index 248a9a3..bce2c9f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 SUBDIRS = docs
 PKGNAME = yum-utils
-UTILS = package-cleanup debuginfo-install repoclosure repomanage repoquery repo-graph repo-rss yumdownloader yum-builddep repotrack reposync repodiff yum-debug-dump yum-debug-restore verifytree yum-groups-manager find-repos-of-install
+UTILS = package-cleanup debuginfo-install repoclosure repomanage repoquery repo-graph repo-rss yumdownloader yum-builddep repotrack reposync repodiff yum-debug-dump yum-debug-restore verifytree yum-groups-manager find-repos-of-install needs-restarting
 UTILSROOT = yum-complete-transaction yumdb
 VERSION=$(shell awk '/Version:/ { print $$2 }' ${PKGNAME}.spec)
 RELEASE=$(shell awk -F%: '/Release:/ { print $$2 }' ${PKGNAME}.spec ')
diff --git a/needs-restarting.py b/needs-restarting.py
new file mode 100755
index 0000000..a6feafe
--- /dev/null
+++ b/needs-restarting.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python -tt
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2009 Red Hat Inc
+# written by Seth Vidal
+
+# look through list of running apps
+# report any app which was updated after it was started
+# (and therefore needs to be restarted)
+
+
+# for each /proc/number-dir 
+# get stat of create time on that dir
+# open up smaps and search for all lines with 'fd:' in them
+# take filename
+# search for the package owning that file
+# make a list of installtimes of all pkgs of the files the program has open
+# sort the list
+# if the dir create time is < the largest time on the installtimes list
+# then output the pid and process cmdline as needing to be restarted
+
+#TODO:
+# maybe note deleted files which are not owned by any pkg but which an app
+# is still using
+# output userids, too?
+
+
+import sys
+import os
+import yum
+import glob
+import stat
+from optparse import OptionParser
+
+def parseargs(args):
+    usage = """
+    needs-restarting: Report a list of process ids of programs that started 
+                    running before they or some component they use were updated.
+    """
+    parser = OptionParser(usage=usage)
+    
+    parser.add_option("-u", "--useronly", default=False, action="store_true",
+      help='show processes for my userid only')
+    
+    (opts, args) = parser.parse_args(args)
+    return (opts, args)
+
+
+def return_running_pids(uid=None):
+    mypid = os.getpid()
+    pids = []
+    for fn in glob.glob('/proc/[0123456789]*'):
+        if mypid == os.path.basename(fn):
+            continue
+
+        if uid: # meaning we're not root and we've added -u
+            if os.stat(fn)[stat.ST_UID] != uid:
+                continue
+
+        pids.append(os.path.basename(fn))
+    return pids
+
+def get_open_files(pid):
+    files = []
+    smaps = '/proc/%s/smaps' % pid
+    try:
+        maps = open(smaps, 'r')
+    except (IOError, OSError), e:
+        print "Could not open %s" % smaps
+        return files
+
+    for line in maps.readlines():
+        if line.find('fd:') == -1:
+            continue
+        line = line.replace('\n', '')
+        slash = line.find('/')
+        filename = line[slash:]
+        filename = filename.replace('(deleted)', '') #only mildly retarded
+        filename = filename.strip()
+        if filename not in files:
+            files.append(filename)
+    return files
+
+def main(args):
+    (opts, args)  = parseargs(args)
+    
+    my = yum.YumBase()
+    if hasattr(my, 'setCacheDir'):
+        my.setCacheDir()
+    my.conf.cache = True
+    
+    myuid = None
+    if opts.useronly:
+        myuid = os.getuid()
+    
+    needing_restart = []
+
+    for pid in return_running_pids(uid=myuid):
+        try:
+            pid_start = os.stat('/proc/' + pid)[stat.ST_CTIME]
+        except OSError, e:
+            continue
+        found_match = False
+        for fn in get_open_files(pid):
+            if found_match:
+                break
+            
+            for pkg in my.rpmdb.searchFiles(fn):
+                if float(pkg.installtime) > float(pid_start):
+                    needing_restart.append(pid)
+                    found_match = True
+
+    for pid in needing_restart:
+        try:
+            cmdline = open('/proc/' +pid+ '/cmdline', 'r').read()
+        except OSError, e:
+            print "Couldn't access process information for %s: %s" % (pid, str(e))
+            continue
+        print '%s : %s' % (pid, cmdline)
+        
+    return 0
+    
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/yum-utils.spec b/yum-utils.spec
index 4cc4161..c5cd267 100644
--- a/yum-utils.spec
+++ b/yum-utils.spec
@@ -422,6 +422,7 @@ fi
 %{_sysconfdir}/bash_completion.d
 %{_bindir}/debuginfo-install
 %{_bindir}/find-repos-of-install
+%{_bindir}/needs-restarting
 %{_bindir}/package-cleanup
 %{_bindir}/repoclosure
 %{_bindir}/repodiff
@@ -599,6 +600,9 @@ fi
 
 
 %changelog
+* Wed Nov  4 2009 Seth Vidal <skvidal at fedoraproject.org>
+- add needs-restarting
+
 * Mon Oct 12 2009 Seth Vidal <skvidal at fedoraproject.org>
 - add python compileall to all plugins so we get .pyc/.pyo files in them
 - fixes https://bugzilla.redhat.com/show_bug.cgi?id=493174


More information about the Yum-commits mailing list