diff options
-rw-r--r-- | NEWS | 10 | ||||
-rw-r--r-- | VERSION.cmake | 2 | ||||
-rw-r--r-- | ext/testcase.c | 14 | ||||
-rw-r--r-- | package/libsolv.changes | 17 | ||||
-rw-r--r-- | src/rules.c | 170 | ||||
-rw-r--r-- | src/solver.c | 8 | ||||
-rw-r--r-- | test/testcases/choicerules/choice2.t | 23 |
7 files changed, 167 insertions, 77 deletions
@@ -2,6 +2,16 @@ This file contains the major changes between libsolv versions: +Version 0.7.16 +- selected bug fixes: + * do not ask the namespace callback for splitprovides when writing + a testcase + * fix add_complex_recommends() selecting conflicted packages in + rare cases leading to crashes + * improve choicerule generation so that package updates are + prefered in more cases + * deal with missing repos in testcase_mangle_repo_names + Version 0.7.15 - selected bug fixes: * fix deduceq2addedmap clearing bits outside of the map diff --git a/VERSION.cmake b/VERSION.cmake index 5c9b9e6..c218401 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 "15") +SET(LIBSOLV_PATCH "16") diff --git a/ext/testcase.c b/ext/testcase.c index bbed5ab..0be7a21 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -1711,7 +1711,7 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha for (rid = 1; rid < pool->nrels; rid++) { Reldep *rd = pool->rels + rid; - if (rd->flags != REL_NAMESPACE || rd->name == NAMESPACE_OTHERPROVIDERS) + if (rd->flags != REL_NAMESPACE || rd->name == NAMESPACE_OTHERPROVIDERS || rd->name == NAMESPACE_SPLITPROVIDES) continue; /* evaluate all namespace ids, skip empty results */ d = pool_whatprovides(pool, MAKERELDEP(rid)); @@ -1826,14 +1826,12 @@ testcase_mangle_repo_names(Pool *pool) for (mp = buf; *mp; mp++) if (*mp == ' ' || *mp == '\t' || *mp == '/') *mp = '_'; - for (;;) - { - for (i = 1; i < repoid; i++) - if (!strcmp(buf, names[i])) - break; - if (i == repoid) - break; + for (i = 1; i < repoid; i++) + { + if (!names[i] || strcmp(buf, names[i]) != 0) + continue; sprintf(mp, "_%d", mangle++); + i = 0; /* restart conflict check */ } names[repoid] = buf; } diff --git a/package/libsolv.changes b/package/libsolv.changes index 900490d..2f4bfe3 100644 --- a/package/libsolv.changes +++ b/package/libsolv.changes @@ -1,4 +1,21 @@ ------------------------------------------------------------------- +Tue Oct 20 12:04:00 CEST 2020 - mls@suse.de + +- do not ask the namespace callback for splitprovides when writing + a testcase +- fix add_complex_recommends() selecting conflicted packages in + rare cases leading to crashes +- improve choicerule generation so that package updates are + prefered in more cases +- bump version to 0.7.16 + +------------------------------------------------------------------- +Mon Oct 5 13:06:44 CEST 2020 - mls@suse.de + +- make testcase_mangle_repo_names deal correctly with freed repos + [bnc#1177238] + +------------------------------------------------------------------- Fri Sep 11 12:31:27 CEST 2020 - mls@suse.de - fix deduceq2addedmap clearing bits outside of the map diff --git a/src/rules.c b/src/rules.c index ffa2988..6c8e82b 100644 --- a/src/rules.c +++ b/src/rules.c @@ -3187,6 +3187,44 @@ 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 0; + 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 inline void queue_removeelement(Queue *q, Id el) { @@ -3203,20 +3241,62 @@ queue_removeelement(Queue *q, Id el) } } +static Id +choicerule_find_installed(Pool *pool, Id p) +{ + Solvable *s = pool->solvables + p; + Id p2, pp2; + + if (!s->repo) + return 0; + if (s->repo == pool->installed) + return p; + FOR_PROVIDES(p2, pp2, s->name) + { + Solvable *s2 = pool->solvables + p2; + if (s2->repo != pool->installed) + continue; + if (!pool->implicitobsoleteusesprovides && s->name != s2->name) + continue; + if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2)) + continue; + return p2; + } + if (s->obsoletes) + { + Id obs, *obsp = s->repo->idarraydata + s->obsoletes; + while ((obs = *obsp++) != 0) + { + FOR_PROVIDES(p2, pp2, obs) + { + Solvable *s2 = pool->solvables + p2; + if (s2->repo != pool->installed) + continue; + if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs)) + continue; + if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) + continue; + return p2; + } + } + } + return 0; +} + void solver_addchoicerules(Solver *solv) { Pool *pool = solv->pool; Map m, mneg; Rule *r; - Queue q, qi, qcheck, infoq; + Queue q, qi, qcheck, qcheck2, infoq; int i, j, rid, havechoice, negcnt; - Id p, d, pp; - Id p2, pp2; - Solvable *s, *s2; + Id p, d, pp, p2; + Solvable *s; Id lastaddedp, lastaddedd; int lastaddedcnt; unsigned int now; + int isnewest = 0; solv->choicerules = solv->nrules; if (!pool->installed) @@ -3229,6 +3309,7 @@ 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); @@ -3260,80 +3341,28 @@ solver_addchoicerules(Solver *solv) continue; if (s->repo == pool->installed) { + queue_push2(&qi, p, p); queue_push(&q, p); continue; } - /* check if this package is "blocked" by a installed package */ - s2 = 0; - FOR_PROVIDES(p2, pp2, s->name) - { - s2 = pool->solvables + p2; - if (s2->repo != pool->installed) - continue; - if (!pool->implicitobsoleteusesprovides && s->name != s2->name) - continue; - if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2)) - continue; - break; - } + /* find an installed package p2 that we can update/downgrade to p */ + p2 = choicerule_find_installed(pool, p); if (p2) { - /* found installed package p2 that we can update to p */ if (MAPTST(&mneg, p)) continue; - if (policy_is_illegal(solv, s2, s, 0)) - continue; -#if 0 - if (solver_choicerulecheck(solv, p2, r, &m)) + if (policy_is_illegal(solv, pool->solvables + p2, s, 0)) continue; - queue_push(&qi, p2); -#else queue_push2(&qi, p2, p); -#endif queue_push(&q, p); continue; } - if (s->obsoletes) - { - Id obs, *obsp = s->repo->idarraydata + s->obsoletes; - s2 = 0; - while ((obs = *obsp++) != 0) - { - FOR_PROVIDES(p2, pp2, obs) - { - s2 = pool->solvables + p2; - if (s2->repo != pool->installed) - continue; - if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs)) - continue; - if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) - continue; - break; - } - if (p2) - break; - } - if (obs) - { - /* found installed package p2 that we can update to p */ - if (MAPTST(&mneg, p)) - continue; - if (policy_is_illegal(solv, s2, s, 0)) - continue; -#if 0 - if (solver_choicerulecheck(solv, p2, r, &m)) - continue; - queue_push(&qi, p2); -#else - queue_push2(&qi, p2, p); -#endif - queue_push(&q, p); - continue; - } - } /* package p is independent of the installed ones */ havechoice = 1; } +#if 0 + printf("havechoice: %d qcount %d qicount %d\n", havechoice, q.count, qi.count); +#endif if (!havechoice || !q.count || !qi.count) continue; /* no choice */ @@ -3341,13 +3370,25 @@ solver_addchoicerules(Solver *solv) 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; + } + } /* do extra checking */ for (i = j = 0; i < qi.count; i += 2) { p2 = qi.elements[i]; if (!p2) continue; - if (solver_choicerulecheck(solv, p2, r, &m, &qcheck)) + if (isnewest && solver_choicerulecheck(solv, p2, r, &m, &qcheck)) { /* oops, remove element p from q */ queue_removeelement(&q, qi.elements[i + 1]); @@ -3441,6 +3482,7 @@ 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 686a8af..9c02cc7 100644 --- a/src/solver.c +++ b/src/solver.c @@ -1198,7 +1198,7 @@ createbranch(Solver *solv, int level, Queue *dq, Id p, Id data) int i; IF_POOLDEBUG (SOLV_DEBUG_POLICY) { - POOL_DEBUG (SOLV_DEBUG_POLICY, "creating a branch:\n"); + POOL_DEBUG (SOLV_DEBUG_POLICY, "creating a branch [data=%d]:\n", data); for (i = 0; i < dq->count; i++) POOL_DEBUG (SOLV_DEBUG_POLICY, " - %s\n", pool_solvid2str(pool, dq->elements[i])); } @@ -1218,7 +1218,7 @@ takebranch(Solver *solv, int pos, int end, const char *msg, int disablerules) #if 0 { int i; - printf("branch group level %d [%d-%d] %d %d:\n", solv->branches.elements[end - 1], start, end, solv->branches.elements[end - 4], solv->branches.elements[end - 3]); + printf("branch group level %d [%d-%d] %d %d:\n", solv->branches.elements[end - 1], end - solv->branches.elements[end - 2], end, solv->branches.elements[end - 4], solv->branches.elements[end - 3]); for (i = end - solv->branches.elements[end - 2]; i < end - 4; i++) printf("%c %c%s\n", i == pos ? 'x' : ' ', solv->branches.elements[i] >= 0 ? ' ' : '-', pool_solvid2str(pool, solv->branches.elements[i] >= 0 ? solv->branches.elements[i] : -solv->branches.elements[i])); } @@ -2089,6 +2089,8 @@ add_complex_recommends(Solver *solv, Id rec, Queue *dq, Map *dqmap) queue_truncate(dq, blkcnt); break; } + if (solv->decisionmap[p] < 0) + continue; if (dqmap) { if (!MAPTST(dqmap, p)) @@ -2096,8 +2098,6 @@ add_complex_recommends(Solver *solv, Id rec, Queue *dq, Map *dqmap) } else { - if (solv->decisionmap[p] < 0) - continue; if (solv->process_orphans && solv->installed && pool->solvables[p].repo == solv->installed && (solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, p - solv->installed->start)))) continue; } diff --git a/test/testcases/choicerules/choice2.t b/test/testcases/choicerules/choice2.t new file mode 100644 index 0000000..7c78fc6 --- /dev/null +++ b/test/testcases/choicerules/choice2.t @@ -0,0 +1,23 @@ +repo system 0 testtags <inline> +#>=Pkg: A 1 1 noarch +#>=Req: P = 1 +#>=Pkg: B 1 1 noarch +#>=Prv: P = 1 +repo available 0 testtags <inline> +#>=Pkg: A 2 1 noarch +#>=Req: P = 2 +#>=Pkg: A 2 2 noarch +#>=Req: P = 2 +#>=Pkg: B 2 1 noarch +#>=Prv: P = 2 +#>=Pkg: C 1 1 noarch +#>=Prv: P = 1 +#>=Pkg: C 2 1 noarch +#>=Prv: P = 2 +system i686 rpm system + +job update name B +result transaction,problems <inline> +result transaction,problems <inline> +#>upgrade A-1-1.noarch@system A-2-2.noarch@available +#>upgrade B-1-1.noarch@system B-2-1.noarch@available |