From 7a6a10a3614b92a38a27d0b8fad6a8be7856f7be Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 28 May 2010 16:17:06 +0200 Subject: [PATCH] - add SOLVER_SET bits to tell solver which properties of a job are intended by the user - add policy_is_illegal check function - rework solv package select function to use new SET bits --- examples/solv.c | 249 +++++++++++++++++++++++------------------------------- src/evr.c | 2 + src/evr.h | 7 +- src/policy.c | 25 ++++++ src/policy.h | 6 ++ src/rules.c | 214 +++++++++++++++++++++++++++++++++++----------- src/solver.c | 20 ++--- src/solver.h | 8 ++ src/solverdebug.c | 36 +++----- src/solverdebug.h | 3 +- 10 files changed, 339 insertions(+), 231 deletions(-) diff --git a/examples/solv.c b/examples/solv.c index 887fe88..437ed9d 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -924,9 +924,11 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie, int mark) flags = 0; if (repoext) - flags = REPO_USE_LOADING|REPO_EXTEND_SOLVABLES; - if (repoext && strcmp(repoext, "DL") != 0) - flags |= REPO_LOCALPOOL; /* no local pool for DL so that we can compare IDs */ + { + flags = REPO_USE_LOADING|REPO_EXTEND_SOLVABLES; + if (strcmp(repoext, "DL") != 0) + flags |= REPO_LOCALPOOL; /* no local pool for DL so that we can compare IDs */ + } if (repo_add_solv_flags(repo, fp, flags)) { @@ -1590,8 +1592,13 @@ str2archid(Pool *pool, char *arch) return id; } + +#define DEPGLOB_NAME 1 +#define DEPGLOB_DEP 2 +#define DEPGLOB_NAMEDEP 3 + int -depglob(Pool *pool, char *name, Queue *job) +depglob(Pool *pool, char *name, Queue *job, int what) { Id p, pp; Id id = str2id(pool, name, 0); @@ -1603,7 +1610,7 @@ depglob(Pool *pool, char *name, Queue *job) { Solvable *s = pool->solvables + p; match = 1; - if (s->name == id) + if (s->name == id && (what & DEPGLOB_NAME) != 0) { queue_push2(job, SOLVER_SOLVABLE_NAME, id); return 1; @@ -1611,7 +1618,8 @@ depglob(Pool *pool, char *name, Queue *job) } if (match) { - printf("[using capability match for '%s']\n", name); + if (what == DEPGLOB_NAMEDEP) + printf("[using capability match for '%s']\n", name); queue_push2(job, SOLVER_SOLVABLE_PROVIDES, id); return 1; } @@ -1620,40 +1628,46 @@ depglob(Pool *pool, char *name, Queue *job) if (strpbrk(name, "[*?") == 0) return 0; - /* looks like a name glob. hard work. */ - for (p = 1; p < pool->nsolvables; p++) + if ((what & DEPGLOB_NAME) != 0) { - Solvable *s = pool->solvables + p; - if (!s->repo || !pool_installable(pool, s)) - continue; - id = s->name; - if (fnmatch(name, id2str(pool, id), 0) == 0) + /* looks like a name glob. hard work. */ + for (p = 1; p < pool->nsolvables; p++) { - for (i = 0; i < job->count; i += 2) - if (job->elements[i] == SOLVER_SOLVABLE_NAME && job->elements[i + 1] == id) - break; - if (i == job->count) - queue_push2(job, SOLVER_SOLVABLE_NAME, id); - match = 1; + Solvable *s = pool->solvables + p; + if (!s->repo || !pool_installable(pool, s)) + continue; + id = s->name; + if (fnmatch(name, id2str(pool, id), 0) == 0) + { + for (i = 0; i < job->count; i += 2) + if (job->elements[i] == SOLVER_SOLVABLE_NAME && job->elements[i + 1] == id) + break; + if (i == job->count) + queue_push2(job, SOLVER_SOLVABLE_NAME, id); + match = 1; + } } + if (match) + return 1; } - if (match) - return 1; - /* looks like a dep glob. really hard work. */ - for (id = 1; id < pool->ss.nstrings; id++) + if ((what & DEPGLOB_DEP)) { - if (!pool->whatprovides[id]) - continue; - if (fnmatch(name, id2str(pool, id), 0) == 0) + /* looks like a dep glob. really hard work. */ + for (id = 1; id < pool->ss.nstrings; id++) { - if (!match) - printf("[using capability match for '%s']\n", name); - for (i = 0; i < job->count; i += 2) - if (job->elements[i] == SOLVER_SOLVABLE_PROVIDES && job->elements[i + 1] == id) - break; - if (i == job->count) - queue_push2(job, SOLVER_SOLVABLE_PROVIDES, id); - match = 1; + if (!pool->whatprovides[id]) + continue; + if (fnmatch(name, id2str(pool, id), 0) == 0) + { + if (!match && what == DEPGLOB_NAMEDEP) + printf("[using capability match for '%s']\n", name); + for (i = 0; i < job->count; i += 2) + if (job->elements[i] == SOLVER_SOLVABLE_PROVIDES && job->elements[i + 1] == id) + break; + if (i == job->count) + queue_push2(job, SOLVER_SOLVABLE_PROVIDES, id); + match = 1; + } } } if (match) @@ -1664,98 +1678,53 @@ depglob(Pool *pool, char *name, Queue *job) void addrelation(Pool *pool, Queue *job, int flags, Id evr) { - int i; + int i, match; + Id p, pp; for (i = 0; i < job->count; i += 2) { - if (job->elements[i] != SOLVER_SOLVABLE_NAME && job->elements[i] != SOLVER_SOLVABLE_PROVIDES) + Id select = job->elements[i] & SOLVER_SELECTMASK; + if (select != SOLVER_SOLVABLE_NAME && select != SOLVER_SOLVABLE_PROVIDES) continue; job->elements[i + 1] = rel2id(pool, job->elements[i + 1], evr, flags, 1); - } -} - -int -limitevr(Pool *pool, char *evr, Queue *job, Id archid) -{ - Queue mq; - Id p, pp, evrid; - int matched = 0; - int i, j; - Solvable *s; - const char *sevr; - - queue_init(&mq); - for (i = 0; i < job->count; i += 2) - { - queue_empty(&mq); - FOR_JOB_SELECT(p, pp, job->elements[i], job->elements[i + 1]) + if (flags == REL_ARCH) + job->elements[i] |= SOLVER_SETARCH; + if (flags == REL_EQ && select == SOLVER_SOLVABLE_NAME && job->elements[i]) { - s = pool_id2solvable(pool, p); - if (archid && s->arch != archid) - continue; - sevr = id2str(pool, s->evr); - if (!strchr(evr, ':') && strchr(sevr, ':')) - sevr = strchr(sevr, ':') + 1; - if (evrcmp_str(pool, sevr, evr, EVRCMP_MATCH) == 0) - queue_push(&mq, p); + const char *evrstr = id2str(pool, evr); + if (strchr(evrstr, '-')) + job->elements[i] |= SOLVER_SETEVR; + else + job->elements[i] |= SOLVER_SETEV; } - if (mq.count) + /* make sure we still have matches */ + match = 0; + FOR_JOB_SELECT(p, pp, job->elements[i], job->elements[i + 1]) { - if (!matched && i) - { - queue_deleten(job, 0, i); - i = 0; - } - matched = 1; - /* if all solvables have the same evr */ - s = pool_id2solvable(pool, mq.elements[0]); - evrid = s->evr; - for (j = 0; j < mq.count; j++) - { - s = pool_id2solvable(pool, mq.elements[j]); - if (s->evr != evrid) - break; - } - if (j == mq.count && j > 1) - { - prune_to_best_arch(pool, &mq); - // prune_to_highest_prio(pool, &mq); - mq.count = 1; - } - if (mq.count > 1) - { - job->elements[i] = SOLVER_SOLVABLE_ONE_OF; - job->elements[i + 1] = pool_queuetowhatprovides(pool, &mq); - } - else - { - job->elements[i] = SOLVER_SOLVABLE; - job->elements[i + 1] = mq.elements[0]; - } + match = 1; + break; } - else if (matched) + if (!match) { - queue_deleten(job, i, 2); - i -= 2; + fprintf(stderr, "nothing matches %s\n", solver_select2str(pool, job->elements[i] & SOLVER_SELECTMASK, job->elements[i + 1])); + exit(1); } } - queue_free(&mq); - if (matched) - return 1; - if (!archid) +} + +void +addrelation_arch(Pool *pool, Queue *job, int flags, char *evr) +{ + char *r; + Id archid; + if ((r = strrchr(evr, '.')) != 0 && r[1] && (archid = str2archid(pool, r + 1)) != 0) { - char *r; - if ((r = strrchr(evr, '.')) != 0 && r[1] && (archid = str2archid(pool, r + 1)) != 0) - { - *r = 0; - if (limitevr(pool, evr, job, archid)) - { - *r = '.'; - return 1; - } - *r = '.'; - } + *r = 0; + addrelation(pool, job, REL_ARCH, archid); + addrelation(pool, job, flags, str2id(pool, evr, 1)); + *r = '.'; } - return 0; + else + addrelation(pool, job, flags, str2id(pool, evr, 1)); } int @@ -1785,16 +1754,9 @@ limitrepo(Pool *pool, Id repofilter, Queue *job) i = 0; } matched = 1; - if (mq.count > 1) - { - job->elements[i] = SOLVER_SOLVABLE_ONE_OF; - job->elements[i + 1] = pool_queuetowhatprovides(pool, &mq); - } - else - { - job->elements[i] = SOLVER_SOLVABLE; - job->elements[i + 1] = mq.elements[0]; - } + /* here we assume that repo == vendor */ + job->elements[i] = SOLVER_SOLVABLE_ONE_OF | (job->elements[i] & SOLVER_SETMASK) | SOLVER_SETVENDOR | SOLVER_SETREPO; + job->elements[i + 1] = pool_queuetowhatprovides(pool, &mq); } else if (matched) { @@ -1816,7 +1778,6 @@ mkselect(Pool *pool, int mode, char *name, Queue *job) { Dataiterator di; Queue q; - int match = 0; queue_init(&q); dataiterator_init(&di, pool, mode == SOLVER_ERASE ? pool->installed : 0, 0, SOLVABLE_FILELIST, name, SEARCH_STRING|SEARCH_FILES|SEARCH_COMPLETE_FILELIST); @@ -1832,21 +1793,19 @@ mkselect(Pool *pool, int mode, char *name, Queue *job) if (q.count) { printf("[using file list match for '%s']\n", name); - match = 1; if (q.count > 1) queue_push2(job, SOLVER_SOLVABLE_ONE_OF, pool_queuetowhatprovides(pool, &q)); else queue_push2(job, SOLVER_SOLVABLE, q.elements[0]); + queue_free(&q); + return; } - queue_free(&q); - if (match) - return; } if ((r = strpbrk(name, "<=>")) != 0) { /* relation case, support: * depglob rel - * depglob.rpm rel + * depglob.arch rel */ int rflags = 0; int nend = r - name; @@ -1871,7 +1830,7 @@ mkselect(Pool *pool, int mode, char *name, Queue *job) fprintf(stderr, "bad relation\n"); exit(1); } - if (depglob(pool, name, job)) + if (depglob(pool, name, job, DEPGLOB_NAMEDEP)) { addrelation(pool, job, rflags, str2id(pool, r, 1)); return; @@ -1879,7 +1838,7 @@ mkselect(Pool *pool, int mode, char *name, Queue *job) if ((r2 = strrchr(name, '.')) != 0 && r2[1] && (archid = str2archid(pool, r2 + 1)) != 0) { *r2 = 0; - if (depglob(pool, name, job)) + if (depglob(pool, name, job, DEPGLOB_NAMEDEP)) { *r2 = '.'; addrelation(pool, job, REL_ARCH, archid); @@ -1894,16 +1853,17 @@ mkselect(Pool *pool, int mode, char *name, Queue *job) /* no relation case, support: * depglob * depglob.arch - * depglob-version-release - * depglob-version-release.arch + * nameglob-version + * nameglob-version.arch + * nameglob-version-release + * nameglob-version-release.arch */ - if (depglob(pool, name, job)) + if (depglob(pool, name, job, DEPGLOB_NAMEDEP)) return; - archid = 0; if ((r = strrchr(name, '.')) != 0 && r[1] && (archid = str2archid(pool, r + 1)) != 0) { *r = 0; - if (depglob(pool, name, job)) + if (depglob(pool, name, job, DEPGLOB_NAMEDEP)) { *r = '.'; addrelation(pool, job, REL_ARCH, archid); @@ -1914,24 +1874,25 @@ mkselect(Pool *pool, int mode, char *name, Queue *job) if ((r = strrchr(name, '-')) != 0) { *r = 0; - if (depglob(pool, name, job)) + if (depglob(pool, name, job, DEPGLOB_NAME)) { /* have just the version */ + addrelation_arch(pool, job, REL_EQ, r + 1); *r = '-'; - if (limitevr(pool, r + 1, job, 0)) - return; + return; } if ((r2 = strrchr(name, '-')) != 0) { *r = '-'; *r2 = 0; - if (depglob(pool, name, job)) + r = r2; + if (depglob(pool, name, job, DEPGLOB_NAME)) { - *r2 = '-'; - if (limitevr(pool, r2 + 1, job, 0)) - return; + /* have version-release */ + addrelation_arch(pool, job, REL_EQ, r + 1); + *r = '-'; + return; } - *r2 = '-'; } *r = '-'; } diff --git a/src/evr.c b/src/evr.c index 4d6318f..a20c7b7 100644 --- a/src/evr.c +++ b/src/evr.c @@ -215,6 +215,8 @@ evrcmp_str(const Pool *pool, const char *evr1, const char *evr2, int mode) if (r1 && !r2) return 1; } + if (mode == EVRCMP_COMPARE_EVONLY) + return 0; if (r1 && r2) { if (s1 != ++r1 && s2 != ++r2) diff --git a/src/evr.h b/src/evr.h index c45cf81..e9a96f4 100644 --- a/src/evr.h +++ b/src/evr.h @@ -19,9 +19,10 @@ extern "C" { #include "pooltypes.h" -#define EVRCMP_COMPARE 0 -#define EVRCMP_MATCH_RELEASE 1 -#define EVRCMP_MATCH 2 +#define EVRCMP_COMPARE 0 +#define EVRCMP_MATCH_RELEASE 1 +#define EVRCMP_MATCH 2 +#define EVRCMP_COMPARE_EVONLY 3 extern int vercmp(const char *s1, const char *q1, const char *s2, const char *q2); extern int evrcmp_str(const Pool *pool, const char *evr1, const char *evr2, int mode); diff --git a/src/policy.c b/src/policy.c index 168400b..0dc3df8 100644 --- a/src/policy.c +++ b/src/policy.c @@ -441,6 +441,31 @@ policy_illegal_vendorchange(Solver *solv, Solvable *s1, Solvable *s2) return 1; /* no class matches */ } +/* check if it is illegal to replace installed + * package "is" with package "s" (which must obsolete "is") + */ +int +policy_is_illegal(Solver *solv, Solvable *is, Solvable *s, int ignore) +{ + Pool *pool = solv->pool; + int ret = 0; + if (!(ignore & POLICY_ILLEGAL_DOWNGRADE) && !solv->allowdowngrade) + { + if (is->name == s->name && evrcmp(pool, is->evr, s->evr, EVRCMP_COMPARE) > 0) + ret |= POLICY_ILLEGAL_DOWNGRADE; + } + if (!(ignore & POLICY_ILLEGAL_ARCHCHANGE) && !solv->allowarchchange) + { + if (is->arch != s->arch && policy_illegal_archchange(solv, s, is)) + ret |= POLICY_ILLEGAL_ARCHCHANGE; + } + if (!(ignore & POLICY_ILLEGAL_VENDORCHANGE) && !solv->allowvendorchange) + { + if (is->vendor != s->vendor && policy_illegal_vendorchange(solv, s, is)) + ret |= POLICY_ILLEGAL_VENDORCHANGE; + } + return ret; +} /*------------------------------------------------------------------- * diff --git a/src/policy.h b/src/policy.h index e52f4f8..b072929 100644 --- a/src/policy.h +++ b/src/policy.h @@ -56,9 +56,15 @@ extern void prune_to_best_version(Pool *pool, Queue *plist); * candidates : List of candidates (This list depends on other * restrictions like architecture and vendor policies too) */ + +#define POLICY_ILLEGAL_DOWNGRADE 1 +#define POLICY_ILLEGAL_ARCHCHANGE 2 +#define POLICY_ILLEGAL_VENDORCHANGE 4 + extern void policy_filter_unwanted(Solver *solv, Queue *plist, int mode); extern int policy_illegal_archchange(Solver *solv, Solvable *s1, Solvable *s2); extern int policy_illegal_vendorchange(Solver *solv, Solvable *s1, Solvable *s2); +extern int policy_is_illegal(Solver *solv, Solvable *s1, Solvable *s2, int ignore); extern void policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, diff --git a/src/rules.c b/src/rules.c index 783ce6c..635bb55 100644 --- a/src/rules.c +++ b/src/rules.c @@ -22,6 +22,7 @@ #include "pool.h" #include "poolarch.h" #include "util.h" +#include "evr.h" #include "policy.h" #include "solverdebug.h" @@ -1338,17 +1339,44 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) Id select, p, pp; Repo *installed; Solvable *s; - int i; + int i, j, set, qstart, pass; + Map omap; installed = solv->installed; select = how & SOLVER_SELECTMASK; switch (how & SOLVER_JOBMASK) { case SOLVER_INSTALL: - if ((select == SOLVER_SOLVABLE_NAME || select == SOLVER_SOLVABLE_PROVIDES) && solv->infarchrules != solv->infarchrules_end && ISRELDEP(what)) + set = how & SOLVER_SETMASK; + if (select == SOLVER_SOLVABLE) + set |= SOLVER_SETARCH | SOLVER_SETVENDOR | SOLVER_SETREPO | SOLVER_SETEVR; + else if ((select == SOLVER_SOLVABLE_NAME || select == SOLVER_SOLVABLE_PROVIDES) && ISRELDEP(what)) { Reldep *rd = GETRELDEP(pool, what); + if (rd->flags == REL_EQ && select == SOLVER_SOLVABLE_NAME) + { +#if !defined(DEBIAN_SEMANTICS) + const char *evr = id2str(pool, rd->evr); + if (strchr(evr, '-')) + set |= SOLVER_SETEVR; + else + set |= SOLVER_SETEV; +#else + set |= SOLVER_SETEVR; +#endif + } + if (rd->flags <= 7 && ISRELDEP(rd->name)) + rd = GETRELDEP(pool, rd->name); if (rd->flags == REL_ARCH) + set |= SOLVER_SETARCH; + } + if (!set) + return; + if ((set & SOLVER_SETARCH) != 0 && solv->infarchrules != solv->infarchrules_end) + { + if (select == SOLVER_SOLVABLE) + queue_push2(q, DISABLE_INFARCH, pool->solvables[what].name); + else { int qcnt = q->count; FOR_JOB_SELECT(p, pp, select, what) @@ -1364,55 +1392,143 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) } } } - if (select != SOLVER_SOLVABLE) - break; - s = pool->solvables + what; - if (solv->infarchrules != solv->infarchrules_end) - queue_push2(q, DISABLE_INFARCH, s->name); - if (solv->duprules != solv->duprules_end) - queue_push2(q, DISABLE_DUP, s->name); - if (!installed) - return; - if (solv->noobsoletes.size && MAPTST(&solv->noobsoletes, what)) + if ((set & SOLVER_SETREPO) != 0 && solv->duprules != solv->duprules_end) { - /* XXX: remove if we always do distupgrade with DUP rules */ - if (solv->dupmap_all && s->repo == installed) - queue_push2(q, DISABLE_UPDATE, what); - return; + if (select == SOLVER_SOLVABLE) + queue_push2(q, DISABLE_DUP, pool->solvables[what].name); + else + { + int qcnt = q->count; + FOR_JOB_SELECT(p, pp, select, what) + { + s = pool->solvables + p; + /* unify names */ + for (i = qcnt; i < q->count; i += 2) + if (q->elements[i + 1] == s->name) + break; + if (i < q->count) + continue; + queue_push2(q, DISABLE_DUP, s->name); + } + } } - if (s->repo == installed) + if (!installed) + return; + /* now the hard part: disable some update rules */ + + /* first check if we have noobs or installed packages in the job */ + FOR_JOB_SELECT(p, pp, select, what) { - queue_push2(q, DISABLE_UPDATE, what); - return; + if (pool->solvables[p].repo == installed) + { + if (select == SOLVER_SOLVABLE) + queue_push2(q, DISABLE_UPDATE, what); + return; + } + if (solv->noobsoletes.size && MAPTST(&solv->noobsoletes, p)) + return; } - if (s->obsoletes) + + /* all job packages obsolete */ + qstart = q->count; + pass = 0; + memset(&omap, 0, sizeof(omap)); + FOR_JOB_SELECT(p, pp, select, what) { - Id obs, *obsp; - obsp = s->repo->idarraydata + s->obsoletes; - while ((obs = *obsp++) != 0) - FOR_PROVIDES(p, pp, obs) - { - Solvable *ps = pool->solvables + p; - if (ps->repo != installed) - continue; - if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps, obs)) - continue; - if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) - continue; - queue_push2(q, DISABLE_UPDATE, p); - } + Id p2, pp2; + + if (pass == 1) + map_grow(&omap, installed->end - installed->start); + s = pool->solvables + p; + if (s->obsoletes) + { + Id obs, *obsp; + obsp = s->repo->idarraydata + s->obsoletes; + while ((obs = *obsp++) != 0) + FOR_PROVIDES(p2, pp2, obs) + { + Solvable *ps = pool->solvables + p2; + if (ps->repo != installed) + continue; + if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps, obs)) + continue; + if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) + continue; + if (pass) + MAPSET(&omap, p2 - installed->start); + else + queue_push2(q, DISABLE_UPDATE, p2); + } + } + FOR_PROVIDES(p2, pp2, s->name) + { + Solvable *ps = pool->solvables + p2; + if (ps->repo != installed) + continue; + if (!pool->implicitobsoleteusesprovides && ps->name != s->name) + continue; + if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) + continue; + if (pass) + MAPSET(&omap, p2 - installed->start); + else + queue_push2(q, DISABLE_UPDATE, p2); + } + if (pass) + { + for (i = j = qstart; i < q->count; i += 2) + { + if (MAPTST(&omap, q->elements[i + 1] - installed->start)) + { + MAPCLR(&omap, q->elements[i + 1] - installed->start); + q->elements[j + 1] = q->elements[i + 1]; + j += 2; + } + } + queue_truncate(q, j); + } + if (q->count == qstart) + break; + pass++; } - FOR_PROVIDES(p, pp, s->name) + if (omap.size) + map_free(&omap); + if (select == SOLVER_SOLVABLE || qstart == q->count) + return; /* all done already */ + + /* now that we know which installed packages are obsoleted check each of them */ + for (i = j = qstart; i < q->count; i += 2) { - Solvable *ps = pool->solvables + p; - if (ps->repo != installed) - continue; - if (!pool->implicitobsoleteusesprovides && ps->name != s->name) - continue; - if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) - continue; - queue_push2(q, DISABLE_UPDATE, p); + Solvable *is = pool->solvables + q->elements[i + 1]; + FOR_JOB_SELECT(p, pp, select, what) + { + int illegal = 0; + s = pool->solvables + p; + if ((set & SOLVER_SETEVR) != 0) + illegal |= POLICY_ILLEGAL_DOWNGRADE; /* ignore */ + if ((set & SOLVER_SETARCH) != 0) + illegal |= POLICY_ILLEGAL_ARCHCHANGE; /* ignore */ + if ((set & SOLVER_SETVENDOR) != 0) + illegal |= POLICY_ILLEGAL_VENDORCHANGE; /* ignore */ + illegal = policy_is_illegal(solv, is, s, illegal); + if (illegal && illegal == POLICY_ILLEGAL_DOWNGRADE && (set & SOLVER_SETEV) != 0) + { + /* it's ok if the EV is different */ + if (evrcmp(pool, is->evr, s->evr, EVRCMP_COMPARE_EVONLY) != 0) + illegal = 0; + } + if (illegal) + break; + } + if (!p) + { + /* no package conflicts with the update rule */ + /* thus keep the DISABLE_UPDATE */ + q->elements[j + 1] = q->elements[i + 1]; + j += 2; + } } + queue_truncate(q, j); return; case SOLVER_ERASE: if (!installed) @@ -1871,12 +1987,10 @@ solver_addchoicerules(Solver *solv) if (p2) { /* found installed package p2 that we can update to p */ - 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; if (MAPTST(&mneg, p)) continue; + if (policy_is_illegal(solv, s2, s, 0)) + continue; queue_push(&qi, p2); queue_push(&q, p); continue; @@ -1904,12 +2018,10 @@ solver_addchoicerules(Solver *solv) if (obs) { /* found installed package p2 that we can update to p */ - 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; if (MAPTST(&mneg, p)) continue; + if (policy_is_illegal(solv, s2, s, 0)) + continue; queue_push(&qi, p2); queue_push(&q, p); continue; diff --git a/src/solver.c b/src/solver.c index 1ffe5bf..7cefd1a 100644 --- a/src/solver.c +++ b/src/solver.c @@ -2764,7 +2764,7 @@ solver_solve(Solver *solv, Queue *job) switch (how & SOLVER_JOBMASK) { case SOLVER_INSTALL: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %sinstall %s\n", weak ? "weak " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %sinstall %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); if (select == SOLVER_SOLVABLE) { p = what; @@ -2786,7 +2786,7 @@ solver_solve(Solver *solv, Queue *job) solver_addjobrule(solv, p, d, i, weak); break; case SOLVER_ERASE: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %s%serase %s\n", weak ? "weak " : "", how & SOLVER_CLEANDEPS ? "clean deps " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %s%serase %s\n", weak ? "weak " : "", how & SOLVER_CLEANDEPS ? "clean deps " : "", solver_select2str(pool, select, what)); if ((how & SOLVER_CLEANDEPS) != 0 && !solv->cleandepsmap.size && solv->installed) map_grow(&solv->cleandepsmap, solv->installed->end - solv->installed->start); if (select == SOLVER_SOLVABLE && solv->installed && pool->solvables[what].repo == solv->installed) @@ -2817,23 +2817,23 @@ solver_solve(Solver *solv, Queue *job) break; case SOLVER_UPDATE: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %supdate %s\n", weak ? "weak " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %supdate %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); break; case SOLVER_VERIFY: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %sverify %s\n", weak ? "weak " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %sverify %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); break; case SOLVER_WEAKENDEPS: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %sweaken deps %s\n", weak ? "weak " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %sweaken deps %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); if (select != SOLVER_SOLVABLE) break; s = pool->solvables + what; weaken_solvable_deps(solv, what); break; case SOLVER_NOOBSOLETES: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %sno obsolete %s\n", weak ? "weak " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %sno obsolete %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); break; case SOLVER_LOCK: - POOL_DEBUG(SAT_DEBUG_JOB, "job: %slock %s\n", weak ? "weak " : "", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: %slock %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); FOR_JOB_SELECT(p, pp, select, what) { s = pool->solvables + p; @@ -2841,10 +2841,10 @@ solver_solve(Solver *solv, Queue *job) } break; case SOLVER_DISTUPGRADE: - POOL_DEBUG(SAT_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(pool, select, what)); break; case SOLVER_DROP_ORPHANED: - POOL_DEBUG(SAT_DEBUG_JOB, "job: drop orphaned %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: drop orphaned %s\n", solver_select2str(pool, select, what)); if (select == SOLVER_SOLVABLE_ALL) solv->droporphanedmap_all = 1; FOR_JOB_SELECT(p, pp, select, what) @@ -2858,7 +2858,7 @@ solver_solve(Solver *solv, Queue *job) } break; case SOLVER_USERINSTALLED: - POOL_DEBUG(SAT_DEBUG_JOB, "job: user installed %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_JOB, "job: user installed %s\n", solver_select2str(pool, select, what)); break; default: POOL_DEBUG(SAT_DEBUG_JOB, "job: unknown job\n"); diff --git a/src/solver.h b/src/solver.h index c4de09b..1b09522 100644 --- a/src/solver.h +++ b/src/solver.h @@ -247,6 +247,14 @@ typedef struct _Solver { #define SOLVER_ESSENTIAL 0x020000 #define SOLVER_CLEANDEPS 0x040000 +#define SOLVER_SETEV 0x01000000 +#define SOLVER_SETEVR 0x02000000 +#define SOLVER_SETARCH 0x04000000 +#define SOLVER_SETVENDOR 0x08000000 +#define SOLVER_SETREPO 0x10000000 + +#define SOLVER_SETMASK 0x1f000000 + /* old API compatibility, do not use in new code */ #if 1 #define SOLVER_INSTALL_SOLVABLE (SOLVER_INSTALL|SOLVER_SOLVABLE) diff --git a/src/solverdebug.c b/src/solverdebug.c index e5bf519..0d8ad24 100644 --- a/src/solverdebug.c +++ b/src/solverdebug.c @@ -661,23 +661,23 @@ solver_printsolution(Solver *solv, Id problem, Id solution) if (select == SOLVER_SOLVABLE && solv->installed && pool->solvables[what].repo == solv->installed) POOL_DEBUG(SAT_DEBUG_RESULT, " - do not keep %s installed\n", solvid2str(pool, what)); else if (select == SOLVER_SOLVABLE_PROVIDES) - POOL_DEBUG(SAT_DEBUG_RESULT, " - do not install a solvable %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_RESULT, " - do not install a solvable %s\n", solver_select2str(pool, select, what)); else - POOL_DEBUG(SAT_DEBUG_RESULT, " - do not install %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_RESULT, " - do not install %s\n", solver_select2str(pool, select, what)); break; case SOLVER_ERASE: if (select == SOLVER_SOLVABLE && !(solv->installed && pool->solvables[what].repo == solv->installed)) POOL_DEBUG(SAT_DEBUG_RESULT, " - do not forbid installation of %s\n", solvid2str(pool, what)); else if (select == SOLVER_SOLVABLE_PROVIDES) - POOL_DEBUG(SAT_DEBUG_RESULT, " - do not deinstall all solvables %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_RESULT, " - do not deinstall all solvables %s\n", solver_select2str(pool, select, what)); else - POOL_DEBUG(SAT_DEBUG_RESULT, " - do not deinstall %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_RESULT, " - do not deinstall %s\n", solver_select2str(pool, select, what)); break; case SOLVER_UPDATE: - POOL_DEBUG(SAT_DEBUG_RESULT, " - do not install most recent version of %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_RESULT, " - do not install most recent version of %s\n", solver_select2str(pool, select, what)); break; case SOLVER_LOCK: - POOL_DEBUG(SAT_DEBUG_RESULT, " - do not lock %s\n", solver_select2str(solv, select, what)); + POOL_DEBUG(SAT_DEBUG_RESULT, " - do not lock %s\n", solver_select2str(pool, select, what)); break; default: POOL_DEBUG(SAT_DEBUG_RESULT, " - do something different\n"); @@ -707,26 +707,19 @@ solver_printsolution(Solver *solv, Id problem, Id solution) sd = rp ? pool->solvables + rp : 0; if (sd) { - int gotone = 0; - if (!solv->allowdowngrade && evrcmp(pool, s->evr, sd->evr, EVRCMP_MATCH_RELEASE) > 0) - { - POOL_DEBUG(SAT_DEBUG_RESULT, " - allow downgrade of %s to %s\n", solvable2str(pool, s), solvable2str(pool, sd)); - gotone = 1; - } - if (!solv->allowarchchange && s->name == sd->name && s->arch != sd->arch && policy_illegal_archchange(solv, s, sd)) - { - POOL_DEBUG(SAT_DEBUG_RESULT, " - allow architecture change of %s to %s\n", solvable2str(pool, s), solvable2str(pool, sd)); - gotone = 1; - } - if (!solv->allowvendorchange && s->name == sd->name && s->vendor != sd->vendor && policy_illegal_vendorchange(solv, s, sd)) + int illegal = policy_is_illegal(solv, s, sd, 0); + if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) + POOL_DEBUG(SAT_DEBUG_RESULT, " - allow downgrade of %s to %s\n", solvable2str(pool, s), solvable2str(pool, sd)); + if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) + POOL_DEBUG(SAT_DEBUG_RESULT, " - allow architecture change of %s to %s\n", solvable2str(pool, s), solvable2str(pool, sd)); + if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) { if (sd->vendor) POOL_DEBUG(SAT_DEBUG_RESULT, " - allow vendor change from '%s' (%s) to '%s' (%s)\n", id2str(pool, s->vendor), solvable2str(pool, s), id2str(pool, sd->vendor), solvable2str(pool, sd)); else POOL_DEBUG(SAT_DEBUG_RESULT, " - allow vendor change from '%s' (%s) to no vendor (%s)\n", id2str(pool, s->vendor), solvable2str(pool, s), solvable2str(pool, sd)); - gotone = 1; } - if (!gotone) + if (!illegal) POOL_DEBUG(SAT_DEBUG_RESULT, " - allow replacement of %s with %s\n", solvable2str(pool, s), solvable2str(pool, sd)); } else @@ -801,9 +794,8 @@ solver_printtrivial(Solver *solv) } const char * -solver_select2str(Solver *solv, Id select, Id what) +solver_select2str(Pool *pool, Id select, Id what) { - Pool *pool = solv->pool; const char *s; char *b; if (select == SOLVER_SOLVABLE) diff --git a/src/solverdebug.h b/src/solverdebug.h index e1033e7..7be568d 100644 --- a/src/solverdebug.h +++ b/src/solverdebug.h @@ -31,7 +31,8 @@ extern void solver_printcompleteprobleminfo(Solver *solv, Id problem); extern void solver_printsolution(Solver *solv, Id problem, Id solution); extern void solver_printallsolutions(Solver *solv); extern void solver_printtrivial(Solver *solv); -extern const char *solver_select2str(Solver *solv, Id select, Id what); + +extern const char *solver_select2str(Pool *pool, Id select, Id what); #endif /* SATSOLVER_SOLVERDEBUG_H */ -- 2.7.4