Blob Blame History Raw
From bfdc347fdfc350a9b290543fac905cb21f9a71a8 Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
Date: Mon, 30 Sep 2019 14:35:57 +0200
Subject: [PATCH] Add POOL_FLAG_WHATPROVIDESWITHDISABLED pool flag

This makes libsolv keep disabled packages (i.e. packages
not in the considered map) in the whatprovides hash.

It is useful if you want to modify the considered map after
the whatprovides hash is generated.

Note that using the flag will change the reported problems
as disabled packages are now seen by the solver but
considered uninstallable.
---
 ext/testcase.c |  1 +
 src/policy.c   |  2 ++
 src/pool.c     | 16 +++++++++-------
 src/pool.h     |  2 ++
 src/repo.h     | 20 ++++++++++++++++++++
 src/rules.c    | 22 ++++++++++++++++++++++
 6 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/ext/testcase.c b/ext/testcase.c
index fcebcfa..bd0643a 100644
--- a/ext/testcase.c
+++ b/ext/testcase.c
@@ -152,6 +152,7 @@ static struct poolflags2str {
   { POOL_FLAG_NOOBSOLETESMULTIVERSION,      "noobsoletesmultiversion", 0 },
   { POOL_FLAG_ADDFILEPROVIDESFILTERED,      "addfileprovidesfiltered", 0 },
   { POOL_FLAG_NOWHATPROVIDESAUX,            "nowhatprovidesaux", 0 },
+  { POOL_FLAG_WHATPROVIDESWITHDISABLED,     "whatprovideswithdisabled", 0 },
   { 0, 0, 0 }
 };
 
diff --git a/src/policy.c b/src/policy.c
index 823a008..10a2c4d 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -1579,6 +1579,8 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
 	continue;
 
       ps = pool->solvables + p;
+      if (pool->considered && pool->whatprovideswithdisabled && ps->repo != pool->installed && pool_disabled_solvable(pool, ps)) 
+	continue;
       if (s->name == ps->name)	/* name match */
 	{
 	  if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, ps))
diff --git a/src/pool.c b/src/pool.c
index 4b63727..d2053b9 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -202,6 +202,8 @@ pool_get_flag(Pool *pool, int flag)
       return pool->addfileprovidesfiltered;
     case POOL_FLAG_NOWHATPROVIDESAUX:
       return pool->nowhatprovidesaux;
+    case POOL_FLAG_WHATPROVIDESWITHDISABLED:
+      return pool->whatprovideswithdisabled;
     default:
       break;
     }
@@ -247,6 +249,9 @@ pool_set_flag(Pool *pool, int flag, int value)
     case POOL_FLAG_NOWHATPROVIDESAUX:
       pool->nowhatprovidesaux = value;
       break;
+    case POOL_FLAG_WHATPROVIDESWITHDISABLED:
+      pool->whatprovideswithdisabled = value;
+      break;
     default:
       break;
     }
@@ -473,9 +478,7 @@ pool_createwhatprovides(Pool *pool)
       s = pool->solvables + i;
       if (!s->provides || !s->repo || s->repo->disabled)
 	continue;
-      /* we always need the installed solvable in the whatprovides data,
-         otherwise obsoletes/conflicts on them won't work */
-      if (s->repo != installed && !pool_installable(pool, s))
+      if (!pool_installable_whatprovides(pool, s))
 	continue;
       pp = s->repo->idarraydata + s->provides;
       while ((id = *pp++) != 0)
@@ -534,9 +537,8 @@ pool_createwhatprovides(Pool *pool)
       s = pool->solvables + i;
       if (!s->provides || !s->repo || s->repo->disabled)
 	continue;
-      if (s->repo != installed && !pool_installable(pool, s))
+      if (!pool_installable_whatprovides(pool, s))
 	continue;
-
       /* for all provides of this solvable */
       pp = s->repo->idarraydata + s->provides;
       while ((id = *pp++) != 0)
@@ -963,7 +965,7 @@ pool_addstdproviders(Pool *pool, Id d)
        * and those should not use filelist entries */
       if (s->repo->disabled)
 	continue;
-      if (s->repo != pool->installed && !pool_installable(pool, s))
+      if (!pool_installable_whatprovides(pool, s))
 	continue;
       queue_push(&q, di.solvid);
     }
@@ -1243,7 +1245,7 @@ pool_addrelproviders(Pool *pool, Id d)
 	      FOR_POOL_SOLVABLES(p)
 		{
 		  Solvable *s = pool->solvables + p;
-		  if (s->repo != pool->installed && !pool_installable(pool, s))
+		  if (!pool_installable_whatprovides(pool, s))
 		    continue;
 		  if (s->arch == evr)
 		    queue_push(&plist, p);
diff --git a/src/pool.h b/src/pool.h
index c90c29a..aa173ea 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -166,6 +166,7 @@ struct s_Pool {
   Id *whatprovidesauxdata;
   Offset whatprovidesauxdataoff;
 
+  int whatprovideswithdisabled;
 #endif
 };
 
@@ -204,6 +205,7 @@ struct s_Pool {
 #define POOL_FLAG_ADDFILEPROVIDESFILTERED		9
 #define POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS		10
 #define POOL_FLAG_NOWHATPROVIDESAUX			11
+#define POOL_FLAG_WHATPROVIDESWITHDISABLED		12
 
 /* ----------------------------------------------- */
 
diff --git a/src/repo.h b/src/repo.h
index 58704f1..9a5e981 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -123,6 +123,26 @@ static inline int pool_installable(const Pool *pool, Solvable *s)
   return 1;
 }
 
+#ifdef LIBSOLV_INTERNAL
+static inline int pool_installable_whatprovides(const Pool *pool, Solvable *s)
+{
+  /* we always need the installed solvable in the whatprovides data,
+     otherwise obsoletes/conflicts on them won't work */
+  if (s->repo != pool->installed)
+    {
+      if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC || pool_badarch_solvable(pool, s))
+	return 0;
+      if (pool->considered && !pool->whatprovideswithdisabled)
+	{
+	  Id id = s - pool->solvables;
+	  if (!MAPTST(pool->considered, id))
+	    return 0;
+	}
+    }
+  return 1;
+}
+#endif
+
 /* not in solvable.h because we need the repo definition */
 static inline Solvable *solvable_free(Solvable *s, int reuseids)
 {
diff --git a/src/rules.c b/src/rules.c
index 3aef6ee..4075b9d 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -3323,6 +3323,21 @@ prune_best_update(Solver *solv, Id p, Queue *q)
   policy_filter_unwanted(solv, q, POLICY_MODE_RECOMMEND);
 }
 
+static void
+prune_disabled(Pool *pool, Queue *q)
+{
+  int i, j;
+  for (i = j = 0; i < q->count; i++)
+    {
+      Id p = q->elements[i];
+      Solvable *s = pool->solvables + p;
+      if (s->repo && s->repo != pool->installed && !MAPTST(pool->considered, p))
+	continue;
+      q->elements[j++] = p;
+    }
+  queue_truncate(q, j);
+}
+
 void
 solver_addbestrules(Solver *solv, int havebestinstalljobs, int haslockjob)
 {
@@ -3377,15 +3392,19 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs, int haslockjob)
 		      else if (p2 < 0)
 		        queue_push(&q2, p2);
 		    }
+		  if (pool->considered && pool->whatprovideswithdisabled)
+		    prune_disabled(pool, &q);
 		  if (!q.count)
 		    continue;	/* orphaned */
 		  /* select best packages, just look at prio and version */
 		  oldcnt = q.count;
 		  policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
 		  if (q.count == oldcnt)
 		    continue;	/* nothing filtered */
 		  if (lockedmap)
 		    {
+		      queue_insertn(&q, 0, q2.count, q2.elements);
+		      queue_empty(&q2);
 		      FOR_RULELITERALS(p2, pp2, r)
 			{
 			  if (p2 <= 0)
@@ -3399,9 +3418,12 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs, int haslockjob)
 			    continue;
 			  queue_push(&q2, p2);
 			}
+		      if (pool->considered && pool->whatprovideswithdisabled)
+			prune_disabled(pool, &q2);
 		      policy_filter_unwanted(solv, &q2, POLICY_MODE_RECOMMEND);
 		      for (k = 0; k < q2.count; k++)
 			queue_pushunique(&q, q2.elements[k]);
+		      queue_empty(&q2);
 		    }
 		  if (q2.count)
 		    queue_insertn(&q, 0, q2.count, q2.elements);
--
libgit2 0.28.2