RPM Community Forums

Mailing List Message of <rpm-devel>

Repairing an rpmdb when db_dump/db_load doesn't

From: Jeff Johnson <n3npq@mac.com>
Date: Thu 20 Mar 2008 - 19:29:08 CET
Message-Id: <F75C4E1A-6BEF-466B-8BD1-B96B92DF7860@mac.com>
I just fixed an rpmdb that db_dump into db_load would not repair.

Here are some random notes on what I did so I can find later:

The rpm failure symptom was:

     # rpm -qa -vv
     ...
     D: rpmdb: read h#     897 Header SHA1 digest: OK  
(225a98efd2abd23e19a9baca1c67c9e75833b787)
     DirectFB-0.9.25-29.i586
     Segmentation fault

The root cause problem was:

     # /usr/lib/rpm/db_verify /var/lib/rpm/Packages
     db_verify: Page 5669: item 50 is out of order or nonsensical
     db_verify: Packages: DB_VERIFY_BAD: Database verification failed

The usual
     cd /var/lib/rpm
     mv Packages Packages-ORIG
     db_dump Packages-ORIG | db_load Packages
failed to repair the damage.

Deeper analysis showed that there was not only structural, but also  
data,
damage of header instances.

This modest hack applied a sanity check on header instances, and skipped
damaged header instances:

Index: rpmdb.c
===================================================================
RCS file: /v/rpm/cvs/rpm/rpmdb/rpmdb.c,v
retrieving revision 1.244
diff -u -b -B -w -p -r1.244 rpmdb.c
--- rpmdb.c     12 Mar 2008 19:41:13 -0000      1.244
+++ rpmdb.c     20 Mar 2008 18:20:08 -0000
@@ -2402,6 +2402,10 @@ if (dbiByteSwapped(dbi) == 1)
             if (rc || (mi->mi_setx && mi->mi_offset == 0))
                 return NULL;
  /*@=compmempass@*/
+if (mi->mi_offset & 0xffff0000) {
+fprintf(stderr, "*** damaged key 0x%x reset to 0\n", mi->mi_offset);
+mi->mi_offset = 0;
+}
         }
         mi->mi_setx++;
      } while (mi->mi_offset == 0);

With the hack applied, here's the damage that was exhibited:
[root@wellfleet rpm]# rpm -qa > /dev/null
*** damaged key 0x80000399 reset to 0
*** damaged key 0x808003f9 reset to 0
error: rpmdb: skipping h#    1164 Header SHA1 digest: BAD Expected 
(3411a61f872094fd2ceb650f7317abb1a49022dc) !=  
(237083ef497fcabaf510e7db4457d4d165a7967c)
error: rpmdb: skipping h#    1220 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1287 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1215 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1223 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1274 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1077 Header V3 DSA signature: BAD, key  
ID 6b9d6523
error: rpmdb: skipping h#    1217 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1245 Header V3 DSA signature: BAD, key  
ID 9a795806
*** damaged key 0x58000002 reset to 0
*** damaged key 0x30000019 reset to 0
error: rpmdb: skipping h#    1144 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1216 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1240 Header V3 DSA signature: BAD, key  
ID 9a795806
error: rpmdb: skipping h#    1147 Header SHA1 digest: BAD Expected 
(d7d4356d956f9d8d279b4ccb2b7236ff90bf6c4e) !=  
(5b050cf3fe1023ecf9a41fdda31c99a1cd75b530)
error: rpmdb: skipping h#    1219 Header V3 DSA signature: BAD, key  
ID 9c800aca
error: rpmdb: skipping h#    1328 Header V3 DSA signature: BAD, key  
ID 9c800aca


An rpm --rebuilddb then saved what headers were not damaged, skipping  
over the damage.

The damage was random and pathological and hardly worth avoiding  
imho. Certainly
rpm (and rpmlib) did not do this damage.

However the hack could be done more carefully by retrieving the  
largest known
header instance and using that as range check on header instances.  
Otherwise,
its just a hack: there's lots of types of damage that would pass  
through the
hack y sanity check without detection. Note that the more careful  
check I mentioned
assumes that the range check is on a quiescent rpmdb, very much not  
true for concurrent
rpmdb access in general.

Back to hacking ...

73 de Jeff
Received on Thu Mar 20 19:29:51 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.