[Yum-devel] [PATCH] Fix /var/lib/rpm/Packages mtime race. BZ 973375

Zdenek Pavlas zpavlas at redhat.com
Wed Jun 19 10:15:29 UTC 2013


> So, again, I'm heavily inclined to just say "stop
> doing that" unless we really need to come up with some workaround.

Came up with this..  We can prefix rpmdb version with h_nelem
loaded from the Berkeley DB header.  This way, most additions
and removals should be detected.  But yes, it's ugly.

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 56c3793..96f4fc1 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -31,6 +31,7 @@ from packageSack import PackageSackBase, PackageSackVersion
 # For returnPackages(patterns=)
 import fnmatch
 import re
+import struct
 
 from yum.i18n import to_unicode, _
 import constants
@@ -1157,7 +1158,10 @@ class RPMDBPackageSack(PackageSackBase):
                 if fo is None:
                     return None
                 rpmdbv = fo.readline()[:-1]
-                self._have_cached_rpmdbv_data  = rpmdbv
+                rpmdbv_nrec, rpmdbv = rpmdbv.split(':', 1)
+                nrec = struct.unpack('<88xI', open(rpmdbfname).read(92))[0]
+                if nrec == int(rpmdbv_nrec):
+                    self._have_cached_rpmdbv_data  = rpmdbv
         return self._have_cached_rpmdbv_data
 
     def _put_cached_simpleVersion_main(self, rpmdbv):
@@ -1173,6 +1177,7 @@ class RPMDBPackageSack(PackageSackBase):
         if not os.path.exists(rpmdbfname):
             return # haha
 
+        nrec = struct.unpack('<88xI', open(rpmdbfname).read(92))[0]
         _cached_rpmdb_mtime = os.path.getmtime(rpmdbfname)
         if self._cached_rpmdb_mtime != _cached_rpmdb_mtime:
             #  Something altered the rpmdb since we loaded our first package,
@@ -1190,8 +1195,7 @@ class RPMDBPackageSack(PackageSackBase):
                 return
 
         fo = _open_no_umask(rpmdbvfname + ".tmp", "w")
-        fo.write(self._have_cached_rpmdbv_data)
-        fo.write('\n')
+        fo.write('%d:%s\n' % (nrec, self._have_cached_rpmdbv_data))
         fo.close()
         os.rename(rpmdbvfname + ".tmp", rpmdbvfname)
 


More information about the Yum-devel mailing list