diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2020-11-27 14:44:40 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2020-11-27 14:44:40 +0900 |
commit | a997565567d8b30dc3a6f289e72324f8f2085b64 (patch) | |
tree | 9d2bddbd4f09ca9ce3cdd906c663e2d7f6412169 | |
parent | 0de6a1fb83326a7af7c401e706a808da0c042a0f (diff) | |
download | libsolv-a997565567d8b30dc3a6f289e72324f8f2085b64.tar.gz libsolv-a997565567d8b30dc3a6f289e72324f8f2085b64.tar.bz2 libsolv-a997565567d8b30dc3a6f289e72324f8f2085b64.zip |
Imported Upstream version 0.7.10upstream/0.7.10
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | VERSION.cmake | 2 | ||||
-rw-r--r-- | ext/libsolvext.ver | 2 | ||||
-rw-r--r-- | ext/repo_rpmdb.c | 29 | ||||
-rw-r--r-- | ext/repo_rpmdb.h | 7 | ||||
-rw-r--r-- | ext/repo_rpmdb_bdb.h | 62 | ||||
-rw-r--r-- | ext/repo_rpmdb_librpm.h | 159 | ||||
-rw-r--r-- | package/libsolv.changes | 7 |
9 files changed, 224 insertions, 54 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b39fd99..b7e5d7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,6 +238,8 @@ IF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM) ENDIF (NOT ENABLE_RPMDB_LIBRPM) INCLUDE (CheckLibraryExists) CHECK_LIBRARY_EXISTS(rpmio pgpDigGetParams "" HAVE_PGPDIGGETPARAMS) + CHECK_LIBRARY_EXISTS(rpm rpmdbNextIteratorHeaderBlob "" HAVE_RPMDBNEXTITERATORHEADERBLOB) + CHECK_LIBRARY_EXISTS(rpm rpmdbFStat "" HAVE_RPMDBFSTAT) ENDIF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM) IF (ENABLE_PUBKEY) @@ -270,7 +272,8 @@ ENDIF (${CMAKE_MAJOR_VERSION} GREATER 2) # should create config.h with #cmakedefine instead... FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN - HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS WITH_LIBXML2 WITHOUT_COOKIEOPEN) + HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS HAVE_RPMDBNEXTITERATORHEADERBLOB HAVE_RPMDBFSTAT + WITH_LIBXML2 WITHOUT_COOKIEOPEN) IF(${VAR}) ADD_DEFINITIONS (-D${VAR}=1) SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR}) @@ -2,6 +2,11 @@ This file contains the major changes between libsolv versions: +Version 0.7.10 +- new features: + * new rpm_stat_database() function + * new rpm_hash_database_state() function + Version 0.7.9 - new features: * support conda constrains dependencies diff --git a/VERSION.cmake b/VERSION.cmake index 0ec5582..7707dfc 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "1") SET(LIBSOLV_MAJOR "0") SET(LIBSOLV_MINOR "7") -SET(LIBSOLV_PATCH "9") +SET(LIBSOLV_PATCH "10") diff --git a/ext/libsolvext.ver b/ext/libsolvext.ver index 02cf6d1..6423837 100644 --- a/ext/libsolvext.ver +++ b/ext/libsolvext.ver @@ -47,10 +47,12 @@ SOLV_1.0 { rpm_byfp; rpm_byrpmdbid; rpm_byrpmh; + rpm_hash_database_state; rpm_installedrpmdbids; rpm_iterate_filelist; rpm_query; rpm_query_num; + rpm_stat_database; rpm_state_create; rpm_state_free; solv_verify_sig; diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index e49188d..67aa97c 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -1329,8 +1329,6 @@ freestate(struct rpmdbstate *state) { /* close down */ #ifdef ENABLE_RPMDB - if (state->pkgdbopened) - closepkgdb(state); if (state->dbenvopened) closedbenv(state); #endif @@ -1624,11 +1622,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) repo_empty(ref, 1); /* get it out of the way */ if ((flags & RPMDB_REPORT_PROGRESS) != 0) count = count_headers(&state); - if (!openpkgdb(&state)) - { - freestate(&state); - return -1; - } if (pkgdb_cursor_open(&state)) { freestate(&state); @@ -2394,6 +2387,28 @@ rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queu return nentries; } +int +rpm_hash_database_state(void *rpmstate, Chksum *chk) +{ + struct rpmdbstate *state = rpmstate; + struct stat stb; + if (stat_database(state, &stb)) + return -1; + if (state->dbenvopened != 1 && !opendbenv(state)) + return -1; + solv_chksum_add(chk, &stb.st_mtime, sizeof(stb.st_mtime)); + solv_chksum_add(chk, &stb.st_size, sizeof(stb.st_size)); + solv_chksum_add(chk, &stb.st_ino, sizeof(stb.st_ino)); + hash_name_index(rpmstate, chk); + return 0; +} + +int +rpm_stat_database(void *rpmstate, void *stb) +{ + return stat_database((struct rpmdbstate *)rpmstate, (struct stat *)stb) ? -1 : 0; +} + void * rpm_byrpmdbid(void *rpmstate, Id rpmdbid) { diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h index 554d48a..22aab88 100644 --- a/ext/repo_rpmdb.h +++ b/ext/repo_rpmdb.h @@ -7,6 +7,7 @@ #include "queue.h" #include "repo.h" +#include "chksum.h" struct headerToken_s; @@ -39,7 +40,11 @@ extern void *rpm_state_create(Pool *pool, const char *rootdir); extern void *rpm_state_free(void *rpmstate); /* return all matching rpmdbids */ -extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq); +extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq); +/* stat the package database */ +extern int rpm_stat_database(void *rpmstate, void *stb); +/* hash the state of the package database */ +extern int rpm_hash_database_state(void *rpmstate, Chksum *chk); /* return handles to a rpm header */ extern void *rpm_byrpmdbid(void *rpmstate, Id rpmdbid); diff --git a/ext/repo_rpmdb_bdb.h b/ext/repo_rpmdb_bdb.h index 574e9a8..a8b8500 100644 --- a/ext/repo_rpmdb_bdb.h +++ b/ext/repo_rpmdb_bdb.h @@ -56,11 +56,31 @@ struct rpmdbstate { }; +static inline int +access_rootdir(struct rpmdbstate *state, const char *dir, int mode) +{ + if (state->rootdir) + { + char *path = solv_dupjoin(state->rootdir, dir, 0); + int r = access(path, mode); + free(path); + return r; + } + return access(dir, mode); +} + +static void +detect_ostree(struct rpmdbstate *state) +{ + state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 && + access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 ? 1 : -1; +} + static int stat_database_name(struct rpmdbstate *state, char *dbname, struct stat *statbuf, int seterror) { char *dbpath; - dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname); + dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname); if (stat(dbpath, statbuf)) { if (seterror) @@ -75,6 +95,8 @@ stat_database_name(struct rpmdbstate *state, char *dbname, struct stat *statbuf, static int stat_database(struct rpmdbstate *state, struct stat *statbuf) { + if (!state->is_ostree) + detect_ostree(state); return stat_database_name(state, "Packages", statbuf, 1); } @@ -160,6 +182,7 @@ opendbenv(struct rpmdbstate *state) dbenv->set_thread_count(dbenv, 8); #endif dbpath = solv_dupjoin(rootdir, "/var/lib/rpm", 0); + state->is_ostree = -1; if (access(dbpath, W_OK) == -1) { free(dbpath); @@ -167,7 +190,7 @@ opendbenv(struct rpmdbstate *state) if (access(dbpath, R_OK) == 0) state->is_ostree = 1; free(dbpath); - dbpath = solv_dupjoin(rootdir, state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm", 0); + dbpath = solv_dupjoin(rootdir, state->is_ostree > 0 ? "/usr/share/rpm" : "/var/lib/rpm", 0); r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0); } else @@ -209,6 +232,12 @@ closedbenv(struct rpmdbstate *state) uint32_t eflags = 0; #endif + if (state->db) + { + state->db->close(state->db, 0); + state->db = 0; + } + state->pkgdbopened = 0; if (!state->dbenv) return; #if defined(FEDORA) || defined(MAGEIA) @@ -264,16 +293,6 @@ openpkgdb(struct rpmdbstate *state) return 1; } -static void -closepkgdb(struct rpmdbstate *state) -{ - if (!state->db) - return; - state->db->close(state->db, 0); - state->db = 0; - state->pkgdbopened = 0; -} - /* get the rpmdbids of all installed packages from the Name index database. * This is much faster then querying the big Packages database */ static struct rpmdbentry * @@ -464,6 +483,8 @@ count_headers(struct rpmdbstate *state) static int pkgdb_cursor_open(struct rpmdbstate *state) { + if (state->pkgdbopened != 1 && !openpkgdb(state)) + return -1; if (state->db->cursor(state->db, NULL, &state->dbc, 0)) return pool_error(state->pool, -1, "db->cursor failed"); return 0; @@ -497,3 +518,20 @@ pkgdb_cursor_getrpm(struct rpmdbstate *state) return 0; /* no more entries */ } +static int +hash_name_index(struct rpmdbstate *state, Chksum *chk) +{ + char *dbpath; + int fd, l; + char buf[4096]; + + dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", "Name"); + if ((fd = open(dbpath, O_RDONLY)) < 0) + return -1; + while ((l = read(fd, buf, sizeof(buf))) > 0) + solv_chksum_add(chk, buf, l); + close(fd); + return 0; +} + + diff --git a/ext/repo_rpmdb_librpm.h b/ext/repo_rpmdb_librpm.h index 6fdcfb0..b50a4b5 100644 --- a/ext/repo_rpmdb_librpm.h +++ b/ext/repo_rpmdb_librpm.h @@ -23,13 +23,32 @@ struct rpmdbstate { int rpmheadsize; int dbenvopened; /* database environment opened */ - int pkgdbopened; /* package database openend */ int is_ostree; /* read-only db that lives in /usr/share/rpm */ rpmts ts; rpmdbMatchIterator mi; /* iterator over packages database */ }; +static inline int +access_rootdir(struct rpmdbstate *state, const char *dir, int mode) +{ + if (state->rootdir) + { + char *path = solv_dupjoin(state->rootdir, dir, 0); + int r = access(path, mode); + free(path); + return r; + } + return access(dir, mode); +} + +static void +detect_ostree(struct rpmdbstate *state) +{ + state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 && + access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 ? 1 : -1; +} + static int stat_database(struct rpmdbstate *state, struct stat *statbuf) { @@ -43,9 +62,15 @@ stat_database(struct rpmdbstate *state, struct stat *statbuf) }; int i; +#ifdef HAVE_RPMDBFSTAT + if (state->dbenvopened == 1) + return rpmdbFStat(rpmtsGetRdb(state->ts), statbuf); +#endif + if (!state->is_ostree) + detect_ostree(state); for (i = 0; ; i++) { - char *dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname[i]); + char *dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname[i]); if (!stat(dbpath, statbuf)) { free(dbpath); @@ -53,8 +78,10 @@ stat_database(struct rpmdbstate *state, struct stat *statbuf) } if (errno != ENOENT || !dbname[i + 1]) { + int saved_errno = errno; pool_error(state->pool, -1, "%s: %s", dbpath, strerror(errno)); solv_free(dbpath); + errno = saved_errno; return -1; } solv_free(dbpath); @@ -68,16 +95,8 @@ opendbenv(struct rpmdbstate *state) const char *rootdir = state->rootdir; rpmts ts; char *dbpath; - dbpath = solv_dupjoin("_dbpath ", rootdir, "/var/lib/rpm"); - if (access(dbpath + 8, W_OK) == -1) - { - free(dbpath); - dbpath = solv_dupjoin(rootdir, "/usr/share/rpm/Packages", 0); - if (access(dbpath, R_OK) == 0) - state->is_ostree = 1; - free(dbpath); - dbpath = solv_dupjoin("_dbpath ", rootdir, state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); - } + detect_ostree(state); + dbpath = solv_dupjoin("_dbpath ", rootdir, state->is_ostree > 0 ? "/usr/share/rpm" : "/var/lib/rpm"); rpmDefineMacro(NULL, dbpath, 0); solv_free(dbpath); ts = rpmtsCreate(); @@ -98,7 +117,6 @@ opendbenv(struct rpmdbstate *state) rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES | _RPMVSF_NOHEADER); state->ts = ts; state->dbenvopened = 1; - state->pkgdbopened = 1; return 1; } @@ -108,22 +126,9 @@ closedbenv(struct rpmdbstate *state) if (state->ts) rpmtsFree(state->ts); state->ts = 0; - state->pkgdbopened = 0; state->dbenvopened = 0; } -static int -openpkgdb(struct rpmdbstate *state) -{ - /* already done in opendbenv */ - return 1; -} - -static void -closepkgdb(struct rpmdbstate *state) -{ -} - /* get the rpmdbids of all installed packages from the Name index database. * This is much faster then querying the big Packages database */ static struct rpmdbentry * @@ -139,7 +144,6 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma int nentries = 0; rpmdbIndexIterator ii; - int i; *nentriesp = 0; if (namedatap) @@ -154,6 +158,7 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma while (rpmdbIndexIteratorNext(ii, &key, &keylen) == 0) { + unsigned int i, npkgs; if (match) { if (keylen != matchl || memcmp(key, match, keylen) != 0) @@ -169,7 +174,8 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma namedata[namedatal + keylen] = 0; namedatal += keylen + 1; } - for (i = 0; i < rpmdbIndexIteratorNumPkgs(ii); i++) + npkgs = rpmdbIndexIteratorNumPkgs(ii); + for (i = 0; i < npkgs; i++) { entries = solv_extend(entries, nentries, 1, sizeof(*entries), ENTRIES_BLOCK); entries[nentries].rpmdbid = rpmdbIndexIteratorPkgOffset(ii, i); @@ -187,17 +193,67 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma return entries; } +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) +static int +rpm_byrpmhdrblob(struct rpmdbstate *state, const unsigned char *data, unsigned int size) +{ + unsigned int dsize, cnt, len; + RpmHead *rpmhead; + if (size < 8) + return pool_error(state->pool, 0, "corrupt rpm database (size)"); + cnt = getu32(data); + dsize = getu32(data + 4); + if (cnt >= MAX_HDR_CNT || dsize >= MAX_HDR_DSIZE) + return pool_error(state->pool, 0, "corrupt rpm database (cnt/dcnt)"); + if (8 + cnt * 16 + dsize > size) + return pool_error(state->pool, 0, "corrupt rpm database (data size)"); + len = 16 * cnt + dsize; + if (len + 1 > state->rpmheadsize) + { + state->rpmheadsize = len + 128; + state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + state->rpmheadsize); + } + rpmhead = state->rpmhead; + memcpy(rpmhead->data, data + 8, len); + rpmhead->data[len] = 0; + rpmhead->cnt = cnt; + rpmhead->dcnt = dsize; + rpmhead->dp = rpmhead->data + cnt * 16; + return 1; +} +#endif + /* retrive header by rpmdbid, returns 0 if not found, -1 on error */ static int getrpm_dbid(struct rpmdbstate *state, Id rpmdbid) { +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) + const unsigned char *uh; + unsigned int uhlen; +#else Header h; +#endif rpmdbMatchIterator mi; unsigned int offset = rpmdbid; + if (rpmdbid <= 0) + return pool_error(state->pool, -1, "illegal rpmdbid %d", rpmdbid); if (state->dbenvopened != 1 && !opendbenv(state)) return -1; - mi = rpmtsInitIterator(state->ts, RPMDBI_PACKAGES, &offset, sizeof(offset)); + mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_PACKAGES, &offset, sizeof(offset)); +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) + uh = rpmdbNextIteratorHeaderBlob(mi, &uhlen); + if (!uh) + { + rpmdbFreeIterator(mi); + return 0; + } + if (!rpm_byrpmhdrblob(state, uh, uhlen)) + { + rpmdbFreeIterator(mi); + return -1; + } +#else h = rpmdbNextIterator(mi); if (!h) { @@ -209,8 +265,9 @@ getrpm_dbid(struct rpmdbstate *state, Id rpmdbid) rpmdbFreeIterator(mi); return -1; } +#endif mi = rpmdbFreeIterator(mi); - return 1; + return rpmdbid; } static int @@ -221,7 +278,7 @@ count_headers(struct rpmdbstate *state) if (state->dbenvopened != 1 && !opendbenv(state)) return 0; - mi = rpmtsInitIterator(state->ts, RPMDBI_NAME, NULL, 0); + mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_NAME, NULL, 0); count = rpmdbGetIteratorCount(mi); rpmdbFreeIterator(mi); return count; @@ -230,7 +287,7 @@ count_headers(struct rpmdbstate *state) static int pkgdb_cursor_open(struct rpmdbstate *state) { - state->mi = rpmtsInitIterator(state->ts, RPMDBI_PACKAGES, NULL, 0); + state->mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_PACKAGES, NULL, 0); return 0; } @@ -244,6 +301,17 @@ pkgdb_cursor_close(struct rpmdbstate *state) static Id pkgdb_cursor_getrpm(struct rpmdbstate *state) { +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) + const unsigned char *uh; + unsigned int uhlen; + while ((uh = rpmdbNextIteratorHeaderBlob(state->mi, &uhlen)) != 0) + { + Id dbid = rpmdbGetIteratorOffset(state->mi); + if (!rpm_byrpmhdrblob(state, uh, uhlen)) + continue; + return dbid; + } +#else Header h; while ((h = rpmdbNextIterator(state->mi))) { @@ -252,6 +320,33 @@ pkgdb_cursor_getrpm(struct rpmdbstate *state) continue; return dbid; } +#endif + return 0; +} + +static int +hash_name_index(struct rpmdbstate *state, Chksum *chk) +{ + rpmdbIndexIterator ii; + const void *key; + size_t keylen; + + if (state->dbenvopened != 1 && !opendbenv(state)) + return -1; + ii = rpmdbIndexIteratorInit(rpmtsGetRdb(state->ts), RPMDBI_NAME); + if (!ii) + return -1; + while (rpmdbIndexIteratorNext(ii, &key, &keylen) == 0) + { + unsigned int i, npkgs = rpmdbIndexIteratorNumPkgs(ii); + solv_chksum_add(chk, key, (int)keylen); + for (i = 0; i < npkgs; i++) + { + unsigned int offset = rpmdbIndexIteratorPkgOffset(ii, i); + solv_chksum_add(chk, &offset, sizeof(offset)); + } + } + rpmdbIndexIteratorFree(ii); return 0; } diff --git a/package/libsolv.changes b/package/libsolv.changes index 9ae1511..b638864 100644 --- a/package/libsolv.changes +++ b/package/libsolv.changes @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Tue Dec 10 14:18:36 CET 2019 - mls@suse.de + +- added two new function to make libzypp independent of the rpm + database format +- bump version to 0.7.10 + +------------------------------------------------------------------- Thu Nov 21 16:34:52 CET 2019 - mls@suse.de - support conda constrains dependencies |