diff options
Diffstat (limited to 'src/solver.c')
-rw-r--r-- | src/solver.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/src/solver.c b/src/solver.c index c6cad6b..2e28b7d 100644 --- a/src/solver.c +++ b/src/solver.c @@ -217,13 +217,24 @@ autouninstall(Solver *solv, Id *problem) Rule *r; if (m && !MAPTST(m, v - solv->updaterules)) continue; - /* check if identical to feature rule, we don't like that */ + /* 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) { /* update rule == feature rule */ if (v > lastfeature) lastfeature = v; + /* prefer orphaned packages in dup mode */ + if (solv->keep_orphans) + { + r = solv->rules + v; + if (!r->d && r->p == (solv->installed->start + (v - solv->updaterules))) + { + lastfeature = v; + lastupdate = 0; + break; + } + } continue; } if (v > lastupdate) @@ -2714,7 +2725,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) if (!solv->decisioncnt_orphan) solv->decisioncnt_orphan = solv->decisionq.count; - if (solv->dupmap_all && solv->installed) + if (solv->installed && (solv->orphaned.count || solv->brokenorphanrules)) { int installedone = 0; @@ -3350,7 +3361,7 @@ solver_solve(Solver *solv, Queue *job) Solvable *s; Rule *r; int now, solve_start; - int hasdupjob = 0; + int needduprules = 0; int hasbestinstalljob = 0; solve_start = solv_timems(0); @@ -3561,6 +3572,19 @@ solver_solve(Solver *solv, Queue *job) MAPSET(&solv->droporphanedmap, p - installed->start); } break; + case SOLVER_ALLOWUNINSTALL: + if (select == SOLVER_SOLVABLE_ALL || (select == SOLVER_SOLVABLE_REPO && installed && what == installed->repoid)) + solv->allowuninstall_all = 1; + FOR_JOB_SELECT(p, pp, select, what) + { + s = pool->solvables + p; + if (s->repo != installed) + continue; + if (!solv->allowuninstallmap.size) + map_grow(&solv->allowuninstallmap, installed->end - installed->start); + MAPSET(&solv->allowuninstallmap, p - installed->start); + } + break; default: break; } @@ -3608,8 +3632,10 @@ solver_solve(Solver *solv, Queue *job) if (how & SOLVER_FORCEBEST) solv->bestupdatemap_all = 1; } - if (!solv->dupmap_all || solv->allowuninstall) - hasdupjob = 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; break; default: break; @@ -3664,7 +3690,7 @@ solver_solve(Solver *solv, Queue *job) /* create dup maps if needed. We need the maps early to create our * update rules */ - if (hasdupjob) + if (needduprules) solver_createdupmaps(solv); /* @@ -3723,9 +3749,13 @@ solver_solve(Solver *solv, Queue *job) * check for and remove duplicate */ r = solv->rules + solv->nrules - 1; /* r: update rule */ - if (!r->p) - continue; sr = r - (installed->end - installed->start); /* sr: feature rule */ + if (!r->p) + { + if (sr->p) + memset(sr, 0, sizeof(*sr)); /* no feature rules without update rules */ + continue; + } /* it's also orphaned if the feature rule consists just of the installed package */ if (!solv->dupmap_all && sr->p == i && !sr->d && !sr->w2) queue_push(&solv->orphaned, i); @@ -3917,17 +3947,6 @@ solver_solve(Solver *solv, Queue *job) break; case SOLVER_ALLOWUNINSTALL: POOL_DEBUG(SOLV_DEBUG_JOB, "job: allowuninstall %s\n", solver_select2str(pool, select, what)); - if (select == SOLVER_SOLVABLE_ALL || (select == SOLVER_SOLVABLE_REPO && installed && what == installed->repoid)) - solv->allowuninstall_all = 1; - FOR_JOB_SELECT(p, pp, select, what) - { - s = pool->solvables + p; - if (s->repo != installed) - continue; - if (!solv->allowuninstallmap.size) - map_grow(&solv->allowuninstallmap, installed->end - installed->start); - MAPSET(&solv->allowuninstallmap, p - installed->start); - } break; default: POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n"); @@ -3966,7 +3985,7 @@ solver_solve(Solver *solv, Queue *job) else solv->infarchrules = solv->infarchrules_end = solv->nrules; - if (hasdupjob) + if (needduprules) solver_addduprules(solv, &addedmap); else solv->duprules = solv->duprules_end = solv->nrules; @@ -3976,7 +3995,7 @@ solver_solve(Solver *solv, Queue *job) else solv->bestrules = solv->bestrules_end = solv->nrules; - if (hasdupjob) + if (needduprules) solver_freedupmaps(solv); /* no longer needed */ if (solv->do_yum_obsoletes) |