From: Michael Schroeder Date: Mon, 14 Jan 2013 14:59:55 +0000 (+0100) Subject: trivial_installable: check vendor of affected package to see if a patch should be... X-Git-Tag: BASE-SuSE-Code-12_3-Branch~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78295f753dc699286f62dfd708847597d282e1eb;p=thirdparty%2Flibsolv.git trivial_installable: check vendor of affected package to see if a patch should be ignored [bnc#736100] --- diff --git a/src/pool.h b/src/pool.h index 97224e08..e785cd8c 100644 --- a/src/pool.h +++ b/src/pool.h @@ -265,6 +265,8 @@ Id pool_id2langid(Pool *pool, Id id, const char *lang, int create); int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap); int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *noobsoletesmap); int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap); +struct _Solver; /* argh, needed for vendorchange callback FIXME */ +int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, struct _Solver *solv); void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap); diff --git a/src/solvable.c b/src/solvable.c index 536c1b06..45945443 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -20,6 +20,8 @@ #include "pool.h" #include "repo.h" #include "util.h" +#include "policy.h" +#include "poolvendor.h" #include "chksum.h" const char * @@ -459,7 +461,11 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm while ((con = *conp++) != 0) { if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap)) - return 0; + { + if (ispatch && solvable_is_irrelevant_patch(s, installedmap, 0)) + return -1; + return 0; + } if (!interesting && ISRELDEP(con)) { con = dep2name(pool, con); @@ -467,6 +473,8 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm interesting = 1; } } + if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap, 0)) + interesting = 0; } #if 0 if (s->repo) @@ -568,6 +576,76 @@ solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *noobsoletes } +/* check if this patch is relevant according to the vendor. To bad that patches + * don't have a vendor, so we need to do some careful repo testing. */ +int +solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, Solver *solv) +{ + Pool *pool = s->repo->pool; + Id con, *conp; + int hadpatchpackage = 0; + + if (!s->conflicts) + return 0; + conp = s->repo->idarraydata + s->conflicts; + while ((con = *conp++) != 0) + { + Reldep *rd; + Id p, pp, p2, pp2; + if (!ISRELDEP(con)) + continue; + rd = GETRELDEP(pool, con); + if (rd->flags != REL_LT) + continue; + FOR_PROVIDES(p, pp, con) + { + Solvable *si; + if (!MAPTST(installedmap, p)) + continue; + si = pool->solvables + p; + if (!pool_match_nevr(pool, si, con)) + continue; + FOR_PROVIDES(p2, pp2, rd->name) + { + Solvable *s2 = pool->solvables + p2; + if (!pool_match_nevr(pool, s2, rd->name)) + continue; + if (pool_match_nevr(pool, s2, con)) + continue; /* does not fulfill patch */ + if (s2->repo == s->repo) + { + hadpatchpackage = 1; + /* ok, we have a package from the patch repo that solves the conflict. check vendor */ + if (si->vendor == s2->vendor) + return 0; + /* FIXME: solv is only needed for the vendorchange callback */ + if (solv) + { + if (!policy_illegal_vendorchange(solv, si, s2)) + return 0; + } + else + { + Id v1 = si->vendor ? si->vendor : ID_EMPTY; + Id v2 = s2->vendor ? s2->vendor : ID_EMPTY; + if (v1 == v2) + return 0; + v1 = pool_vendor2mask(pool, v1); + v2 = pool_vendor2mask(pool, v2); + if ((v1 & v2) != 0) + return 0; + } + /* vendor change was illegal, ignore conflict */ + } + } + } + } + /* if we didn't find a patchpackage don't claim that the patch is irrelevant */ + if (!hadpatchpackage) + return 0; + return 1; +} + /*****************************************************************************/ /* diff --git a/src/solver.c b/src/solver.c index 2f248398..43668d54 100644 --- a/src/solver.c +++ b/src/solver.c @@ -3745,9 +3745,18 @@ solver_create_state_maps(Solver *solv, Map *installedmap, Map *conflictsmap) void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res) { + Pool *pool = solv->pool; Map installedmap; - pool_create_state_maps(solv->pool, &solv->decisionq, &installedmap, 0); - pool_trivial_installable_noobsoletesmap(solv->pool, &installedmap, pkgs, res, solv->noobsoletes.size ? &solv->noobsoletes : 0); + int i; + pool_create_state_maps(pool, &solv->decisionq, &installedmap, 0); + pool_trivial_installable_noobsoletesmap(pool, &installedmap, pkgs, res, solv->noobsoletes.size ? &solv->noobsoletes : 0); + for (i = 0; i < res->count; i++) + if (res->elements[i] != -1) + { + Solvable *s = pool->solvables + pkgs->elements[i]; + if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap, solv)) + res->elements[i] = -1; + } map_free(&installedmap); }