RPM Community Forums

Mailing List Message of <rpm-devel>

Re: [CVS] RPM: rpm/rpmdb/ rpmdb.c

From: Jeff Johnson <n3npq@mac.com>
Date: Sun 24 Aug 2008 - 22:58:03 CEST
Message-id: <13B7AF4B-F016-45AF-9BAC-03432A5F083D@mac.com>
There's one subtlety with a rpmdb iterator that I should mention.

In order to support identical paths with differing content
in multiple packages, there's a file state associated, and already
installed headers are rewritten with a change in state.

The only place that is done is in lib/psm.c:

/**
  * Mark files in database shared with this package as "replaced".
  * @param psm           package state machine data
  * @return              0 always
  */
static rpmRC markReplacedFiles(const rpmpsm psm)
{
...
     mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
     xx = rpmdbAppendIterator(mi, offsets, num);
     xx = rpmdbSetIteratorRewrite(mi, 1);
     sfi = replaced;
     while ((h = rpmdbNextIterator(mi)) != NULL) {
         int modified;

         modified = 0;

         /* XXX FIXME: not correct yet, but headerGetEntry needs to  
die now! */
         he->tag = RPMTAG_FILESTATES;
         xx = headerGet(h, he, 0);
         if (!xx)
             continue;

         prev = rpmdbGetIteratorOffset(mi);
         num = 0;
         while (sfi->otherPkg && sfi->otherPkg == prev) {
assert(sfi->otherFileNum < he->c);
             if (he->p.ui8p[sfi->otherFileNum] !=  
RPMFILE_STATE_REPLACED) {
                 he->p.ui8p[sfi->otherFileNum] = RPMFILE_STATE_REPLACED;
                 if (modified == 0) {
                     /* Modified header will be rewritten. */
                     modified = 1;
                     xx = rpmdbSetIteratorModified(mi, modified);
                 }
                 num++;
             }
             sfi++;
         }
         he->p.ptr = _free(he->p.ptr);
     }
     mi = rpmdbFreeIterator(mi);

The code has been broken for several years (at least).

Since noone has noticed, and noone cares, that's almost
enough time to safely attempt the feature reversion.

Otherwise, this pathway through rpmdb iterators may need
to be revived from the dead.

Not hard either way.

73 de Jeff

On Aug 24, 2008, at 4:12 PM, Alexey Tourbin wrote:

>   RPM Package Manager, CVS Repository
>   http://rpm5.org/cvs/
>    
> ______________________________________________________________________ 
> ______
>
>   Server: rpm5.org                         Name:   Alexey Tourbin
>   Root:   /v/rpm/cvs                       Email:  at@rpm5.org
>   Module: rpm                              Date:   24-Aug-2008  
> 22:12:42
>   Branch: HEAD                             Handle: 2008082420124200
>
>   Modified files:
>     rpm/rpmdb               rpmdb.c
>
>   Log:
>     rpmdb.c (miFreeHeader): eliminate mi_key and mi_data, cleanup
>     headerUnload stuff
>
>   Summary:
>     Revision    Changes     Path
>     1.266       +14 -20     rpm/rpmdb/rpmdb.c
>    
> ______________________________________________________________________ 
> ______
>
>   patch -p0 <<'@@ .'
>   Index: rpm/rpmdb/rpmdb.c
>    
> ====================================================================== 
> ======
>   $ cvs diff -u -r1.265 -r1.266 rpmdb.c
>   --- rpm/rpmdb/rpmdb.c	24 Aug 2008 18:36:08 -0000	1.265
>   +++ rpm/rpmdb/rpmdb.c	24 Aug 2008 20:12:42 -0000	1.266
>   @@ -1877,23 +1877,16 @@
>    	return 0;
>
>        if (dbi && mi->mi_dbc && mi->mi_modified && mi- 
> >mi_prevoffset) {
>   -	DBT * key = &mi->mi_key;
>   -	DBT * data = &mi->mi_data;
>   -	sigset_t signalMask;
>   +	DBT k = DBT_INIT;
>   +	DBT v = DBT_INIT;
>    	rpmRC rpmrc = RPMRC_NOTFOUND;
>   -	size_t nb = 0;
>    	int xx;
>
>   -	(void) headerGetMagic(mi->mi_h, NULL, &nb);
>   -/*@i@*/	key->data = (void *) &mi->mi_prevoffset;
>   -	key->size = (UINT32_T) sizeof(mi->mi_prevoffset);
>   -	{   size_t len;
>   -	    len = 0;
>   -	    data->data = headerUnload(mi->mi_h, &len);
>   -	    data->size = (UINT32_T) len;	/* XXX data->size is  
> rpmuint32_t */
>   -#ifdef	DYING	/* XXX this is needed iff headerSizeof() is used  
> instead. */
>   -	    data->size -= nb;	/* XXX HEADER_MAGIC_NO */
>   -#endif
>   +/*@i@*/	k.data = (void *) &mi->mi_prevoffset;
>   +	k.size = (UINT32_T) sizeof(mi->mi_prevoffset);
>   +	{   size_t len = 0;
>   +	    v.data = headerUnload(mi->mi_h, &len);
>   +	    v.size = (UINT32_T) len;
>    	}
>
>    	/* Check header digest/signature on blob export (if requested). */
>   @@ -1901,8 +1894,8 @@
>    	    const char * msg = NULL;
>    	    int lvl;
>
>   -assert(data->data != NULL);
>   -	    rpmrc = headerCheck(rpmtsDig(mi->mi_ts), data->data, data- 
> >size, &msg);
>   +assert(v.data != NULL);
>   +	    rpmrc = headerCheck(rpmtsDig(mi->mi_ts), v.data, v.size,  
> &msg);
>    	    rpmtsCleanDig(mi->mi_ts);
>    	    lvl = (rpmrc == RPMRC_FAIL ? RPMLOG_ERR : RPMLOG_DEBUG);
>    	    rpmlog(lvl, "%s h#%8u %s",
>   @@ -1911,9 +1904,10 @@
>    	    msg = _free(msg);
>    	}
>
>   -	if (data->data != NULL && rpmrc != RPMRC_FAIL) {
>   +	if (v.data != NULL && rpmrc != RPMRC_FAIL) {
>   +	    sigset_t signalMask;
>    	    (void) blockSignals(dbi->dbi_rpmdb, &signalMask);
>   -	    rc = dbiPut(dbi, mi->mi_dbc, key, data, DB_KEYLAST);
>   +	    rc = dbiPut(dbi, mi->mi_dbc, &k, &v, DB_KEYLAST);
>    	    if (rc) {
>    		rpmlog(RPMLOG_ERR,
>    			_("error(%d) storing record #%d into %s\n"),
>   @@ -1922,8 +1916,8 @@
>    	    xx = dbiSync(dbi, 0);
>    	    (void) unblockSignals(dbi->dbi_rpmdb, &signalMask);
>    	}
>   -	data->data = _free(data->data);
>   -	data->size = 0;
>   +	v.data = _free(v.data); /* headerUnload */
>   +	v.size = 0;
>        }
>
>        mi->mi_h = headerFree(mi->mi_h);
>   @@ .
> ______________________________________________________________________
> RPM Package Manager                                    http://rpm5.org
> CVS Sources Repository                                rpm-cvs@rpm5.org
Received on Sun Aug 24 22:59:00 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.