From: Michael Schroeder Date: Wed, 18 Oct 2017 10:52:41 +0000 (+0200) Subject: Always create dup rules for distupgrade jobs X-Git-Tag: 0.6.30~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d625aa6379b657ccae3b8bd7bd1b11993834293;p=thirdparty%2Flibsolv.git Always create dup rules for distupgrade jobs We used to use update rules for "distupgrade all packages". This is a tiny bit faster and needs less memory, but the downside is that for problems there only is the "get rid of the update rule" solution, but not the "disable dup mode for this package" solution. So simplify things by always creating dup rules for dup mode. --- diff --git a/TODO_1.0 b/TODO_1.0 index cb5055d2..6ecb8629 100644 --- a/TODO_1.0 +++ b/TODO_1.0 @@ -23,8 +23,6 @@ - write more manpages -- use dup rules all the time - - bindings: selections.flags() should be a attribute and not a method - rename repodata_lookup_id_uninternalized to repodata_lookup_id_voidid_uninternalized diff --git a/src/policy.c b/src/policy.c index 468be67c..20bd3d54 100644 --- a/src/policy.c +++ b/src/policy.c @@ -145,7 +145,7 @@ solver_prune_installed_dup_packages(Solver *solv, Queue *plist) Solvable *s = pool->solvables + p; if (s->repo != pool->installed && s->repo->priority < bestprio) continue; - if (s->repo == pool->installed && (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)))) + if (s->repo == pool->installed && (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)))) { Id p2, pp2; int keepit = 0; @@ -181,7 +181,7 @@ static inline void solver_prune_to_highest_prio(Solver *solv, Queue *plist) { prune_to_highest_prio(solv->pool, plist); - if (plist->count > 1 && solv->pool->installed && (solv->dupmap_all || solv->dupinvolvedmap.size)) + if (plist->count > 1 && solv->pool->installed && (solv->dupinvolvedmap_all || solv->dupinvolvedmap.size)) solver_prune_installed_dup_packages(solv, plist); } diff --git a/src/rules.c b/src/rules.c index c108de77..967d81cf 100644 --- a/src/rules.c +++ b/src/rules.c @@ -1347,7 +1347,7 @@ solver_addfeaturerule(Solver *solv, Solvable *s) queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf)); p = s - pool->solvables; policy_findupdatepackages(solv, s, &qs, 1); - if (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) + if (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) { if (!dup_maykeepinstalled(solv, s)) { @@ -1421,8 +1421,12 @@ solver_addupdaterule(Solver *solv, Solvable *s) queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf)); /* find update candidates for 's' */ - if (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) - p = finddistupgradepackages(solv, s, &qs); + if (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) + { + policy_findupdatepackages(solv, s, &qs, 2); + if (!dup_maykeepinstalled(solv, s)) + p = -SYSTEMSOLVABLE; + } else policy_findupdatepackages(solv, s, &qs, 0); @@ -1489,6 +1493,9 @@ solver_addupdaterule(Solver *solv, Solvable *s) } } } + else if (p == -SYSTEMSOLVABLE && solv->dupmap.size) + p = s - pool->solvables; /* let the dup rules sort it out */ + if (!isorphaned && p == -SYSTEMSOLVABLE && qs.count && solv->dupmap.size) p = s - pool->solvables; /* let the dup rules sort it out */ if (qs.count && p == -SYSTEMSOLVABLE) @@ -1619,9 +1626,10 @@ solver_addinfarchrules(Solver *solv, Map *addedmap) a = (a <= pool->lastarch) ? pool->id2arch[a] : 0; if (a != 1 && installed && ps->repo == installed) { - if (!solv->dupmap_all && !(solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) - queue_pushunique(&allowedarchs, ps->arch); /* also ok to keep this architecture */ - continue; /* ignore installed solvables when calculating the best arch */ + if (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) + continue; + queue_pushunique(&allowedarchs, ps->arch); /* also ok to keep this architecture */ + continue; /* but ignore installed solvables when calculating the best arch */ } if (a && a != 1 && (!bestarch || a < bestarch)) { @@ -1647,7 +1655,7 @@ solver_addinfarchrules(Solver *solv, Map *addedmap) ps = pool->solvables + p; if (ps->name != s->name || ps->repo != installed || !MAPTST(addedmap, p)) continue; - if (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) + if (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) continue; a = ps->arch; a = (a <= pool->lastarch) ? pool->id2arch[a] : 0; @@ -1807,6 +1815,9 @@ solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted) Repo *installed = solv->installed; Id pi, pip, obs, *obsp; + if (!solv->dupinvolvedmap.size) + map_grow(&solv->dupinvolvedmap, pool->nsolvables); + MAPSET(&solv->dupinvolvedmap, p); if (targeted) MAPSET(&solv->dupmap, p); @@ -1881,6 +1892,10 @@ solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted) } } +/* create the two dupmaps: + * - dupmap: packages in that map are good to install/keep + * - dupinvolvedmap: packages are subject to dup mode + */ void solver_createdupmaps(Solver *solv) { @@ -1892,7 +1907,8 @@ solver_createdupmaps(Solver *solv) int i, targeted; map_init(&solv->dupmap, pool->nsolvables); - map_init(&solv->dupinvolvedmap, pool->nsolvables); + solv->dupinvolvedmap_all = 0; + map_init(&solv->dupinvolvedmap, 0); for (i = 0; i < job->count; i += 2) { how = job->elements[i]; @@ -1921,12 +1937,15 @@ solver_createdupmaps(Solver *solv) } else if (select == SOLVER_SOLVABLE_ALL) { + solv->dupinvolvedmap_all = 1; FOR_POOL_SOLVABLES(p) { - MAPSET(&solv->dupinvolvedmap, p); if (installed && pool->solvables[p].repo != installed) MAPSET(&solv->dupmap, p); } + solv->updatemap_all = 1; + if (how & SOLVER_FORCEBEST) + solv->bestupdatemap_all = 1; } else { @@ -1957,7 +1976,8 @@ solver_createdupmaps(Solver *solv) break; } } - MAPCLR(&solv->dupinvolvedmap, SYSTEMSOLVABLE); + if (solv->dupinvolvedmap.size) + MAPCLR(&solv->dupinvolvedmap, SYSTEMSOLVABLE); } void @@ -1994,7 +2014,7 @@ solver_addduprules(Solver *solv, Map *addedmap) first = 0; if (first) break; - if (!MAPTST(&solv->dupinvolvedmap, p)) + if (!solv->dupinvolvedmap_all && !MAPTST(&solv->dupinvolvedmap, p)) continue; if (installed && ps->repo == installed) { @@ -2015,24 +2035,35 @@ solver_addduprules(Solver *solv, Map *addedmap) } if (ip) { - /* ok, found a good one. we may keep this package. */ + /* ok, identical to a good one. we may keep this package. */ MAPSET(&solv->dupmap, p); /* for best rules processing */ continue; } + /* check if it's orphaned. If yes, we may keep it */ r = solv->rules + solv->updaterules + (p - installed->start); if (!r->p) - r = solv->rules + solv->featurerules + (p - installed->start); - if (r->p && solv->specialupdaters && solv->specialupdaters[p - installed->start]) + r = solv->rules + solv->featurerules + (p - installed->start); + if (!r->p) + { + /* no update/feature rule, this is an orphan */ + MAPSET(&solv->dupmap, p); /* for best rules processing */ + continue; + } + if (solv->specialupdaters && solv->specialupdaters[p - installed->start]) { /* this is a multiversion orphan, we're good if an update is installed */ solver_addrule(solv, -p, 0, solv->specialupdaters[p - installed->start]); continue; } - if (!r->p || (r->p == p && !r->d && !r->w2)) + if (r->p == p && !r->d && !r->w2) { - /* this is an orphan */ - MAPSET(&solv->dupmap, p); /* for best rules processing */ - continue; + r = solv->rules + solv->featurerules + (p - installed->start); + if (!r->p || (!r->d && !r->w2)) + { + /* this is an orphan */ + MAPSET(&solv->dupmap, p); /* for best rules processing */ + continue; + } } solver_addrule(solv, -p, 0, 0); /* no match, sorry */ } diff --git a/src/solver.c b/src/solver.c index 7e83deb0..71b6ae00 100644 --- a/src/solver.c +++ b/src/solver.c @@ -259,6 +259,10 @@ makeruledecisions(Solver *solv) continue; } + POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "ANALYZE UNSOLVABLE ASSERTION ----------------------\n"); + IF_POOLDEBUG (SOLV_DEBUG_UNSOLVABLE) + solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + ri); + /* * find the decision which is the "opposite" of the rule */ @@ -304,6 +308,8 @@ makeruledecisions(Solver *solv) } assert(solv->decisionq_why.elements[i] > 0); + IF_POOLDEBUG (SOLV_DEBUG_UNSOLVABLE) + solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + solv->decisionq_why.elements[i]); /* * conflict with a pkg rule ? @@ -3647,17 +3653,8 @@ solver_solve(Solver *solv, Queue *job) } break; case SOLVER_DISTUPGRADE: - if (select == SOLVER_SOLVABLE_ALL) - { - solv->dupmap_all = 1; - solv->updatemap_all = 1; - if (how & SOLVER_FORCEBEST) - solv->bestupdatemap_all = 1; - } - if ((how & SOLVER_TARGETED) != 0) - needduprules = 1; - if (!solv->dupmap_all || solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size || solv->keep_orphans) - needduprules = 1; + needduprules = 1; + solv->dupmap_all = 1; break; default: break; @@ -4038,7 +4035,7 @@ solver_solve(Solver *solv, Queue *job) else solv->infarchrules = solv->infarchrules_end = solv->nrules; - if (needduprules) + if (solv->dupinvolvedmap_all || solv->dupinvolvedmap.size) solver_addduprules(solv, &addedmap); else solv->duprules = solv->duprules_end = solv->nrules; diff --git a/src/solver.h b/src/solver.h index 464d7e6c..9d2a7d54 100644 --- a/src/solver.h +++ b/src/solver.h @@ -167,9 +167,10 @@ struct _Solver { int strongrecommends; /* true: create weak rules for recommends */ int install_also_updates; /* true: do not prune install job rules to installed packages */ - Map dupmap; /* dup these packages*/ - int dupmap_all; /* dup all packages */ + Map dupmap; /* dup to those packages */ + int dupmap_all; /* dup to all repo packages */ Map dupinvolvedmap; /* packages involved in dup process */ + int dupinvolvedmap_all; /* all packages are involved */ int dup_allowdowngrade; /* dup mode: allow to downgrade installed solvable */ int dup_allownamechange; /* dup mode: allow to change name of installed solvable */ int dup_allowarchchange; /* dup mode: allow to change architecture of installed solvables */