bring libsolv in line with currrent rpm's multiversion handling
authorMichael Schroeder <mls@suse.de>
Fri, 26 Apr 2013 12:49:55 +0000 (14:49 +0200)
committerMichael Schroeder <mls@suse.de>
Fri, 26 Apr 2013 12:49:55 +0000 (14:49 +0200)
A multiversion install still obeys the obsoletes of a package.
The solver already had a flag to support this, "keepexplicitobsoletes",
but as this is a feature of the package manager it belongs in the
pool, so that the transaction code can do the right thing.
We now have a "noobsoletesmultiversion" flag in the pool that also
defines the default for "keepexplicitobsoletes".

ext/testcase.c
src/pool.c
src/pool.h
src/solver.c
src/transaction.c

index 72f9dc8..dd8f687 100644 (file)
@@ -112,6 +112,7 @@ static struct poolflags2str {
   { POOL_FLAG_OBSOLETEUSESCOLORS,           "obsoleteusescolors", 0 },
   { POOL_FLAG_NOINSTALLEDOBSOLETES,         "noinstalledobsoletes", 0 },
   { POOL_FLAG_HAVEDISTEPOCH,                "havedistepoch", 0 },
+  { POOL_FLAG_NOOBSOLETESMULTIVERSION,      "noobsoletesmultiversion", 0 },
   { 0, 0, 0 }
 };
 
index 869aa43..5244f2a 100644 (file)
@@ -82,6 +82,7 @@ pool_create(void)
   pool->obsoleteusescolors = 1;
 #endif
 #ifdef RPM5
+  pool->noobsoletesmultiversion = 1;
   pool->forbidselfconflicts = 1;
   pool->obsoleteusesprovides = 1;
   pool->implicitobsoleteusesprovides = 1;
@@ -171,6 +172,8 @@ pool_get_flag(Pool *pool, int flag)
       return pool->noinstalledobsoletes;
     case POOL_FLAG_HAVEDISTEPOCH:
       return pool->havedistepoch;
+    case POOL_FLAG_NOOBSOLETESMULTIVERSION:
+      return pool->noobsoletesmultiversion;
     default:
       break;
     }
@@ -204,6 +207,9 @@ pool_set_flag(Pool *pool, int flag, int value)
     case POOL_FLAG_HAVEDISTEPOCH:
       pool->havedistepoch = value;
       break;
+    case POOL_FLAG_NOOBSOLETESMULTIVERSION:
+      pool->noobsoletesmultiversion = value;
+      break;
     default:
       break;
     }
index f94940f..7dcf916 100644 (file)
@@ -130,6 +130,7 @@ struct _Pool {
   int obsoleteusescolors;      /* true: obsoletes check arch color */
   int noinstalledobsoletes;    /* true: ignore obsoletes of installed packages */
   int forbidselfconflicts;     /* true: packages which conflict with itself are not installable */
+  int noobsoletesmultiversion; /* true: obsoletes are ignored for multiversion installs */
 
   Id noarchid;                 /* ARCH_NOARCH, ARCH_ALL, ARCH_ANY, ... */
 
@@ -181,6 +182,7 @@ struct _Pool {
 #define POOL_FLAG_OBSOLETEUSESCOLORS                   5
 #define POOL_FLAG_NOINSTALLEDOBSOLETES                 6
 #define POOL_FLAG_HAVEDISTEPOCH                                7
+#define POOL_FLAG_NOOBSOLETESMULTIVERSION              8
 
 /* ----------------------------------------------- */
 
index 70d7184..e1fe034 100644 (file)
@@ -1427,6 +1427,8 @@ solver_create(Pool *pool)
   solv->dup_allowarchchange = 1;
   solv->dup_allowvendorchange = 1;
 
+  solv->keepexplicitobsoletes = pool->noobsoletesmultiversion ? 0 : 1;
+
   queue_init(&solv->ruletojob);
   queue_init(&solv->decisionq);
   queue_init(&solv->decisionq_why);
index 94f0236..cf039cf 100644 (file)
@@ -46,6 +46,7 @@ obsq_sortcmp(const void *ap, const void *bp, void *dp)
   obs = pool->solvables + ob;
   if (oas->name != obs->name)
     {
+      /* bring "same name" obsoleters (i.e. upgraders) to front */
       if (oas->name == s->name)
         return -1;
       if (obs->name == s->name)
@@ -165,9 +166,19 @@ transaction_base_type(Transaction *trans, Id p)
     }
   else
     {
+      /* install or multiinstall */
       int multi = trans->multiversionmap.size && MAPTST(&trans->multiversionmap, p);
       if (multi)
-       return p2 ? SOLVER_TRANSACTION_MULTIREINSTALL : SOLVER_TRANSACTION_MULTIINSTALL;
+       {
+         if (p2)
+           {
+             s = pool->solvables + p;
+             s2 = pool->solvables + p2;
+             if (s->name == s2->name && s->arch == s2->arch && s->evr == s2->evr)
+               return SOLVER_TRANSACTION_MULTIREINSTALL;
+           }
+         return SOLVER_TRANSACTION_MULTIINSTALL;
+       }
       if (!p2)
        return SOLVER_TRANSACTION_INSTALL;
       s = pool->solvables + p;
@@ -580,7 +591,7 @@ create_transaction_info(Transaction *trans, Queue *decisionq)
            continue;
          queue_push2(ti, p, p2);
        }
-      if (s->obsoletes && !multi)
+      if (s->obsoletes && (!multi || !pool->noobsoletesmultiversion))
        {
          Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
          while ((obs = *obsp++) != 0)