diff --git a/0001-Add-support-for-computing-hashes-using-OpenSSL.patch b/0001-Add-support-for-computing-hashes-using-OpenSSL.patch index 5a7c78a..e20e293 100644 --- a/0001-Add-support-for-computing-hashes-using-OpenSSL.patch +++ b/0001-Add-support-for-computing-hashes-using-OpenSSL.patch @@ -1,19 +1,17 @@ -From 11eab76046e2df31248d358ab85bdbcf366d2c78 Mon Sep 17 00:00:00 2001 -From: Nicola Sella -Date: Wed, 11 Nov 2020 14:52:14 +0100 -Subject: [PATCH 1/1] Add support for computing hashes using OpenSSL +From c56a7db62db6d62b53830f8f1af4d5a70e86d69f Mon Sep 17 00:00:00 2001 +From: Jaroslav Rohel +Date: Fri, 25 Oct 2019 14:33:22 +0200 +Subject: [PATCH 1/3] Add support for computing hashes using OpenSSL It adds WITH_OPENSSL build option. If it is ON, OpenSSL will be used instead of internal implementation of computing hashes (MD5, SHA1, SHA224, SHA256, SHA384, SHA512). - -Rebase of https://github.com/openSUSE/libsolv/commit/9839a88e4fda23b46015170b201c98da7bcdd55e --- CMakeLists.txt | 13 +++++++++++-- - src/CMakeLists.txt | 16 +++++++++++----- + src/CMakeLists.txt | 12 +++++++++--- src/chksum.c | 32 ++++++++++++++++++++++++++++++++ tools/CMakeLists.txt | 2 +- - 4 files changed, 55 insertions(+), 8 deletions(-) + 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3541f496..e73dc552 100644 @@ -61,7 +59,7 @@ index 3541f496..e73dc552 100644 SET (SYSTEM_LIBRARIES ${RPMDB_LIBRARY} ${SYSTEM_LIBRARIES}) ENDIF (ENABLE_RPMDB) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index bbf30bac..ece870ee 100644 +index bbf30bac..6b5ea42b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,9 +18,8 @@ SET (libsolv_SRCS @@ -76,7 +74,7 @@ index bbf30bac..ece870ee 100644 SET (libsolv_HEADERS bitmap.h evr.h hash.h policy.h poolarch.h poolvendor.h pool.h -@@ -43,14 +42,21 @@ IF (WIN32) +@@ -43,6 +42,10 @@ IF (WIN32) LIST (APPEND libsolv_SRCS ${WIN32_COMPAT_SOURCES}) ENDIF (WIN32) @@ -87,16 +85,13 @@ index bbf30bac..ece870ee 100644 IF (HAVE_LINKER_VERSION_SCRIPT) SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINK_FLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/src/libsolv.ver") ENDIF (HAVE_LINKER_VERSION_SCRIPT) - - IF (DISABLE_SHARED) -- ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS}) -+ ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS}) +@@ -51,6 +54,9 @@ IF (DISABLE_SHARED) + ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS}) ELSE (DISABLE_SHARED) -- ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS}) -+ ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS}) -+ IF (WITH_OPENSSL) -+ TARGET_LINK_LIBRARIES (libsolv ${OPENSSL_CRYPTO_LIBRARY}) -+ ENDIF (WITH_OPENSSL) + ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS}) ++ IF (WITH_OPENSSL) ++ TARGET_LINK_LIBRARIES (libsolv ${OPENSSL_CRYPTO_LIBRARY}) ++ ENDIF (WITH_OPENSSL) ENDIF (DISABLE_SHARED) IF (WIN32) @@ -161,5 +156,5 @@ index f19030eb..d477e195 100644 ADD_EXECUTABLE (mergesolv mergesolv.c ) TARGET_LINK_LIBRARIES (mergesolv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIES}) -- -2.26.2 +2.31.1 diff --git a/0002-Add-support-for-storing-user-data-in-a-solv-file.patch b/0002-Add-support-for-storing-user-data-in-a-solv-file.patch new file mode 100644 index 0000000..f17d194 --- /dev/null +++ b/0002-Add-support-for-storing-user-data-in-a-solv-file.patch @@ -0,0 +1,311 @@ +From 9b89a186e3769631b6cee859be9d69063cfdfb94 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Fri, 25 Feb 2022 16:47:21 +0100 +Subject: [PATCH 2/3] Add support for storing user data in a solv file + +Userdata can be arbritrary (binary)data with a maximum size of +65535 bytes. It can be read without reading the complete +solv file, but do not forget to rewind the fp after reading +the user data. + +New functions: +void + void repowriter_set_userdata(Repowriter *writer, const void *data, int len) + int solv_read_userdata(FILE *fp, unsigned char **datap, int *lenp) +--- + src/libsolv.ver | 2 ++ + src/pooltypes.h | 6 ++++-- + src/repo_solv.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/repo_solv.h | 1 + + src/repo_write.c | 24 ++++++++++++++++++++- + src/repo_write.h | 3 +++ + tools/dumpsolv.c | 50 ++++++++++++++++++++++++++++++++++++++++---- + 7 files changed, 133 insertions(+), 7 deletions(-) + +diff --git a/src/libsolv.ver b/src/libsolv.ver +index ee40d0ad..4c6fbf4f 100644 +--- a/src/libsolv.ver ++++ b/src/libsolv.ver +@@ -255,6 +255,7 @@ SOLV_1.0 { + repowriter_set_keyqueue; + repowriter_set_repodatarange; + repowriter_set_solvablerange; ++ repowriter_set_userdata; + repowriter_write; + selection_add; + selection_filter; +@@ -288,6 +289,7 @@ SOLV_1.0 { + solv_malloc; + solv_malloc2; + solv_oom; ++ solv_read_userdata; + solv_realloc; + solv_realloc2; + solv_replacebadutf8; +diff --git a/src/pooltypes.h b/src/pooltypes.h +index e1f77b0e..3bde155a 100644 +--- a/src/pooltypes.h ++++ b/src/pooltypes.h +@@ -23,9 +23,11 @@ + #define SOLV_VERSION_6 6 + #define SOLV_VERSION_7 7 + #define SOLV_VERSION_8 8 ++#define SOLV_VERSION_9 9 + +-#define SOLV_FLAG_PREFIX_POOL 4 +-#define SOLV_FLAG_SIZE_BYTES 8 ++#define SOLV_FLAG_PREFIX_POOL 4 ++#define SOLV_FLAG_SIZE_BYTES 8 ++#define SOLV_FLAG_USERDATA 16 + + struct s_Stringpool; + typedef struct s_Stringpool Stringpool; +diff --git a/src/repo_solv.c b/src/repo_solv.c +index 761d06e6..2ba602b2 100644 +--- a/src/repo_solv.c ++++ b/src/repo_solv.c +@@ -514,6 +514,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) + switch (solvversion) + { + case SOLV_VERSION_8: ++ case SOLV_VERSION_9: + break; + default: + return pool_error(pool, SOLV_ERROR_UNSUPPORTED, "unsupported SOLV version"); +@@ -552,6 +553,18 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) + return pool_error(pool, SOLV_ERROR_CORRUPT, "main repository contains holes, cannot extend"); + } + ++ /******* Part 0: skip optional userdata ******************************/ ++ ++ if (solvflags & SOLV_FLAG_USERDATA) ++ { ++ unsigned int userdatalen = read_u32(&data); ++ if (userdatalen >= 65536) ++ return pool_error(pool, SOLV_ERROR_CORRUPT, "illegal userdata length"); ++ while (userdatalen--) ++ if (getc(data.fp) == EOF) ++ return pool_error(pool, SOLV_ERROR_EOF, "unexpected EOF"); ++ } ++ + /******* Part 1: string IDs *****************************************/ + + sizeid = read_u32(&data); /* size of string space */ +@@ -1353,3 +1366,44 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key + return 0; + } + ++int ++solv_read_userdata(FILE *fp, unsigned char **datap, int *lenp) ++{ ++ unsigned char d[4 * 10], *ud = 0; ++ unsigned int n; ++ if (fread(d, sizeof(d), 1, fp) != 1) ++ return SOLV_ERROR_EOF; ++ n = d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3]; ++ if (n != ('S' << 24 | 'O' << 16 | 'L' << 8 | 'V')) ++ return SOLV_ERROR_NOT_SOLV; ++ n = d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7]; ++ switch(n) ++ { ++ case SOLV_VERSION_8: ++ case SOLV_VERSION_9: ++ break; ++ default: ++ return SOLV_ERROR_UNSUPPORTED; ++ } ++ n = d[32] << 24 | d[33] << 16 | d[34] << 8 | d[35]; ++ if (!(n & SOLV_FLAG_USERDATA)) ++ n = 0; ++ else ++ n = d[36] << 24 | d[37] << 16 | d[38] << 8 | d[39]; ++ if (n >= 65536) ++ return SOLV_ERROR_CORRUPT; ++ if (n) ++ { ++ ud = solv_malloc(n + 1); ++ if (fread(ud, n, 1, fp) != 1) ++ { ++ solv_free(ud); ++ return SOLV_ERROR_EOF; ++ } ++ ud[n] = 0; ++ } ++ *datap = ud; ++ if (lenp) ++ *lenp = (int)n; ++ return 0; ++} +diff --git a/src/repo_solv.h b/src/repo_solv.h +index 0c663949..57bf1772 100644 +--- a/src/repo_solv.h ++++ b/src/repo_solv.h +@@ -23,6 +23,7 @@ extern "C" { + #endif + + extern int repo_add_solv(Repo *repo, FILE *fp, int flags); ++extern int solv_read_userdata(FILE *fp, unsigned char **datap, int *lenp); + + #define SOLV_ADD_NO_STUBS (1 << 8) + +diff --git a/src/repo_write.c b/src/repo_write.c +index af4e7599..a11de002 100644 +--- a/src/repo_write.c ++++ b/src/repo_write.c +@@ -1071,6 +1071,7 @@ repowriter_create(Repo *repo) + Repowriter * + repowriter_free(Repowriter *writer) + { ++ solv_free(writer->userdata); + return solv_free(writer); + } + +@@ -1107,6 +1108,17 @@ repowriter_set_solvablerange(Repowriter *writer, int solvablestart, int solvable + writer->solvableend = solvableend; + } + ++void ++repowriter_set_userdata(Repowriter *writer, const void *data, int len) ++{ ++ writer->userdata = solv_free(writer->userdata); ++ writer->userdatalen = 0; ++ if (len < 0 || len >= 65536) ++ return; ++ writer->userdata = len ? solv_memdup(data, len) : 0; ++ writer->userdatalen = len; ++} ++ + /* + * the code works the following way: + * +@@ -1898,7 +1910,10 @@ for (i = 1; i < target.nkeys; i++) + + /* write file header */ + write_u32(&target, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V'); +- write_u32(&target, SOLV_VERSION_8); ++ if (writer->userdatalen) ++ write_u32(&target, SOLV_VERSION_9); ++ else ++ write_u32(&target, SOLV_VERSION_8); + + + /* write counts */ +@@ -1911,7 +1926,14 @@ for (i = 1; i < target.nkeys; i++) + solv_flags = 0; + solv_flags |= SOLV_FLAG_PREFIX_POOL; + solv_flags |= SOLV_FLAG_SIZE_BYTES; ++ if (writer->userdatalen) ++ solv_flags |= SOLV_FLAG_USERDATA; + write_u32(&target, solv_flags); ++ if (writer->userdatalen) ++ { ++ write_u32(&target, writer->userdatalen); ++ write_blob(&target, writer->userdata, writer->userdatalen); ++ } + + if (nstrings) + { +diff --git a/src/repo_write.h b/src/repo_write.h +index 34716705..7734b013 100644 +--- a/src/repo_write.h ++++ b/src/repo_write.h +@@ -32,6 +32,8 @@ typedef struct s_Repowriter { + int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata); + void *kfdata; + Queue *keyq; ++ void *userdata; ++ int userdatalen; + } Repowriter; + + /* repowriter flags */ +@@ -46,6 +48,7 @@ void repowriter_set_keyfilter(Repowriter *writer, int (*keyfilter)(Repo *repo, R + void repowriter_set_keyqueue(Repowriter *writer, Queue *keyq); + void repowriter_set_repodatarange(Repowriter *writer, int repodatastart, int repodataend); + void repowriter_set_solvablerange(Repowriter *writer, int solvablestart, int solvableend); ++void repowriter_set_userdata(Repowriter *writer, const void *data, int len); + int repowriter_write(Repowriter *writer, FILE *fp); + + /* convenience functions */ +diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c +index 13076574..49651fbe 100644 +--- a/tools/dumpsolv.c ++++ b/tools/dumpsolv.c +@@ -13,6 +13,7 @@ + + static int with_attr; + static int dump_json; ++static int dump_userdata; + + #include "pool.h" + #include "chksum.h" +@@ -394,10 +395,7 @@ int main(int argc, char **argv) + int c, i, j, n; + Solvable *s; + +- pool = pool_create(); +- pool_setloadcallback(pool, loadcallback, 0); +- +- while ((c = getopt(argc, argv, "haj")) >= 0) ++ while ((c = getopt(argc, argv, "uhaj")) >= 0) + { + switch(c) + { +@@ -410,11 +408,55 @@ int main(int argc, char **argv) + case 'j': + dump_json = 1; + break; ++ case 'u': ++ dump_userdata++; ++ break; + default: + usage(1); + break; + } + } ++ if (dump_userdata) ++ { ++ if (optind == argc) ++ argc++; ++ for (; optind < argc; optind++) ++ { ++ unsigned char *userdata = 0; ++ int r, userdatalen = 0; ++ if (argv[optind] && freopen(argv[optind], "r", stdin) == 0) ++ { ++ perror(argv[optind]); ++ exit(1); ++ } ++ r = solv_read_userdata(stdin, &userdata, &userdatalen); ++ if (r) ++ { ++ fprintf(stderr, "could not read userdata: error %d\n", r); ++ exit(1); ++ } ++ if (dump_userdata > 1) ++ { ++ /* dump raw */ ++ if (userdatalen && fwrite(userdata, userdatalen, 1, stdout) != 1) ++ { ++ perror("fwrite"); ++ exit(1); ++ } ++ } ++ else ++ { ++ for (r = 0; r < userdatalen; r++) ++ printf("%02x", userdata[r]); ++ printf("\n"); ++ } ++ solv_free(userdata); ++ } ++ exit(0); ++ } ++ ++ pool = pool_create(); ++ pool_setloadcallback(pool, loadcallback, 0); + if (!dump_json) + pool_setdebuglevel(pool, 1); + if (dump_json) +-- +2.31.1 + diff --git a/0003-Improve-choice-rule-generation.patch b/0003-Improve-choice-rule-generation.patch new file mode 100644 index 0000000..a28e3a1 --- /dev/null +++ b/0003-Improve-choice-rule-generation.patch @@ -0,0 +1,352 @@ +From fd52342713012ec111b1559fa1647f88768fa782 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Wed, 16 Mar 2022 15:17:20 +0100 +Subject: [PATCH 3/3] Improve choice rule generation + +New strategy: take the package update map into account when creating +choice rules. This simplifies the code quite a bit. Also check at +the end of the solving if a choice rule led to two packages providing +the same thing. In that case, break the choice rule and re-run the +solver. +--- + src/rules.c | 169 +++++++++++++-------------------------------------- + src/solver.c | 45 ++++++++++++++ + 2 files changed, 88 insertions(+), 126 deletions(-) + +diff --git a/src/rules.c b/src/rules.c +index 212df322..324fe5da 100644 +--- a/src/rules.c ++++ b/src/rules.c +@@ -3139,6 +3139,12 @@ solver_rule2rules(Solver *solv, Id rid, Queue *q, int recursive) + + + /* check if the newest versions of pi still provides the dependency we're looking for */ ++/* pi: installed package ++ * r: rule for the dependency ++ * m: map with all positive elements of r ++ * return 0: at least one provider ++ * return 1: the newest versions do not provide the dependency ++ */ + static int + solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q) + { +@@ -3187,94 +3193,6 @@ solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q) + return 1; /* none of the new packages provided it */ + } + +-static int +-solver_choicerulecheck2(Solver *solv, Id pi, Id pt, Queue *q) +-{ +- Pool *pool = solv->pool; +- Rule *ur; +- Id p, pp; +- int i; +- +- if (!q->count || q->elements[0] != pi) +- { +- if (q->count) +- queue_empty(q); +- ur = solv->rules + solv->updaterules + (pi - pool->installed->start); +- if (!ur->p) +- ur = solv->rules + solv->featurerules + (pi - pool->installed->start); +- if (!ur->p) +- return 1; /* orphaned, thus newest */ +- queue_push2(q, pi, 0); +- FOR_RULELITERALS(p, pp, ur) +- if (p > 0 && p != pi) +- queue_push(q, p); +- queue_push(q, pi); +- } +- if (q->count <= 3) +- return q->count == 3 && q->elements[2] == pt ? 1 : 0; +- if (!q->elements[1]) +- { +- queue_deleten(q, 0, 2); +- policy_filter_unwanted(solv, q, POLICY_MODE_CHOOSE); +- queue_unshift(q, 1); /* filter mark */ +- queue_unshift(q, pi); +- } +- for (i = 2; i < q->count; i++) +- if (q->elements[i] == pt) +- return 1; +- return 0; /* not newest */ +-} +- +-static int +-solver_choicerulecheck3(Solver *solv, Id pt, Queue *q) +-{ +- Pool *pool = solv->pool; +- Id p, pp; +- int i; +- +- if (!q->count || q->elements[0] != pt) +- { +- Solvable *s = pool->solvables + pt; +- if (q->count) +- queue_empty(q); +- /* no installed package, so check all with same name */ +- queue_push2(q, pt, 0); +- FOR_PROVIDES(p, pp, s->name) +- if (pool->solvables[p].name == s->name && p != pt) +- queue_push(q, p); +- queue_push(q, pt); +- } +- if (q->count <= 3) +- return q->count == 3 && q->elements[2] == pt ? 1 : 0; +- if (!q->elements[1]) +- { +- queue_deleten(q, 0, 2); +- policy_filter_unwanted(solv, q, POLICY_MODE_CHOOSE); +- queue_unshift(q, 1); /* filter mark */ +- queue_unshift(q, pt); +- } +- for (i = 2; i < q->count; i++) +- if (q->elements[i] == pt) +- return 1; +- return 0; /* not newest */ +-} +- +-static inline void +-queue_removeelement(Queue *q, Id el) +-{ +- int i, j; +- for (i = 0; i < q->count; i++) +- if (q->elements[i] == el) +- break; +- if (i < q->count) +- { +- for (j = i++; i < q->count; i++) +- if (q->elements[i] != el) +- q->elements[j++] = q->elements[i]; +- queue_truncate(q, j); +- } +-} +- + static Id + choicerule_find_installed(Pool *pool, Id p) + { +@@ -3323,14 +3241,14 @@ solver_addchoicerules(Solver *solv) + Pool *pool = solv->pool; + Map m, mneg; + Rule *r; +- Queue q, qi, qcheck, qcheck2, infoq; ++ Queue q, qi, qcheck, infoq; + int i, j, rid, havechoice, negcnt; + Id p, d, pp, p2; + Solvable *s; + Id lastaddedp, lastaddedd; + int lastaddedcnt; + unsigned int now; +- int isnewest = 0; ++ int isinstalled; + + solv->choicerules = solv->nrules; + if (!pool->installed) +@@ -3342,7 +3260,6 @@ solver_addchoicerules(Solver *solv) + queue_init(&q); + queue_init(&qi); + queue_init(&qcheck); +- queue_init(&qcheck2); + queue_init(&infoq); + map_init(&m, pool->nsolvables); + map_init(&mneg, pool->nsolvables); +@@ -3362,20 +3279,28 @@ solver_addchoicerules(Solver *solv) + if (r->p >= 0 || ((r->d == 0 || r->d == -1) && r->w2 <= 0)) + continue; /* only look at requires rules */ + /* solver_printrule(solv, SOLV_DEBUG_RESULT, r); */ +- queue_empty(&q); + queue_empty(&qi); + havechoice = 0; ++ isinstalled = 0; + FOR_RULELITERALS(p, pp, r) + { + if (p < 0) +- continue; ++ { ++ Solvable *s = pool->solvables - p; ++ p2 = s->repo == pool->installed ? -p : 0; ++ if (p2) ++ { ++ if (!(solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, p2 - solv->installed->start)))) ++ isinstalled = 1; ++ } ++ continue; ++ } + s = pool->solvables + p; + if (!s->repo) + continue; + if (s->repo == pool->installed) + { + queue_push2(&qi, p, p); +- queue_push(&q, p); + continue; + } + /* find an installed package p2 that we can update/downgrade to p */ +@@ -3387,7 +3312,6 @@ solver_addchoicerules(Solver *solv) + if (policy_is_illegal(solv, pool->solvables + p2, s, 0)) + continue; + queue_push2(&qi, p2, p); +- queue_push(&q, p); + continue; + } + /* package p is independent of the installed ones */ +@@ -3396,47 +3320,31 @@ solver_addchoicerules(Solver *solv) + #if 0 + printf("havechoice: %d qcount %d qicount %d\n", havechoice, q.count, qi.count); + #endif +- if (!havechoice || !q.count || !qi.count) ++ if (!havechoice || !qi.count) + continue; /* no choice */ + + FOR_RULELITERALS(p, pp, r) + if (p > 0) + MAPSET(&m, p); + +- isnewest = 1; +- FOR_RULELITERALS(p, pp, r) +- { +- if (p > 0) +- break; +- p2 = choicerule_find_installed(pool, -p); +- if (p2 && !solver_choicerulecheck2(solv, p2, -p, &qcheck2)) +- { +- isnewest = 0; +- break; +- } +- if (!p2 && !solver_choicerulecheck3(solv, -p, &qcheck2)) +- { +- isnewest = 0; +- break; +- } +- } +- /* do extra checking */ +- for (i = j = 0; i < qi.count; i += 2) ++ if (!isinstalled) + { +- p2 = qi.elements[i]; +- if (!p2) +- continue; +- if (isnewest && solver_choicerulecheck(solv, p2, r, &m, &qcheck)) ++ /* do extra checking for packages related to installed packages */ ++ for (i = j = 0; i < qi.count; i += 2) + { +- /* oops, remove element p from q */ +- queue_removeelement(&q, qi.elements[i + 1]); +- continue; ++ p2 = qi.elements[i]; ++ if (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, p2 - solv->installed->start))) ++ { ++ if (solver_choicerulecheck(solv, p2, r, &m, &qcheck)) ++ continue; ++ } ++ qi.elements[j++] = p2; ++ qi.elements[j++] = qi.elements[i + 1]; + } +- qi.elements[j++] = p2; ++ queue_truncate(&qi, j); + } +- queue_truncate(&qi, j); + +- if (!q.count || !qi.count) ++ if (!qi.count) + { + FOR_RULELITERALS(p, pp, r) + if (p > 0) +@@ -3444,6 +3352,15 @@ solver_addchoicerules(Solver *solv) + continue; + } + ++ queue_empty(&q); ++ /* split q from qi */ ++ for (i = j = 0; i < qi.count; i += 2) ++ { ++ queue_push(&q, qi.elements[i + 1]); ++ qi.elements[j++] = qi.elements[i]; ++ } ++ queue_truncate(&qi, j); ++ + + /* now check the update rules of the installed package. + * if all packages of the update rules are contained in +@@ -3463,6 +3380,7 @@ solver_addchoicerules(Solver *solv) + break; + if (p) + break; ++ /* speed improvement: only check each package once */ + for (j = i + 1; j < qi.count; j++) + if (qi.elements[i] == qi.elements[j]) + qi.elements[j] = 0; +@@ -3520,7 +3438,6 @@ solver_addchoicerules(Solver *solv) + queue_free(&q); + queue_free(&qi); + queue_free(&qcheck); +- queue_free(&qcheck2); + queue_free(&infoq); + map_free(&m); + map_free(&mneg); +diff --git a/src/solver.c b/src/solver.c +index 1dc2c783..08029baa 100644 +--- a/src/solver.c ++++ b/src/solver.c +@@ -2615,6 +2615,43 @@ resolve_orphaned(Solver *solv, int level, int disablerules, Queue *dq, int *reru + return level; + } + ++int ++solver_check_unneeded_choicerules(Solver *solv) ++{ ++ Pool *pool = solv->pool; ++ Rule *r, *or; ++ Id p, pp, p2, pp2; ++ int i; ++ int havedisabled = 0; ++ ++ /* check if some choice rules could have been broken */ ++ for (i = solv->choicerules, r = solv->rules + i; i < solv->choicerules_end; i++, r++) ++ { ++ if (r->d < 0) ++ continue; ++ or = solv->rules + solv->choicerules_info[i - solv->choicerules]; ++ if (or->d < 0) ++ continue; ++ FOR_RULELITERALS(p, pp, or) ++ { ++ if (p < 0 || solv->decisionmap[p] <= 0) ++ continue; ++ FOR_RULELITERALS(p2, pp2, r) ++ if (p2 == p) ++ break; ++ if (!p2) ++ { ++ /* did not find p in choice rule, disable it */ ++ POOL_DEBUG(SOLV_DEBUG_SOLVER, "disabling unneeded choice rule #%d\n", i); ++ solver_disablechoicerules(solv, r); ++ havedisabled = 1; ++ break; ++ } ++ } ++ } ++ return havedisabled; ++} ++ + /*------------------------------------------------------------------- + * + * solver_run_sat +@@ -2800,6 +2837,14 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) + continue; + } + ++ if (solv->choicerules != solv->choicerules_end && solver_check_unneeded_choicerules(solv)) ++ { ++ POOL_DEBUG(SOLV_DEBUG_SOLVER, "did choice rule minimization, rerunning solver\n"); ++ solver_reset(solv); ++ level = 0; /* restart from scratch */ ++ continue; ++ } ++ + if (solv->solution_callback) + { + solv->solution_callback(solv, solv->solution_callback_data); +-- +2.31.1 + diff --git a/0004-Allow-accessing-toolversion-at-runtime-and-increase-.patch b/0004-Allow-accessing-toolversion-at-runtime-and-increase-.patch new file mode 100644 index 0000000..9603470 --- /dev/null +++ b/0004-Allow-accessing-toolversion-at-runtime-and-increase-.patch @@ -0,0 +1,68 @@ +From 07a1a0fd83f108a0e9b1f801b52ff2bd26722097 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= +Date: Thu, 27 Jan 2022 08:38:27 +0100 +Subject: [PATCH] Allow accessing toolversion at runtime and increase it + +--- + src/libsolv.ver | 1 + + src/solvversion.c | 1 + + src/solvversion.h.in | 3 ++- + tools/common_write.c | 1 + + 4 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/libsolv.ver b/src/libsolv.ver +index 4c6fbf4f..89517f50 100644 +--- a/src/libsolv.ver ++++ b/src/libsolv.ver +@@ -306,6 +306,7 @@ SOLV_1.0 { + solv_version_major; + solv_version_minor; + solv_version_patch; ++ solv_toolversion; + solvable_add_deparray; + solvable_add_idarray; + solvable_add_poolstr_array; +diff --git a/src/solvversion.c b/src/solvversion.c +index d66e1958..51d57a63 100644 +--- a/src/solvversion.c ++++ b/src/solvversion.c +@@ -11,3 +11,4 @@ const char solv_version[] = LIBSOLV_VERSION_STRING; + int solv_version_major = LIBSOLV_VERSION_MAJOR; + int solv_version_minor = LIBSOLV_VERSION_MINOR; + int solv_version_patch = LIBSOLV_VERSION_PATCH; ++const char solv_toolversion[] = LIBSOLV_TOOLVERSION; +diff --git a/src/solvversion.h.in b/src/solvversion.h.in +index 43b566a1..da0ad743 100644 +--- a/src/solvversion.h.in ++++ b/src/solvversion.h.in +@@ -23,6 +23,7 @@ extern const char solv_version[]; + extern int solv_version_major; + extern int solv_version_minor; + extern int solv_version_patch; ++extern const char solv_toolversion[]; + + #cmakedefine LIBSOLV_FEATURE_LINKED_PKGS + #cmakedefine LIBSOLV_FEATURE_COMPLEX_DEPS +@@ -48,6 +49,6 @@ extern int solv_version_patch; + #cmakedefine LIBSOLVEXT_FEATURE_ZCHUNK_COMPRESSION + + /* see tools/common_write.c for toolversion history */ +-#define LIBSOLV_TOOLVERSION "1.1" ++#define LIBSOLV_TOOLVERSION "1.2" + + #endif +diff --git a/tools/common_write.c b/tools/common_write.c +index 36f8dd89..8fda3e33 100644 +--- a/tools/common_write.c ++++ b/tools/common_write.c +@@ -19,6 +19,7 @@ + /* toolversion history + * 1.0: initial tool version + * 1.1: changed PRODUCT_ENDOFLIFE parsing ++ * 1.2: added UPDATE_COLLECTIONLIST to updateinfo + */ + + static int +-- +2.31.1 + diff --git a/libsolv.spec b/libsolv.spec index 0ac91b4..bec7717 100644 --- a/libsolv.spec +++ b/libsolv.spec @@ -37,7 +37,7 @@ Name: lib%{libname} Version: 0.7.20 -Release: 1%{?dist} +Release: 3%{?dist} Summary: Package dependency solver License: BSD @@ -49,6 +49,9 @@ Source: %{url}/archive/%{version}/%{name}-%{version}.tar.gz %endif # https://bugzilla.redhat.com/show_bug.cgi?id=1630300 Patch1: 0001-Add-support-for-computing-hashes-using-OpenSSL.patch +Patch2: 0002-Add-support-for-storing-user-data-in-a-solv-file.patch +Patch3: 0003-Improve-choice-rule-generation.patch +Patch4: 0004-Allow-accessing-toolversion-at-runtime-and-increase-.patch BuildRequires: cmake BuildRequires: gcc-c++ @@ -277,6 +280,13 @@ export LD_LIBRARY_PATH=%{buildroot}%{_libdir} %endif %changelog +* Thu May 05 2022 Lukas Hrazky - 0.7.20-3 +- Allow accessing toolversion at runtime and increase it + +* Wed May 04 2022 Lukas Hrazky - 0.7.20-2 +- Add support for storing user data in a solv file +- Improve choice rule generation + * Tue Nov 09 2021 Pavla Kratochvilova - 0.7.20-1 - Update to 0.7.20 - new SOLVER_EXCLUDEFROMWEAK job to ignore pkgs for weak dependencies