2012/2/23 Javier Fernández-Sanguino Peña <j...@computer.org>:
> On Wed, Feb 22, 2012 at 06:33:19PM +1100, Marcus Furlong wrote:
>> If rpm support would be acceptable, I'd be happy to re-work the above
>> patch so that it checks for the existence of "dpkg-query" and/or "rpm"
>> and proceeds accordingly.
>
> I'm open to supporting rpm in checkrestart but to do so it would be best to
> separate the dpkg and rpm calls into different functions and call one (or the
> other) based not on the existance of the dpkg-query or rpm binaries
> themselves (you can install the rpm software in Debian) but on wether you are
> running in an rpm or deb-based distribution.

We have debian installations that have rpm installed (due to hardware
RAID software that IBM distributes only as rpms). The attached patch
checks for the existence of both dpkg-query and rpm. If it finds
either it runs the corresponding checks. On our systems, this is the
correct thing to do, as it finds both deb-based packages and rpm-based
packages that require restarts. If either rpm or dpkg-query is not
found, those codepaths are not executed.

Tested on lenny, squeeze, opensuse, centos/sl/redhat 5/6.

Regards,
Marcus.
-- 
Marcus Furlong
--- checkrestart.orig	2012-02-29 13:37:30.788710631 +1100
+++ checkrestart	2012-03-05 17:28:40.875381912 +1100
@@ -114,6 +114,11 @@
 # TODO - This does not work yet:
 #        toRestart = psdelcheck()
 
+    global dpkgQueryBin, rpmBin
+
+    dpkgQueryBin = find_cmd('dpkg-query')
+    rpmBin = find_cmd('rpm')
+
     toRestart = lsofcheck()
 
     print "Found %d processes using old versions of upgraded files" % len(toRestart)
@@ -138,33 +143,13 @@
             process.listDeleted()
 
     packages = {}
-    diverted = None
-    dpkgQuery = ["dpkg-query", "--search"] + programs.keys()
-    dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=None,
-                                env = lc_all_c_env)
-    for line in dpkgProc.stdout.readlines():
-        if line.startswith('local diversion'):
-            continue
+    
+    if dpkgQueryBin != 1:
+        deb_packages(programs, packages)
         
-        m = re.match('^diversion by (\S+) (from|to): (.*)$', line)
-        if m:
-            if m.group(2) == 'from':
-                diverted = m.group(3)
-                continue
-            if not diverted:
-                raise Exception('Weird error while handling diversion')
-            packagename, program = m.group(1), diverted
-        else:
-            packagename, program = line[:-1].split(': ')
-            if program == diverted:
-                # dpkg prints a summary line after the diversion, name both
-                # packages of the diversion, so ignore this line
-                # mutt-patched, mutt: /usr/bin/mutt
-                continue
-
-        packages.setdefault(packagename,Package(packagename))
-        packages[packagename].processes.extend(programs[program])
-
+    if rpmBin != 1:
+        rpm_packages(programs, packages)
+    
     print "(%d distinct packages)" % len(packages)
 
     if len(packages) == 0:
@@ -172,18 +157,31 @@
         print "(please read checkrestart(1))"
         sys.exit(0)
 
+
     for package in packages.values():
+        output = ''
         if package == 'util-linux':
             continue
-        dpkgQuery = ["dpkg-query", "--listfiles", package.name]
-        dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=None,
+
+        if dpkgQueryBin != 1:
+            dpkgQuery = [dpkgQueryBin, "--listfiles", package.name]
+            dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                                env = lc_all_c_env)
+            for line in dpkgProc.stdout.readlines():
+                output = output + "%s\n" % line
+
+        if rpmBin != 1:
+            rpmQuery = [rpmBin, "-q", "-l", package.name]
+            rpmProc = subprocess.Popen(rpmQuery, stdout=subprocess.PIPE, stderr=None,
                                 env = lc_all_c_env)
-        for line in dpkgProc.stdout.readlines():
-            path = line[:-1]
-            if path.startswith('/etc/init.d/'):
-                if path.endswith('.sh'):
+            for line in rpmProc.stdout.readlines():
+                output = output + "%s \n" % line
+
+        for line in output.splitlines():
+            if line.startswith('/etc/init.d/') or line.startswith('/etc/rc.d/init.d/'):
+                if line.endswith('.sh'):
                     continue
-                package.initscripts.add(path)
+                package.initscripts.add(line)
         # Alternatively, find init.d scripts that match the process name
         if len(package.initscripts) == 0:
             for process in package.processes:
@@ -265,6 +263,7 @@
 def isdeletedFile (f):
 
     global lc_all_c_env
+    global dpkgQueryBin, rpmBin
 
     if allFiles:
         return 1
@@ -284,7 +283,7 @@
     if f.startswith('/run/'):
         return 0
     # Or about files under /drm
-    if f.startswith('/drm/'):
+    if f.startswith('/drm'):
         return 0
     # Or about files under /var/tmp
     if f.startswith('/var/tmp/'):
@@ -318,15 +317,28 @@
         # a proper filename
         file_name = re.sub(r'\(.*\)','', f)
         file_name = re.sub(r'\s+$','', file_name)
-        dpkgQuery = ["dpkg-query", "--search", file_name]
-        dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=None,
-                                env = lc_all_c_env)
-        for line in dpkgProc.stdout.readlines():
-            if line.endswith(f):
-                 file_in_package = True
-                 break
+        if dpkgQueryBin != 1:
+            dpkgQuery = [dpkgQueryBin, "--search", file_name]
+            dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=None,
+                                    env = lc_all_c_env)
+            for line in dpkgProc.stdout.readlines():
+                if line.endswith(file_name):
+                    file_in_package = True
+                    break
+        if rpmBin != 1:
+            output = ''
+            rpmQuery = [rpmBin, "-q", "-f", "--queryformat=%{NAME}", file_name]
+            rpmProc = subprocess.Popen(rpmQuery, stdout=subprocess.PIPE, stderr=None,
+                                    env = lc_all_c_env)
+            for line in rpmProc.stdout.readlines():
+                output = output + "%s: %s\n" % (line, file_name)
+            
+            for line in output.splitlines():
+                if line.endswith(file_name):
+                    file_in_package = True
+                    break
         if not file_in_package:
-                 return 0
+            return 0
 
     # TODO: it should only care about library files (i.e. /lib, /usr/lib and the like)
     # build that check with a regexp to exclude others
@@ -386,6 +398,53 @@
     return process
 
 
+def deb_packages(programs, packages):
+    global dpkgQueryBin
+    diverted = None
+    dpkgQuery = [dpkgQueryBin, "--search"] + programs.keys()
+    dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                                env = lc_all_c_env)
+    for line in dpkgProc.stdout.readlines():
+        if line.startswith('local diversion'):
+            continue
+        
+        m = re.match('^diversion by (\S+) (from|to): (.*)$', line)
+        if m:
+            if m.group(2) == 'from':
+                diverted = m.group(3)
+                continue
+            if not diverted:
+                raise Exception('Weird error while handling diversion')
+            packagename, program = m.group(1), diverted
+        else:
+            packagename, program = line[:-1].split(': ')
+            if program == diverted:
+                # dpkg prints a summary line after the diversion, name both
+                # packages of the diversion, so ignore this line
+                # mutt-patched, mutt: /usr/bin/mutt
+                continue
+
+        packages.setdefault(packagename,Package(packagename))
+        packages[packagename].processes.extend(programs[program])
+
+
+def rpm_packages(programs, packages):
+    global rpmBin
+    output = ''
+    for key in programs.keys():
+        rpmQuery = [rpmBin, "-q", "-f", "--queryformat=%{NAME}", key]
+        rpmProc = subprocess.Popen(rpmQuery, stdout=subprocess.PIPE, stderr=None,
+                                env = lc_all_c_env)
+        for line in rpmProc.stdout.readlines():
+            if not line.endswith('is not owned by any package\n'):
+                output = output + "%s: %s\n" % (line, key)
+
+    for line in output.splitlines():
+        packagename, program = line.split(': ')
+        packages.setdefault(packagename,Package(packagename))
+        packages[packagename].processes.extend(programs[program])
+
+
 class SysProcess:
 	re_name = re.compile('Name:\t(.*)$')
 	re_uids = re.compile('Uid:\t(\d+)\t(\d+)\t(\d+)\t(\d+)$')
@@ -447,7 +506,7 @@
                     newusr = os.path.join(os.path.dirname('/usr'), newusr)
                 f = re.sub('^/usr',newusr, f)
                 # print "Changing usr to " + newusr + " result:" +f; # Debugging
-        return re.sub('( \(deleted\)|.dpkg-new).*$','',f)
+        return re.sub('( \(deleted\)|.dpkg-new|\;|.#prelink#).*$','',f)
 
     def listDeleted(self):
         listfiles = []

Reply via email to