[Rpm-maint] Rpm Database musings

Panu Matilainen pmatilai at laiskiainen.org
Thu Apr 18 12:30:52 UTC 2013

On 04/18/2013 12:04 PM, Michael Schroeder wrote:
> On Wed, Apr 17, 2013 at 05:17:42PM +0300, Panu Matilainen wrote:
>> Time for a status report, just to let you know I haven't forgotten or
>> abandoned this "project".
> That's good to hear ;-)
>> All direct BDB ties in rpmdb.c were cut out last month, been pondering
>> about the backend API since then. Since that "work" was just going around
>> in circles I figured the more practical approach of trying to ram the
>> newrpmdb code into rpm might help get things going again.
>> After a bit of poking around in the last two days, I have bits and pieces
>> in semi-working state. However what soon became very clear is that while
>> BDB might be technically gone from rpmdb.c, its spirit remains there rather
>> strongly (not that this is particularly surprising)
> Yes, the newrpmdb code doesn't have a "cursor" in the BDB sense. I did
> that on purpose, because I wanted to make clear that operation results
> don't have a state, i.e. I don't have to define any semantics when there's
> a cursor still open and the database gets changed.
> It should be easy though to either hide the cursors in the BDB code or
> implement a dummy newrpmdb cursor.

Yup, I suspect it'll have to be a little bit of both: implementing the 
equivalent of rpmpkgList() for BDB would be slow as molasses so some 
kind of cursor/iterator interface is needed for RPMDBI_PACKAGES non-keyd 
iterator and perhaps for the keyiterators too. OTOH adding and removing 
headers + the associated index updates are probably best buried in the 
backend-specific code.

BTW there seems to be a bug in newrpmdb, related to the pkgidx/datidx 
handling for the cases where ovldata is non-zero. It's masked by a 
typo/thinko in the testit.c header data size calculation:

--- a/testit.c
+++ b/testit.c
@@ -100,7 +100,7 @@ rpmheadfromblob(RpmHead *h, unsigned char *blob, 
unsigned in
    h->cnt = blob[8] << 24 | blob[9] << 16 | blob[10] << 8 | blob[11];
-  h->dcnt = blob[9] << 24 | blob[10] << 16 | blob[11] << 8 | blob[12];
+  h->dcnt = blob[12] << 24 | blob[13] << 16 | blob[14] << 8 | blob[15];
    h->dp = blob + 16 + h->cnt * 16;

That causes the larger string arrays to be seen as invalid so the 
non-zero ovldata case never/rarely occurs. With the above fix it starts 
segfaulting at end of rpmidxPutInternal() on headers with large arrays. 
For example with this: 

[pmatilai at localhost newrpmdb]$ valgrind ./testit < 
==10149== Memcheck, a memory error detector
==10149== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==10149== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==10149== Command: ./testit
reading headers
found 1 headers
opening database
==10149== Invalid write of size 4
==10149==    at 0x4068A2: rpmidxPutInternal (rpmidx.c:80)
==10149==    by 0x407C9B: rpmidxPutStrings (rpmidx.c:1101)
==10149==    by 0x401B58: writeheader (testit.c:181)
==10149==    by 0x401440: main (testit.c:470)
==10149==  Address 0x5048250 is not stack'd, malloc'd or (recently) free'd
==10149== Process terminating with default action of signal 11 (SIGSEGV)
==10149==  Access not within mapped region at address 0x5048250
==10149==    at 0x4068A2: rpmidxPutInternal (rpmidx.c:80)
==10149==    by 0x407C9B: rpmidxPutStrings (rpmidx.c:1101)
==10149==    by 0x401B58: writeheader (testit.c:181)
==10149==    by 0x401440: main (testit.c:470)

	- Panu -

More information about the Rpm-maint mailing list