Skip to content

Commit e04f301

Browse files
committed
Rework repo_rpmdb.c a bit
- Clean up package dabase handing - Add rpm_stat_database() function that allows to stat the package database - Add rpm_hash_database_state() function that hashes the package database state - Use rpm's new rpmdbFStat() function if available - Use rpmdbNextIteratorHeaderBlob() function (SUSE extension) if available
1 parent 8a8868a commit e04f301

6 files changed

Lines changed: 211 additions & 53 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ IF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM)
238238
ENDIF (NOT ENABLE_RPMDB_LIBRPM)
239239
INCLUDE (CheckLibraryExists)
240240
CHECK_LIBRARY_EXISTS(rpmio pgpDigGetParams "" HAVE_PGPDIGGETPARAMS)
241+
CHECK_LIBRARY_EXISTS(rpm rpmdbNextIteratorHeaderBlob "" HAVE_RPMDBNEXTITERATORHEADERBLOB)
242+
CHECK_LIBRARY_EXISTS(rpm rpmdbFStat "" HAVE_RPMDBFSTAT)
241243
ENDIF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM)
242244

243245
IF (ENABLE_PUBKEY)
@@ -270,7 +272,8 @@ ENDIF (${CMAKE_MAJOR_VERSION} GREATER 2)
270272

271273
# should create config.h with #cmakedefine instead...
272274
FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN
273-
HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS WITH_LIBXML2 WITHOUT_COOKIEOPEN)
275+
HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS HAVE_RPMDBNEXTITERATORHEADERBLOB HAVE_RPMDBFSTAT
276+
WITH_LIBXML2 WITHOUT_COOKIEOPEN)
274277
IF(${VAR})
275278
ADD_DEFINITIONS (-D${VAR}=1)
276279
SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})

ext/libsolvext.ver

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ SOLV_1.0 {
4747
rpm_byfp;
4848
rpm_byrpmdbid;
4949
rpm_byrpmh;
50+
rpm_hash_database_state;
5051
rpm_installedrpmdbids;
5152
rpm_iterate_filelist;
5253
rpm_query;
5354
rpm_query_num;
55+
rpm_stat_database;
5456
rpm_state_create;
5557
rpm_state_free;
5658
solv_verify_sig;

ext/repo_rpmdb.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,8 +1329,6 @@ freestate(struct rpmdbstate *state)
13291329
{
13301330
/* close down */
13311331
#ifdef ENABLE_RPMDB
1332-
if (state->pkgdbopened)
1333-
closepkgdb(state);
13341332
if (state->dbenvopened)
13351333
closedbenv(state);
13361334
#endif
@@ -1624,11 +1622,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
16241622
repo_empty(ref, 1); /* get it out of the way */
16251623
if ((flags & RPMDB_REPORT_PROGRESS) != 0)
16261624
count = count_headers(&state);
1627-
if (!openpkgdb(&state))
1628-
{
1629-
freestate(&state);
1630-
return -1;
1631-
}
16321625
if (pkgdb_cursor_open(&state))
16331626
{
16341627
freestate(&state);
@@ -2394,6 +2387,28 @@ rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queu
23942387
return nentries;
23952388
}
23962389

2390+
int
2391+
rpm_hash_database_state(void *rpmstate, Chksum *chk)
2392+
{
2393+
struct rpmdbstate *state = rpmstate;
2394+
struct stat stb;
2395+
if (stat_database(state, &stb))
2396+
return -1;
2397+
if (state->dbenvopened != 1 && !opendbenv(state))
2398+
return -1;
2399+
solv_chksum_add(chk, &stb.st_mtime, sizeof(stb.st_mtime));
2400+
solv_chksum_add(chk, &stb.st_size, sizeof(stb.st_size));
2401+
solv_chksum_add(chk, &stb.st_ino, sizeof(stb.st_ino));
2402+
hash_name_index(rpmstate, chk);
2403+
return 0;
2404+
}
2405+
2406+
int
2407+
rpm_stat_database(void *rpmstate, void *stb)
2408+
{
2409+
return stat_database((struct rpmdbstate *)rpmstate, (struct stat *)stb) ? -1 : 0;
2410+
}
2411+
23972412
void *
23982413
rpm_byrpmdbid(void *rpmstate, Id rpmdbid)
23992414
{

ext/repo_rpmdb.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "queue.h"
99
#include "repo.h"
10+
#include "chksum.h"
1011

1112
struct headerToken_s;
1213

@@ -39,7 +40,11 @@ extern void *rpm_state_create(Pool *pool, const char *rootdir);
3940
extern void *rpm_state_free(void *rpmstate);
4041

4142
/* return all matching rpmdbids */
42-
extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq);
43+
extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq);
44+
/* stat the package database */
45+
extern int rpm_stat_database(void *rpmstate, void *stb);
46+
/* hash the state of the package database */
47+
extern int rpm_hash_database_state(void *rpmstate, Chksum *chk);
4348

4449
/* return handles to a rpm header */
4550
extern void *rpm_byrpmdbid(void *rpmstate, Id rpmdbid);

ext/repo_rpmdb_bdb.h

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,31 @@ struct rpmdbstate {
5656
};
5757

5858

59+
static inline int
60+
access_rootdir(struct rpmdbstate *state, const char *dir, int mode)
61+
{
62+
if (state->rootdir)
63+
{
64+
char *path = solv_dupjoin(state->rootdir, dir, 0);
65+
int r = access(path, mode);
66+
free(path);
67+
return r;
68+
}
69+
return access(dir, mode);
70+
}
71+
72+
static void
73+
detect_ostree(struct rpmdbstate *state)
74+
{
75+
state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 &&
76+
access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 ? 1 : -1;
77+
}
78+
5979
static int
6080
stat_database_name(struct rpmdbstate *state, char *dbname, struct stat *statbuf, int seterror)
6181
{
6282
char *dbpath;
63-
dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname);
83+
dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname);
6484
if (stat(dbpath, statbuf))
6585
{
6686
if (seterror)
@@ -75,6 +95,8 @@ stat_database_name(struct rpmdbstate *state, char *dbname, struct stat *statbuf,
7595
static int
7696
stat_database(struct rpmdbstate *state, struct stat *statbuf)
7797
{
98+
if (!state->is_ostree)
99+
detect_ostree(state);
78100
return stat_database_name(state, "Packages", statbuf, 1);
79101
}
80102

@@ -160,14 +182,15 @@ opendbenv(struct rpmdbstate *state)
160182
dbenv->set_thread_count(dbenv, 8);
161183
#endif
162184
dbpath = solv_dupjoin(rootdir, "/var/lib/rpm", 0);
185+
state->is_ostree = -1;
163186
if (access(dbpath, W_OK) == -1)
164187
{
165188
free(dbpath);
166189
dbpath = solv_dupjoin(rootdir, "/usr/share/rpm/Packages", 0);
167190
if (access(dbpath, R_OK) == 0)
168191
state->is_ostree = 1;
169192
free(dbpath);
170-
dbpath = solv_dupjoin(rootdir, state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm", 0);
193+
dbpath = solv_dupjoin(rootdir, state->is_ostree > 0 ? "/usr/share/rpm" : "/var/lib/rpm", 0);
171194
r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0);
172195
}
173196
else
@@ -209,6 +232,12 @@ closedbenv(struct rpmdbstate *state)
209232
uint32_t eflags = 0;
210233
#endif
211234

235+
if (state->db)
236+
{
237+
state->db->close(state->db, 0);
238+
state->db = 0;
239+
}
240+
state->pkgdbopened = 0;
212241
if (!state->dbenv)
213242
return;
214243
#if defined(FEDORA) || defined(MAGEIA)
@@ -264,16 +293,6 @@ openpkgdb(struct rpmdbstate *state)
264293
return 1;
265294
}
266295

267-
static void
268-
closepkgdb(struct rpmdbstate *state)
269-
{
270-
if (!state->db)
271-
return;
272-
state->db->close(state->db, 0);
273-
state->db = 0;
274-
state->pkgdbopened = 0;
275-
}
276-
277296
/* get the rpmdbids of all installed packages from the Name index database.
278297
* This is much faster then querying the big Packages database */
279298
static struct rpmdbentry *
@@ -464,6 +483,8 @@ count_headers(struct rpmdbstate *state)
464483
static int
465484
pkgdb_cursor_open(struct rpmdbstate *state)
466485
{
486+
if (state->pkgdbopened != 1 && !openpkgdb(state))
487+
return -1;
467488
if (state->db->cursor(state->db, NULL, &state->dbc, 0))
468489
return pool_error(state->pool, -1, "db->cursor failed");
469490
return 0;
@@ -497,3 +518,20 @@ pkgdb_cursor_getrpm(struct rpmdbstate *state)
497518
return 0; /* no more entries */
498519
}
499520

521+
static int
522+
hash_name_index(struct rpmdbstate *state, Chksum *chk)
523+
{
524+
char *dbpath;
525+
int fd, l;
526+
char buf[4096];
527+
528+
dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", "Name");
529+
if ((fd = open(dbpath, O_RDONLY)) < 0)
530+
return -1;
531+
while ((l = read(fd, buf, sizeof(buf))) > 0)
532+
solv_chksum_add(chk, buf, l);
533+
close(fd);
534+
return 0;
535+
}
536+
537+

0 commit comments

Comments
 (0)