*/
static void
-findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, Id *jobrp, Id *blkrp, Map *rseen)
+findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, Id *jobrp, Id *blkrp, Id *scprp, Map *rseen)
{
Id rid, d;
- Id lreqr, lconr, lsysr, ljobr, lblkr;
+ Id lreqr, lconr, lsysr, ljobr, lblkr, lscpr;
Rule *r;
Id jobassert = 0;
int i, reqset = 0; /* 0: unset, 1: installed, 2: jobassert, 3: assert */
/* the problem rules are somewhat ordered from "near to the problem" to
* "near to the job" */
- lreqr = lconr = lsysr = ljobr = lblkr = 0;
+ lreqr = lconr = lsysr = ljobr = lblkr = lscpr = 0;
while ((rid = solv->learnt_pool.elements[idx++]) != 0)
{
assert(rid > 0);
if (MAPTST(rseen, rid - solv->learntrules))
continue;
MAPSET(rseen, rid - solv->learntrules);
- findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr, &lblkr, rseen);
+ findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr, &lblkr, &lscpr, rseen);
}
else if ((rid >= solv->jobrules && rid < solv->jobrules_end) || (rid >= solv->infarchrules && rid < solv->infarchrules_end) || (rid >= solv->duprules && rid < solv->duprules_end) || (rid >= solv->bestrules && rid < solv->bestrules_end) || (rid >= solv->yumobsrules && rid < solv->yumobsrules_end))
{
if (!*blkrp)
*blkrp = rid;
}
+ else if (rid >= solv->strictrepopriorules && rid < solv->strictrepopriorules_end)
+ {
+ if (!*scprp)
+ *scprp = rid;
+ }
else
{
assert(rid < solv->pkgrules_end);
*sysrp = lsysr;
if (!*blkrp && lblkr)
*blkrp = lblkr;
+ if (!*scprp && lscpr)
+ *scprp = lscpr;
}
/*
Id
solver_findproblemrule(Solver *solv, Id problem)
{
- Id reqr, conr, sysr, jobr, blkr;
+ Id reqr, conr, sysr, jobr, blkr, srpr;
Id idx = solv->problems.elements[2 * problem - 2];
Map rseen;
- reqr = conr = sysr = jobr = blkr = 0;
+ reqr = conr = sysr = jobr = blkr = srpr = 0;
map_init(&rseen, solv->learntrules ? solv->nrules - solv->learntrules : 0);
- findproblemrule_internal(solv, idx, &reqr, &conr, &sysr, &jobr, &blkr, &rseen);
+ findproblemrule_internal(solv, idx, &reqr, &conr, &sysr, &jobr, &blkr, &srpr, &rseen);
map_free(&rseen);
/* check if the request is about a not-installed package requiring a installed
* package conflicting with the non-installed package. In that case return the conflict */
return conr; /* some conflict */
if (blkr)
return blkr; /* a blacklisted package */
+ if (srpr)
+ return srpr; /* a strict repo priority */
if (sysr)
return sysr; /* an update rule */
if (jobr)
return pool_tmpappend(pool, s, pool_dep2str(pool, dep), 0);
case SOLVER_RULE_BLACK:
return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " can only be installed by a direct request");
+ case SOLVER_RULE_STRICT_REPO_PRIORITY:
+ return pool_tmpjoin(pool, "package '", pool_solvid2str(pool, source), "' is excluded by strict repo priority");
case SOLVER_RULE_PKG_CONSTRAINS:
s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0);
s = pool_tmpappend(pool, s, " has constraint ", pool_dep2str(pool, dep));
*fromp = -r->p;
return SOLVER_RULE_BLACK;
}
+ if (rid >= solv->strictrepopriorules && rid < solv->strictrepopriorules_end)
+ {
+ if (fromp)
+ *fromp = -r->p;
+ return SOLVER_RULE_STRICT_REPO_PRIORITY;
+ }
if (rid >= solv->choicerules && rid < solv->choicerules_end)
return SOLVER_RULE_CHOICE;
if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
return SOLVER_RULE_CHOICE;
if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
return SOLVER_RULE_RECOMMENDS;
- if (rid >= solv->blackrules && rid < solv->blackrules_end)
- return SOLVER_RULE_BLACK;
+ if (rid >= solv->strictrepopriorules && rid < solv->strictrepopriorules_end)
+ return SOLVER_RULE_STRICT_REPO_PRIORITY;
if (rid >= solv->learntrules && rid < solv->nrules)
return SOLVER_RULE_LEARNT;
return SOLVER_RULE_UNKNOWN;
solv->recommendsrules_end = solv->nrules;
}
+/* add rules to exclude solvables provided by lower
+ * precedence repositories */
+void solver_addstrictrepopriorules(struct s_Solver *solv, Map *addedmap)
+{
+ Pool *pool = solv->pool;
+ Solvable *s;
+ Id p, p2, pp2;
+ Map priomap;
+ int max_prio;
+
+ map_init_clone(&priomap, addedmap);
+ solv->strictrepopriorules = solv->nrules;
+
+ FOR_POOL_SOLVABLES(p)
+ {
+ if (!MAPTST(&priomap, p))
+ continue;
+
+ s = pool->solvables + p;
+ max_prio = s->repo->priority;
+ FOR_PROVIDES(p2, pp2, s->name)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (s->name != s2->name)
+ {
+ MAPCLR(&priomap, p2);
+ continue;
+ }
+ if (s2->repo->priority > max_prio)
+ max_prio = s2->repo->priority;
+ }
+
+ FOR_PROVIDES(p2, pp2, s->name)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (!MAPTST(&priomap, p2))
+ continue;
+ MAPCLR(&priomap, p2);
+ if (pool->installed && s2->repo == pool->installed)
+ continue;
+ if (s2->repo->priority < max_prio)
+ solver_addrule(solv, -p2, 0, 0);
+ }
+ }
+ solv->strictrepopriorules_end = solv->nrules;
+ map_free(&priomap);
+}
+
void
solver_breakorphans(Solver *solv)
{
SOLVER_RULE_BEST = 0x900,
SOLVER_RULE_YUMOBS = 0xa00,
SOLVER_RULE_RECOMMENDS = 0xb00,
- SOLVER_RULE_BLACK = 0xc00
+ SOLVER_RULE_BLACK = 0xc00,
+ SOLVER_RULE_STRICT_REPO_PRIORITY = 0xd00
} SolverRuleinfo;
#define SOLVER_RULE_TYPEMASK 0xff00
/* recommends rules */
extern void solver_addrecommendsrules(struct s_Solver *solv);
+/* channel priority rules */
+extern void solver_addstrictrepopriorules(struct s_Solver *solv, Map *addedmap);
+
/* policy rule disabling/reenabling */
extern void solver_disablepolicyrules(struct s_Solver *solv);
extern void solver_reenablepolicyrules(struct s_Solver *solv, int jobidx);
return solv->install_also_updates;
case SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED:
return solv->only_namespace_recommended;
+ case SOLVER_FLAG_STRICT_REPO_PRIORITY:
+ return solv->strict_repo_priority;
default:
break;
}
case SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED:
solv->only_namespace_recommended = value;
break;
+ case SOLVER_FLAG_STRICT_REPO_PRIORITY:
+ solv->strict_repo_priority = value;
+ break;
default:
break;
}
else
solv->recommendsrules = solv->recommendsrules_end = solv->nrules;
+ if (solv->strict_repo_priority)
+ solver_addstrictrepopriorules(solv, &addedmap);
+ else
+ solv->strictrepopriorules = solv->strictrepopriorules_end = solv->nrules;
+
if (1)
solver_addchoicerules(solv);
else
map_free(&installcandidatemap);
queue_free(&q);
- POOL_DEBUG(SOLV_DEBUG_STATS, "%d pkg rules, 2 * %d update rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules, %d best rules, %d yumobs rules\n", solv->pkgrules_end - 1, solv->updaterules_end - solv->updaterules, solv->jobrules_end - solv->jobrules, solv->infarchrules_end - solv->infarchrules, solv->duprules_end - solv->duprules, solv->choicerules_end - solv->choicerules, solv->bestrules_end - solv->bestrules, solv->yumobsrules_end - solv->yumobsrules);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "%d pkg rules, 2 * %d update rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules, %d best rules, %d yumobs rules\n"
+ "%d black rules, %d recommends rules, %d repo priority rules\n",
+ solv->pkgrules_end - 1,
+ solv->updaterules_end - solv->updaterules,
+ solv->jobrules_end - solv->jobrules,
+ solv->infarchrules_end - solv->infarchrules,
+ solv->duprules_end - solv->duprules,
+ solv->choicerules_end - solv->choicerules,
+ solv->bestrules_end - solv->bestrules,
+ solv->yumobsrules_end - solv->yumobsrules,
+ solv->blackrules_end - solv->blackrules,
+ solv->recommendsrules_end - solv->recommendsrules,
+ solv->strictrepopriorules_end - solv->strictrepopriorules);
POOL_DEBUG(SOLV_DEBUG_STATS, "overall rule memory used: %d K\n", solv->nrules * (int)sizeof(Rule) / 1024);
/* create weak map */
Id blackrules; /* rules from blacklisted packages */
Id blackrules_end;
+ Id strictrepopriorules; /* rules from strict priority repositories */
+ Id strictrepopriorules_end;
+
Id choicerules; /* choice rules (always weak) */
Id choicerules_end;
Id *choicerules_info; /* the rule we used to generate the choice rule */
int strongrecommends; /* true: create weak rules for recommends */
int install_also_updates; /* true: do not prune install job rules to installed packages */
int only_namespace_recommended; /* true: only install packages recommended by namespace */
+ int strict_repo_priority; /* true: only use packages from highest precedence/priority */
int process_orphans; /* true: do special orphan processing */
Map dupmap; /* dup to those packages */
#define SOLVER_FLAG_STRONG_RECOMMENDS 25
#define SOLVER_FLAG_INSTALL_ALSO_UPDATES 26
#define SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED 27
+#define SOLVER_FLAG_STRICT_REPO_PRIORITY 28
#define GET_USERINSTALLED_NAMES (1 << 0) /* package names instead of ids */
#define GET_USERINSTALLED_INVERTED (1 << 1) /* autoinstalled */
POOL_DEBUG(type, "YUMOBS ");
else if (p >= solv->blackrules && p < solv->blackrules_end)
POOL_DEBUG(type, "BLACK ");
+ else if (p >= solv->strictrepopriorules && p < solv->strictrepopriorules_end)
+ POOL_DEBUG(type, "PRIOS ");
else if (p >= solv->recommendsrules && p < solv->recommendsrules_end)
POOL_DEBUG(type, "RECOMMENDS ");
solver_printrule(solv, type, r);