#else
# define REPOINFO_PATH "/etc/zypp/repos.d"
# define PRODUCTS_PATH "/etc/products.d"
+# define SOFTLOCKS_PATH "/var/lib/zypp/SoftLocks"
#endif
#define SOLVCACHE_PATH "/var/cache/solv"
return 0;
}
+#ifdef SOFTLOCKS_PATH
+
+void
+addsoftlocks(Pool *pool, Queue *job)
+{
+ FILE *fp;
+ Id type, id, p, pp;
+ char *bp, *ep, buf[4096];
+
+ if ((fp = fopen(SOFTLOCKS_PATH, "r")) == 0)
+ return;
+ while((bp = fgets(buf, sizeof(buf), fp)) != 0)
+ {
+ while (*bp == ' ' || *bp == '\t')
+ bp++;
+ if (!*bp || *bp == '#')
+ continue;
+ for (ep = bp; *ep; ep++)
+ if (*ep == ' ' || *ep == '\t' || *ep == '\n')
+ break;
+ *ep = 0;
+ type = SOLVER_SOLVABLE_NAME;
+ if (!strncmp(bp, "provides:", 9) && bp[9])
+ {
+ type = SOLVER_SOLVABLE_PROVIDES;
+ bp += 9;
+ }
+ id = str2id(pool, bp, 1);
+ if (pool->installed)
+ {
+ FOR_JOB_SELECT(p, pp, type, id)
+ if (pool->solvables[p].repo == pool->installed)
+ break;
+ if (p)
+ continue; /* ignore, as it is already installed */
+ }
+ queue_push2(job, SOLVER_LOCK|SOLVER_WEAK|type, id);
+ }
+ fclose(fp);
+}
+
+#endif
+
#define MODE_LIST 0
#define MODE_INSTALL 1
#define MODE_ERASE 2
// queue_push2(&job, SOLVER_NOOBSOLETES|SOLVER_SOLVABLE_NAME, str2id(pool, "kernel-pae-base", 1));
// queue_push2(&job, SOLVER_NOOBSOLETES|SOLVER_SOLVABLE_NAME, str2id(pool, "kernel-pae-extra", 1));
+#ifdef SOFTLOCKS_PATH
+ addsoftlocks(pool, &job);
+#endif
+
rerunsolver:
for (;;)
{
*depp = pool->solvables[-r->p].name;
return SOLVER_RULE_INFARCH;
}
+ if (rid >= solv->choicerules && rid < solv->choicerules_end)
+ {
+ return SOLVER_RULE_CHOICE;
+ }
if (rid >= solv->learntrules)
{
return SOLVER_RULE_LEARNT;
return SOLVER_RULE_UNKNOWN;
}
+void
+addchoicerules(Solver *solv)
+{
+ Pool *pool = solv->pool;
+ Rule *r;
+ Queue q;
+ int i, rid, havechoice;
+ Id p, d, *pp;
+ Id p2, pp2;
+ Solvable *s, *s2;
+
+ solv->choicerules = solv->nrules;
+ if (!pool->installed)
+ {
+ solv->choicerules_end = solv->nrules;
+ return;
+ }
+ queue_init(&q);
+ for (rid = 1; rid < solv->rpmrules_end ; rid++)
+ {
+ r = solv->rules + rid;
+ if (r->p >= 0 || ((r->d == 0 || r->d == -1) && r->w2 < 0))
+ continue; /* only look at requires rules */
+ // solver_printrule(solv, SAT_DEBUG_RESULT, r);
+ queue_empty(&q);
+ havechoice = 0;
+ FOR_RULELITERALS(p, pp, r)
+ {
+ if (p < 0)
+ continue;
+ s = pool->solvables + p;
+ if (!s->repo)
+ continue;
+ if (s->repo == pool->installed)
+ {
+ 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->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+ continue;
+ break;
+ }
+ if (p2)
+ {
+ /* found one */
+ if (!solv->allowarchchange && s->arch != s2->arch && policy_illegal_archchange(solv, s, s2))
+ continue;
+ if (!solv->allowvendorchange && s->vendor != s2->vendor && policy_illegal_vendorchange(solv, s, s2))
+ continue;
+ 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 one */
+ if (!solv->allowarchchange && s->arch != s2->arch && policy_illegal_archchange(solv, s, s2))
+ continue;
+ if (!solv->allowvendorchange && s->vendor != s2->vendor && policy_illegal_vendorchange(solv, s, s2))
+ continue;
+ queue_push(&q, p);
+ continue;
+ }
+ }
+ /* this package is independent if the installed ones */
+ havechoice = 1;
+ }
+ if (!havechoice || !q.count)
+ continue; /* no choice */
+ for (i = 0; i < q.count; i++)
+ {
+ int j;
+ s = pool->solvables + q.elements[i];
+ if (s->repo == pool->installed)
+ continue;
+ for (j = 0; j < q.count; j++)
+ {
+ if (i == j)
+ continue;
+ s2 = pool->solvables + q.elements[j];
+ if (s2->repo != pool->installed)
+ continue;
+ if (solvable_identical(s, s2))
+ break;
+ }
+ if (j == q.count)
+ break;
+ }
+ if (i == q.count)
+ continue; /* only (identical to) installed packages */
+ d = q.count ? pool_queuetowhatprovides(pool, &q) : 0;
+ solver_addrule(solv, r->p, d);
+ queue_push(&solv->weakruleq, solv->nrules - 1);
+ }
+ queue_free(&q);
+ solv->choicerules_end = solv->nrules;
+}
+
/* EOF */
SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP,
SOLVER_RULE_DISTUPGRADE = 0x500,
SOLVER_RULE_INFARCH = 0x600,
- SOLVER_RULE_LEARNT = 0x700
+ SOLVER_RULE_CHOICE = 0x700,
+ SOLVER_RULE_LEARNT = 0x800
} SolverRuleinfo;
#define SOLVER_RULE_TYPEMASK 0xff00
else
solv->duprules = solv->duprules_end = solv->nrules;
+ if (1)
+ {
+ extern void addchoicerules(Solver *solv);
+ addchoicerules(solv);
+ }
/* all rules created
* --------------------------------------------------------------
map_free(&installcandidatemap);
queue_free(&q);
- POOL_DEBUG(SAT_DEBUG_STATS, "%d rpm rules, %d job rules, %d infarch rules, %d dup rules\n", solv->rpmrules_end - 1, solv->jobrules_end - solv->jobrules, solv->infarchrules_end - solv->infarchrules, solv->duprules_end - solv->duprules);
+ POOL_DEBUG(SAT_DEBUG_STATS, "%d rpm rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules\n", solv->rpmrules_end - 1, solv->jobrules_end - solv->jobrules, solv->infarchrules_end - solv->infarchrules, solv->duprules_end - solv->duprules, solv->choicerules_end - solv->choicerules);
/* create weak map */
map_init(&solv->weakrulemap, solv->nrules);
Id duprules; /* dist upgrade rules */
Id duprules_end;
+ Id choicerules; /* choice rules (always weak) */
+ Id choicerules_end;
+
Id learntrules; /* learnt rules, (end == nrules) */
Map noupdate; /* don't try to update these
s = pool->solvables + v;
POOL_DEBUG(type, " %s [%d]", solvable2str(pool, s), v);
}
+ if (pool->installed && s->repo == pool->installed)
+ POOL_DEBUG(type, "I");
if (r)
{
if (r->w1 == v)
POOL_DEBUG(type, "WEAK ");
if (p >= solv->learntrules)
POOL_DEBUG(type, "LEARNT ");
+ else if (p >= solv->choicerules && p < solv->choicerules_end)
+ POOL_DEBUG(type, "CHOICE ");
else if (p >= solv->infarchrules && p < solv->infarchrules_end)
POOL_DEBUG(type, "INFARCH ");
else if (p >= solv->duprules && p < solv->duprules_end)
case SOLVER_RULE_UNKNOWN:
case SOLVER_RULE_FEATURE:
case SOLVER_RULE_LEARNT:
+ case SOLVER_RULE_CHOICE:
POOL_DEBUG(SAT_DEBUG_RESULT, "bad rule type\n");
return;
}