Improve install candidate selection
authorticktock35 <ticktock35@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Tue, 6 Oct 2009 03:57:46 +0000 (03:57 +0000)
committerticktock35 <ticktock35@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Tue, 6 Oct 2009 03:57:46 +0000 (03:57 +0000)
    Florian Boor <florian.boor@kernelconcepts.de>
Hello,

I have noticed that opkg does not resolve package selection properly if
the same
package is available in more than one compatible architecture.
Failing having installable candidates available is not necessary in this
case:
Either the packages are from feeds with different priorities - in this
case we
can select by priority - or the priorities are the same and it does not
matter
which one gets installed.
Another problem is that in some situations the package lists seem to
contain
duplicates for no obvious reason. (e.g. one package available from two
feeds
makes four entries in the package lists.)
The patch implements a workaround for this by filtering out duplicates
when the
candidate lists are created and makes opkg select an install candidate
per feed
priority.

I have tested the changes with OpenEmbedded and it does not seem to
cause any
obvious problems.
Could I get some opinions about the solution? :)

Greetings

Florian
-----------
Thanks to Florian

git-svn-id: http://opkg.googlecode.com/svn/trunk@219 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358

libopkg/pkg_hash.c

index 8718e20da7abe7f2647280c6da319afbfc805594..d15d441f54df793599179254b3d9e6f23152d369 100644 (file)
@@ -178,6 +178,7 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
      abstract_pkg_vec_t *providers = abstract_pkg_vec_alloc();
      pkg_t *latest_installed_parent = NULL;
      pkg_t *latest_matching = NULL;
+     pkg_t *priorized_matching = NULL;
      pkg_t *held_pkg = NULL;
      pkg_t *good_pkg_by_name = NULL;
 
@@ -244,7 +245,9 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
                    pkg_t *maybe = vec->pkgs[i];
                    opkg_message(conf, OPKG_DEBUG, "  %s arch=%s arch_priority=%d version=%s  \n",
                                 maybe->name, maybe->architecture, maybe->arch_priority, maybe->version);
-                   if (maybe->arch_priority > 0)  {
+                    /* We make sure not to add the same package twice. Need to search for the reason why 
+                       they show up twice sometimes. */
+                   if ((maybe->arch_priority > 0) && (! pkg_vec_contains(matching_pkgs, maybe))) {
                         max_count++;
                         abstract_pkg_vec_insert(matching_apkgs, maybe->parent);
                         pkg_vec_insert(matching_pkgs, maybe);
@@ -300,14 +303,17 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
      }
 
      if (!good_pkg_by_name && !held_pkg && !latest_installed_parent && matching_apkgs->len > 1 && !quiet) {
-         opkg_message(conf, OPKG_ERROR, "Package=%s, %d matching providers\n",
-                      apkg->name, matching_apkgs->len);
-         for (i = 0; i < matching_apkgs->len; i++) {
-              abstract_pkg_t *matching = matching_apkgs->pkgs[i];
-              opkg_message(conf, OPKG_ERROR, "    %s\n", matching->name);
-         }
-         opkg_message(conf, OPKG_ERROR, "Please select one with opkg install or opkg flag prefer\n");
-     }
+          int prio = 0;
+          for (i = 0; i < matching_pkgs->len; i++) {
+              pkg_t *matching = matching_pkgs->pkgs[i];
+                  if (matching->arch_priority > prio) {
+                      priorized_matching = matching;
+                      prio = matching->arch_priority;
+                      opkg_message(conf, OPKG_DEBUG, "Match with priority %i    %s\n", prio, matching->name);
+                  }
+              }
+          
+          }
 
      if (matching_apkgs->len > 1 && conf->verbosity > 1) {
          opkg_message(conf, OPKG_NOTICE, "%s: for apkg=%s, %d matching pkgs\n",
@@ -336,6 +342,11 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
          opkg_message(conf, OPKG_INFO, "  using latest version of installed package %s\n", latest_installed_parent->name);
          return latest_installed_parent;
      }
+     if (priorized_matching) {
+         opkg_message(conf, OPKG_INFO, "  using priorized matching %s %s %s\n",
+                      priorized_matching->name, priorized_matching->version, priorized_matching->architecture);
+         return priorized_matching;
+     }
      if (nmatching > 1) {
          opkg_message(conf, OPKG_INFO, "  no matching pkg out of matching_apkgs=%d\n", nmatching);
          return NULL;