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