From c7c3693656e4078011ea3f2a3b86f31e37b99e64 Mon Sep 17 00:00:00 2001 From: ticktock35 Date: Tue, 6 Oct 2009 03:57:46 +0000 Subject: [PATCH] Improve install candidate selection Florian Boor 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 | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/libopkg/pkg_hash.c b/libopkg/pkg_hash.c index 8718e20..d15d441 100644 --- a/libopkg/pkg_hash.c +++ b/libopkg/pkg_hash.c @@ -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; -- 2.25.1