diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cleandeps.c | 2 | ||||
-rw-r--r-- | src/policy.c | 14 | ||||
-rw-r--r-- | src/pool.c | 3 | ||||
-rw-r--r-- | src/pool.h | 1 | ||||
-rw-r--r-- | src/problems.c | 17 | ||||
-rw-r--r-- | src/rules.c | 32 | ||||
-rw-r--r-- | src/selection.c | 2 | ||||
-rw-r--r-- | src/solver.c | 109 | ||||
-rw-r--r-- | src/strpool.c | 6 |
9 files changed, 156 insertions, 30 deletions
diff --git a/src/cleandeps.c b/src/cleandeps.c index 1da28f6..ef9a528 100644 --- a/src/cleandeps.c +++ b/src/cleandeps.c @@ -837,7 +837,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) if (MAPTST(&solv->multiversion, p)) break; if (p) - continue; + continue; /* found a multiversion package that will not obsolate anything */ } om.size = 0; diff --git a/src/policy.c b/src/policy.c index a38dea0..e1682f2 100644 --- a/src/policy.c +++ b/src/policy.c @@ -866,6 +866,8 @@ move_installed_to_front(Pool *pool, Queue *plist) Solvable *s; Id p, pp; + if (!pool->installed) + return; for (i = j = 0; i < plist->count; i++) { s = pool->solvables + plist->elements[i]; @@ -924,9 +926,9 @@ prune_to_best_version(Pool *pool, Queue *plist) { s = pool->solvables + plist->elements[i]; - POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s[%s]\n", - pool_solvable2str(pool, s), - (pool->installed && s->repo == pool->installed) ? "installed" : "not installed"); + POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s [%d]%s\n", + pool_solvable2str(pool, s), plist->elements[i], + (pool->installed && s->repo == pool->installed) ? "I" : ""); if (!best) /* if no best yet, the current is best */ { @@ -961,8 +963,6 @@ prune_to_best_version(Pool *pool, Queue *plist) else prune_obsoleted(pool, plist); } - if (plist->count > 1 && pool->installed) - move_installed_to_front(pool, plist); } @@ -1236,7 +1236,7 @@ urpm_reorder(Solver *solv, Queue *plist) { char kn[256]; Id p, pp, knid; - memcpy(kn, "kernel", 8); + memcpy(kn, "kernel", 7); memcpy(kn + 6, flavor, release - flavor + 1); memcpy(kn + 6 + (release - flavor) + 1, sn, flavor - sn); strcpy(kn + 6 + (release + 1 - sn), release); @@ -1343,6 +1343,7 @@ policy_filter_unwanted(Solver *solv, Queue *plist, int mode) #endif dislike_old_versions(pool, plist); sort_by_common_dep(pool, plist); + move_installed_to_front(pool, plist); if (solv->urpmreorder) urpm_reorder(solv, plist); prefer_suggested(solv, plist); @@ -1364,6 +1365,7 @@ pool_best_solvables(Pool *pool, Queue *plist, int flags) { dislike_old_versions(pool, plist); sort_by_common_dep(pool, plist); + move_installed_to_front(pool, plist); } } @@ -1505,6 +1505,7 @@ pool_debug(Pool *pool, int type, const char *format, ...) vprintf(format, args); else vfprintf(stderr, format, args); + va_end(args); return; } vsnprintf(buf, sizeof(buf), format, args); @@ -1566,7 +1567,7 @@ pool_setdebuglevel(Pool *pool, int level) if (level > 2) mask |= SOLV_DEBUG_PROPAGATE; if (level > 3) - mask |= SOLV_DEBUG_RULE_CREATION; + mask |= SOLV_DEBUG_RULE_CREATION | SOLV_DEBUG_WATCHES; mask |= pool->debugmask & SOLV_DEBUG_TO_STDERR; /* keep bit */ pool->debugmask = mask; } @@ -188,6 +188,7 @@ struct _Pool { #define SOLV_DEBUG_JOB (1<<11) #define SOLV_DEBUG_SOLVER (1<<12) #define SOLV_DEBUG_TRANSACTION (1<<13) +#define SOLV_DEBUG_WATCHES (1<<14) #define SOLV_DEBUG_TO_STDERR (1<<30) diff --git a/src/problems.c b/src/problems.c index df751c4..2b5cefd 100644 --- a/src/problems.c +++ b/src/problems.c @@ -247,8 +247,23 @@ solver_autouninstall(Solver *solv, int start) if (v >= solv->updaterules && v < solv->updaterules_end) { Rule *r; + Id p = solv->installed->start + (v - solv->updaterules); if (m && !MAPTST(m, v - solv->updaterules)) continue; + if (pool->considered && !MAPTST(pool->considered, p)) + continue; /* do not uninstalled disabled packages */ + if (solv->bestrules_pkg && solv->bestrules_end > solv->bestrules) + { + int j; + for (j = start + 1; j < solv->problems.count - 1; j++) + { + Id vv = solv->problems.elements[j]; + if (vv >= solv->bestrules && vv < solv->bestrules_end && solv->bestrules_pkg[vv - solv->bestrules] == p) + break; + } + if (j < solv->problems.count - 1) + continue; /* best rule involved, do not uninstall */ + } /* check if identical to feature rule, we don't like that (except for orphans) */ r = solv->rules + solv->featurerules + (v - solv->updaterules); if (!r->p) @@ -260,7 +275,7 @@ solver_autouninstall(Solver *solv, int start) if (solv->keep_orphans) { r = solv->rules + v; - if (!r->d && !r->w2 && r->p == (solv->installed->start + (v - solv->updaterules))) + if (!r->d && !r->w2 && r->p == p) { lastfeature = v; lastupdate = 0; diff --git a/src/rules.c b/src/rules.c index df32341..5901145 100644 --- a/src/rules.c +++ b/src/rules.c @@ -1328,6 +1328,31 @@ solver_addfeaturerule(Solver *solv, Solvable *s) } } +/* check if multiversion solvable s2 has an obsoletes for installed solvable s */ +static int +is_multiversion_obsoleteed(Pool *pool, Solvable *s, Solvable *s2) +{ + Id *wp, obs, *obsp; + + if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) + return 0; + obsp = s2->repo->idarraydata + s2->obsoletes; + if (!pool->obsoleteusesprovides) + { + while ((obs = *obsp++) != 0) + if (pool_match_nevr(pool, s, obs)) + return 1; + } + else + { + while ((obs = *obsp++) != 0) + for (wp = pool_whatprovides_ptr(pool, obs); *wp; wp++) + if (pool->solvables + *wp == s) + return 1; + } + return 0; +} + /*------------------------------------------------------------------- * * add rule for update @@ -1389,9 +1414,8 @@ solver_addupdaterule(Solver *solv, Solvable *s) if (MAPTST(&solv->multiversion, qs.elements[i])) { Solvable *ps = pool->solvables + qs.elements[i]; - /* if keepexplicitobsoletes is set and the name is different, - * we assume that there is an obsoletes. XXX: not 100% correct */ - if (solv->keepexplicitobsoletes && ps->name != s->name) + /* check if there is an explicit obsoletes */ + if (solv->keepexplicitobsoletes && ps->obsoletes && is_multiversion_obsoleteed(pool, s, ps)) { qs.elements[j++] = qs.elements[i]; continue; @@ -2175,7 +2199,7 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) if (pool->solvables[p].repo == installed) return; if (solv->multiversion.size && MAPTST(&solv->multiversion, p) && !solv->keepexplicitobsoletes) - return; + return; /* will not obsolete anything, so just return */ } omap.size = 0; qstart = q->count; diff --git a/src/selection.c b/src/selection.c index d44c482..0b36ea8 100644 --- a/src/selection.c +++ b/src/selection.c @@ -1468,7 +1468,7 @@ selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char revr = pool_str2id(pool, r, 1); ret |= SELECTION_REL; } - if ((flags & SELECTION_GLOB) != 0 && !strpbrk(rname, "[*?") != 0) + if ((flags & SELECTION_GLOB) != 0 && strpbrk(rname, "[*?") == 0) flags &= ~SELECTION_GLOB; if ((flags & SELECTION_GLOB) == 0 && (flags & SELECTION_NOCASE) == 0 && (flags & SELECTION_MATCH_DEPSTR) == 0) diff --git a/src/solver.c b/src/solver.c index 6405f4a..102d814 100644 --- a/src/solver.c +++ b/src/solver.c @@ -431,7 +431,7 @@ propagate(Solver *solv, int level) Id *decisionmap = solv->decisionmap; Id *watches = solv->watches + pool->nsolvables; /* place ptr in middle */ - POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate -----\n"); + POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate level %d -----\n", level); /* foreach non-propagated decision */ while (solv->propagate_index < solv->decisionq.count) @@ -444,7 +444,7 @@ propagate(Solver *solv, int level) IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE) { - POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate for decision %d level %d\n", -pkg, level); + POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate decision %d:", -pkg); solver_printruleelement(solv, SOLV_DEBUG_PROPAGATE, 0, -pkg); } @@ -462,10 +462,10 @@ propagate(Solver *solv, int level) continue; } - IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE) + IF_POOLDEBUG (SOLV_DEBUG_WATCHES) { - POOL_DEBUG(SOLV_DEBUG_PROPAGATE," watch triggered "); - solver_printrule(solv, SOLV_DEBUG_PROPAGATE, r); + POOL_DEBUG(SOLV_DEBUG_WATCHES, " watch triggered "); + solver_printrule(solv, SOLV_DEBUG_WATCHES, r); } /* @@ -532,12 +532,12 @@ propagate(Solver *solv, int level) * if we found some p that is UNDEF or TRUE, move * watch to it */ - IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE) + IF_POOLDEBUG (SOLV_DEBUG_WATCHES) { if (p > 0) - POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p)); + POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p)); else - POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p)); + POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p)); } *rp = *next_rp; @@ -593,7 +593,7 @@ propagate(Solver *solv, int level) } /* while we have non-decided decisions */ - POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end-----\n"); + POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end -----\n"); return 0; /* all is well */ } @@ -1790,6 +1790,69 @@ resolve_installed(Solver *solv, int level, int disablerules, Queue *dq) return level; } +/* one or more installed cleandeps packages in dq that are to be updated */ +/* we need to emulate the code in resolve_installed */ +static void +do_cleandeps_update_filter(Solver *solv, Queue *dq) +{ + Pool *pool = solv->pool; + Repo *installed = solv->installed; + Id *specialupdaters = solv->specialupdaters; + Id p, p2, pp, d; + Queue q; + int i, j, k; + + queue_init(&q); + for (i = 0; i < dq->count; i++) + { + Id p = dq->elements[i]; + if (p < 0) + p = -p; + if (pool->solvables[p].repo != installed || !MAPTST(&solv->cleandepsmap, p - installed->start)) + continue; + queue_empty(&q); + /* find updaters */ + if (specialupdaters && (d = specialupdaters[p - installed->start]) != 0) + { + while ((p2 = pool->whatprovidesdata[d++]) != 0) + if (solv->decisionmap[p2] >= 0) + queue_push(&q, p2); + } + else + { + Rule *r = solv->rules + solv->updaterules + (p - installed->start); + if (r->p) + { + FOR_RULELITERALS(p2, pp, r) + if (solv->decisionmap[p2] >= 0) + queue_push(&q, p2); + } + } + if (q.count && solv->update_targets && solv->update_targets->elements[p - installed->start]) + prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q); + /* mark all elements in dq that are in the updaters list */ + dq->elements[i] = -p; + for (j = 0; j < dq->count; j++) + { + p = dq->elements[j]; + if (p < 0) + continue; + for (k = 0; k < q.count; k++) + if (q.elements[k] == p) + { + dq->elements[j] = -p; + break; + } + } + } + /* now prune to marked elements */ + for (i = j = 0; i < dq->count; i++) + if ((p = dq->elements[i]) < 0) + dq->elements[j++] = -p; + dq->count = j; + queue_free(&q); +} + static int resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq) { @@ -1817,6 +1880,8 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq) } if (i == solv->nrules) i = 1; + if (solv->focus_best && solv->do_extra_reordering && i >= solv->featurerules) + continue; r = solv->rules + i; if (r->d < 0) /* ignore disabled rules */ continue; @@ -1885,15 +1950,25 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq) /* prune to cleandeps packages */ if (solv->cleandepsmap.size && solv->installed) { + int cleandeps_update = 0; Repo *installed = solv->installed; for (j = 0; j < dq->count; j++) if (pool->solvables[dq->elements[j]].repo == installed && MAPTST(&solv->cleandepsmap, dq->elements[j] - installed->start)) - break; + { + if (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, dq->elements[j] - installed->start))) + { + cleandeps_update = 1; /* cleandeps package is marked for update */ + continue; + } + break; + } if (j < dq->count) { dq->elements[0] = dq->elements[j]; queue_truncate(dq, 1); } + else if (cleandeps_update) + do_cleandeps_update_filter(solv, dq); /* special update filter */ } if (dq->count > 1 && postponed >= 0) @@ -3233,6 +3308,7 @@ solver_solve(Solver *solv, Queue *job) POOL_DEBUG(SOLV_DEBUG_STATS, "solver started\n"); POOL_DEBUG(SOLV_DEBUG_STATS, "dosplitprovides=%d, noupdateprovide=%d, noinfarchcheck=%d\n", solv->dosplitprovides, solv->noupdateprovide, solv->noinfarchcheck); POOL_DEBUG(SOLV_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allownamechange=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allownamechange, solv->allowarchchange, solv->allowvendorchange); + POOL_DEBUG(SOLV_DEBUG_STATS, "dupallowdowngrade=%d, dupallownamechange=%d, dupallowarchchange=%d, dupallowvendorchange=%d\n", solv->dup_allowdowngrade, solv->dup_allownamechange, solv->dup_allowarchchange, solv->dup_allowvendorchange); POOL_DEBUG(SOLV_DEBUG_STATS, "promoteepoch=%d, forbidselfconflicts=%d\n", pool->promoteepoch, pool->forbidselfconflicts); POOL_DEBUG(SOLV_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d, obsoleteusescolors=%d, implicitobsoleteusescolors=%d\n", pool->obsoleteusesprovides, pool->implicitobsoleteusesprovides, pool->obsoleteusescolors, pool->implicitobsoleteusescolors); POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, addalreadyrecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended); @@ -3736,6 +3812,10 @@ solver_solve(Solver *solv, Queue *job) name_s = s; } solver_addjobrule(solv, -p, 0, 0, i, weak); +#ifdef ENABLE_LINKED_PKGS + if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1) + solver_addjobrule(solv, -solv->instbuddy[p - installed->start], 0, 0, i, weak); +#endif } /* special case for "erase a specific solvable": we also * erase all other solvables with that name, so that they @@ -3803,7 +3883,14 @@ solver_solve(Solver *solv, Queue *job) } } FOR_JOB_SELECT(p, pp, select, what) - solver_addjobrule(solv, installed && pool->solvables[p].repo == installed ? p : -p, 0, 0, i, weak); + { + s = pool->solvables + p; + solver_addjobrule(solv, installed && s->repo == installed ? p : -p, 0, 0, i, weak); +#ifdef ENABLE_LINKED_PKGS + if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1) + solver_addjobrule(solv, solv->instbuddy[p - installed->start], 0, 0, i, weak); +#endif + } break; case SOLVER_DISTUPGRADE: POOL_DEBUG(SOLV_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(pool, select, what)); diff --git a/src/strpool.c b/src/strpool.c index 5e87918..b4a09a5 100644 --- a/src/strpool.c +++ b/src/strpool.c @@ -56,11 +56,7 @@ stringpool_freehash(Stringpool *ss) void stringpool_init_empty(Stringpool *ss) { - const char *emptystrs[] = { - "<NULL>", - "", - 0, - }; + static const char *emptystrs[] = { "<NULL>", "", 0 }; stringpool_init(ss, emptystrs); } |